Raising our compiler requirements for 9.6
Hi,
During the 9.5 cycle, and earlier, the topic of increasing our minimum
bar for compilers came up a bunch of times. Specifically whether we
still should continue to use C90 as a baseline.
I think the time has come to rely at least on some newer features.
At the very least I think we should start to rely on 'static inline's
working. There is not, and hasn't been for a while, any buildfarm animal
that does not support it and we go through some ugly lengths to avoid
relying on inline functions in headers. It's a feature that has been
there in most compilers long before C99.
My feeling is that we shouldn't go the full way to C99 because there's
still common compilers without a complete coverage. But individual
features are fine.
The list of features, in the order of perceived importance, that might
be worthwhile thinking about are:
* static inline
* variadic macros
* designated initializers (e.g. somestruct foo = { .bar = 3 } )
* // style comments (I don't care, but it comes up often enough ...)
Others might have different items. I think we should *not* decide on all
of them at once. We should pick items that are supported everywhere and
uncontroversial and do those first.
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Jul 1, 2015 at 9:14 AM, Andres Freund <andres@anarazel.de> wrote:
At the very least I think we should start to rely on 'static inline's
working. There is not, and hasn't been for a while, any buildfarm animal
that does not support it and we go through some ugly lengths to avoid
relying on inline functions in headers. It's a feature that has been
there in most compilers long before C99.My feeling is that we shouldn't go the full way to C99 because there's
still common compilers without a complete coverage. But individual
features are fine.
I am in full agreement.
The list of features, in the order of perceived importance, that might
be worthwhile thinking about are:
* static inline
* variadic macros
* designated initializers (e.g. somestruct foo = { .bar = 3 } )
* // style comments (I don't care, but it comes up often enough ...)
I don't want to add // style comments, FWIW.
What is the state of support like for variadic macros and designated
initializers? Unlike static inline, I am not aware that they are
something that was widely implemented before C99 was formalized.
--
Peter Geoghegan
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@anarazel.de> writes:
At the very least I think we should start to rely on 'static inline's
working. There is not, and hasn't been for a while, any buildfarm animal
that does not support it
pademelon doesn't.
Also, I think there are some other non-gcc animals that nominally allow
"static inline" but will generate warnings when such functions are
unreferenced in a particular compile (that's what the "quiet inline"
configure test is about). That would be hugely annoying for development,
though maybe we don't care too much if it's only a build target.
I'm not against requiring static inline; it would be a huge improvement
really. But we should not fool ourselves that this comes at zero
compatibility cost.
The list of features, in the order of perceived importance, that might
be worthwhile thinking about are:
* static inline
* variadic macros
* designated initializers (e.g. somestruct foo = { .bar = 3 } )
* // style comments (I don't care, but it comes up often enough ...)
Of these I think only the first is really worth breaking portability
for.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Peter Geoghegan <pg@heroku.com> writes:
On Wed, Jul 1, 2015 at 9:14 AM, Andres Freund <andres@anarazel.de> wrote:
The list of features, in the order of perceived importance, that might
be worthwhile thinking about are:
* static inline
* variadic macros
* designated initializers (e.g. somestruct foo = { .bar = 3 } )
* // style comments (I don't care, but it comes up often enough ...)
I don't want to add // style comments, FWIW.
I concur with that one. I think the portability risk is nil (even
pademelon's compiler takes // without complaint, which surprised me
when I realized it). Rather, I think the argument for continuing to
disallow // has to do with maintaining code style consistency. A mishmash
of // and /* comments looks like heck. (Note, BTW, that pgindent will
forcibly convert // to /* in some though seemingly not all cases.)
As far as "static inline" goes, it occurs to me after more thought that
there really is zero risk of build failures if we start relying on that,
because we already have the "#define inline as empty" trick in configure.
What would happen, on a compiler like pademelon's, is that you'd get a
whole lot of warnings about unreferenced static functions. And maybe some
bloat in the executable, if the compiler is not smart enough to drop those
functions from its output. I think both of these effects are probably
acceptable considering what a small minority of platforms would have any
issue.
A potentially larger issue is that I think we have places where frontend
code is #include'ing backend headers that contain macros we might wish
to convert to inline functions, and that will not work if the macros
contain references to backend functions or global variables. But we could
solve that by refactoring headers where necessary.
What is the state of support like for variadic macros and designated
initializers? Unlike static inline, I am not aware that they are
something that was widely implemented before C99 was formalized.
I agree that the value-for-portability-risk tradeoff doesn't look
great for these features.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 07/01/2015 01:33 PM, Tom Lane wrote:
Andres Freund <andres@anarazel.de> writes:
At the very least I think we should start to rely on 'static inline's
working. There is not, and hasn't been for a while, any buildfarm animal
that does not support itpademelon doesn't.
Other reasoning aside, pademelon is running an HPUX version that is 10
years old. I don't think we should care.
JD
--
Command Prompt, Inc. - http://www.commandprompt.com/ 503-667-4564
PostgreSQL Centered full stack support, consulting and development.
Announcing "I'm offended" is basically telling the world you can't
control your own emotions, so everyone else should do it for you.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
01.07.2015, 23:33, Tom Lane kirjoitti:
Andres Freund <andres@anarazel.de> writes:
At the very least I think we should start to rely on 'static inline's
working. There is not, and hasn't been for a while, any buildfarm animal
that does not support itpademelon doesn't.
HP-UX 10.20 was released in 1996, last shipped in July 2002 and
unsupported since July 2003. Assuming the new features aren't going to
be used in release branches PG 9.5 is probably going to support that
platform longer than there's hardware to run it..
But we should not fool ourselves that this comes at zero
compatibility cost.
But compatibility with obsolete platforms doesn't come with zero cost
either -- and judging from the fact that no one noticed until now that
you couldn't even configure PG 9.0 .. 9.3 on recent Solaris 10 releases
(which I believe was the most popular proprietary Unix) suggests that
not a whole lot of people care about those platforms anymore.
/ Oskari
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
"Joshua D. Drake" <jd@commandprompt.com> writes:
On 07/01/2015 01:33 PM, Tom Lane wrote:
Andres Freund <andres@anarazel.de> writes:
At the very least I think we should start to rely on 'static inline's
working. There is not, and hasn't been for a while, any buildfarm animal
that does not support it
pademelon doesn't.
Other reasoning aside, pademelon is running an HPUX version that is 10
years old. I don't think we should care.
Try 16. The reason I run it is not because anyone cares about actually
running Postgres on such a machine; it's just so that we will know when
we are breaking compatibility with ancient C compilers. I brought it up
merely to refute Andres' claim that we do not have buildfarm coverage
of the case.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-07-01 16:33:24 -0400, Tom Lane wrote:
Andres Freund <andres@anarazel.de> writes:
At the very least I think we should start to rely on 'static inline's
working. There is not, and hasn't been for a while, any buildfarm animal
that does not support itpademelon doesn't.
Oh. I'd gone through all the animals somewhere in the middle of the 9.5
cycle. pademelon was either dormant or not yet reincarnated back then.
I'll go through all again then. Interesting that anole's compiler
supports inlines.
Also, I think there are some other non-gcc animals that nominally allow
"static inline" but will generate warnings when such functions are
unreferenced in a particular compile (that's what the "quiet inline"
configure test is about). That would be hugely annoying for development,
though maybe we don't care too much if it's only a build target.
I know that 4c8aa8b5aea1e032f569222d4b6c1019e84622dc "fixed" that test
on a number of older platforms. Apparently even 10+ years ago some
compiler authors added the smarts to recognize whether static inlines
where declared in a header (don't warn) or in a .c file (warn).
I'm not against requiring static inline; it would be a huge improvement
really. But we should not fool ourselves that this comes at zero
compatibility cost.
It's not zero, but I think it's quite small.
The list of features, in the order of perceived importance, that might
be worthwhile thinking about are:
* static inline
* variadic macros
* designated initializers (e.g. somestruct foo = { .bar = 3 } )
* // style comments (I don't care, but it comes up often enough ...)Of these I think only the first is really worth breaking portability
for.
If variadic macros, or even designated initializers, were supported by
the same set of animals in the buildfarm I'd happily use it, but they're
unfortunately not...
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-07-01 23:39:06 +0200, Andres Freund wrote:
On 2015-07-01 16:33:24 -0400, Tom Lane wrote:
Andres Freund <andres@anarazel.de> writes:
At the very least I think we should start to rely on 'static inline's
working. There is not, and hasn't been for a while, any buildfarm animal
that does not support itpademelon doesn't.
Oh. I'd gone through all the animals somewhere in the middle of the 9.5
cycle. pademelon was either dormant or not yet reincarnated back then.I'll go through all again then. Interesting that anole's compiler
supports inlines.
Here are a list of animals and what they support. I left out several
redundant entries (don't need 30 reports of newish linux + gcc
supporting everything).
animal OS compiler inline quiet inline varargs
anole HPUX 11.31 HP C/aC++A.06.25 y y y
axolotl fed-pi gcc-4.9 y y y
baiji vista MSVC 2005 y y y
binturong solaris 10 sun studio 12.3 y y y
baiji win 8 MSVC 2012 y y y
brolga cygwin gcc-4.3 y y
castoroides solaris 10 sun studio 12.1 y y y
catamount OSX 10.8 llvm-gcc 4.2 y y y
coypu netbsd 5.1 gcc-4.1 y y y
currawong win xp MSVC 2008 y y y
damselfly illumos 201311 gcc-4.7 y y y
dingo solaris 10 gcc-4.9 y y y
dromedary OSX 10.6 gcc-4.2 y y y
dunlin gento 13.0 icc 13.1 y y y
elk freebsd 7.1 gcc-4.2 y y y
frogmouth win xp gcc-4.5 y y y
gaur HP-UX 10.20 gcc-2.95 y y y
gharial HP-UX 11.31 gcc-4.6 y y y
locust OSX 10.5 gcc-4.0 y y y
mallard fedora 21 clang-3.5 y y y
mouflon openbsd 5.7 gcc-4.2 y n* y
narwhal win 2003 gcc-3.4 y y y
okapi gentoo 12.14 icc 11.1 y y y
olinguito openbsd 5.3 gcc-4.2 y n* y
opossum netbsd 5.2 gcc-4.1 y y y
orangutan OSX 10.4 gcc-4.0 y y y
pademelon HP-UX 10.2 HP C Compiler 10.32 n n n
pika netbsd 4.99 gcc-4.1 y y ?**
protosciurus solaris 10 gcc-3.4 y y y
rover_firef OmniOS gcc-4.6 ?*** ?*** ?***
smew debian 6.0 clang 2.9 y y y
spoonbill openbsd 3.6 gcc-3.3 y y y
* fails due to idiotic warnings we can't do much about:
/usr/local/lib/libxml2.so.15.1: warning: strcpy() is almost always misused, please use strlcpy()
/usr/local/lib/libxml2.so.15.1: warning: strcat() is almost always misused, please use strlcat()
/usr/local/lib/libxslt.so.3.8: warning: sprintf() is often misused, please use snprintf()
** hasn't run since check was added, but gcc-4.1 supports
*** doesn't report any details, too old buildfarm client? All supported by 4.6
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-07-02 00:15:14 +0200, Andres Freund wrote:
animal OS compiler inline quiet inline varargs
brolga cygwin gcc-4.3 y y
4.3 obviously supports varargs. Human error.
pademelon HP-UX 10.2 HP C Compiler 10.32 n n n
Since, buildfarm/quiet inline test issues aside, pademelon is the only
animal not supporting inlines and varargs, I think we should just go
ahead and start to use both.
- Andres
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@anarazel.de> writes:
Since, buildfarm/quiet inline test issues aside, pademelon is the only
animal not supporting inlines and varargs, I think we should just go
ahead and start to use both.
I'm good with using inlines, since as I pointed out upthread, that won't
actually break anything. I'm much less convinced that varargs macros
represent a winning tradeoff. Using those *will* irredeemably break
pre-C99 compilers, and AFAICS we do not have an urgent need for them.
(BTW, where are you drawing the conclusion that all these compilers
support varargs? I do not see a configure test for it.)
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-07-01 19:05:08 -0400, Tom Lane wrote:
Andres Freund <andres@anarazel.de> writes:
Since, buildfarm/quiet inline test issues aside, pademelon is the only
animal not supporting inlines and varargs, I think we should just go
ahead and start to use both.I'm good with using inlines, since as I pointed out upthread, that won't
actually break anything. I'm much less convinced that varargs macros
represent a winning tradeoff. Using those *will* irredeemably break
pre-C99 compilers, and AFAICS we do not have an urgent need for them.
Well, I'll happily take that.
(BTW, where are you drawing the conclusion that all these compilers
support varargs? I do not see a configure test for it.)
There is, although not in all branches: PGAC_C_VA_ARGS. We optionally
use vararg macros today, for elog (b853eb9), so I assume it works ;)
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Jul 1, 2015 at 6:24 PM, Andres Freund <andres@anarazel.de> wrote:
On 2015-07-02 00:15:14 +0200, Andres Freund wrote:
animal OS compiler inline quiet inline varargs
brolga cygwin gcc-4.3 y y
4.3 obviously supports varargs. Human error.
pademelon HP-UX 10.2 HP C Compiler 10.32 n n n
Since, buildfarm/quiet inline test issues aside, pademelon is the only
animal not supporting inlines and varargs, I think we should just go
ahead and start to use both.
So far this thread is all about the costs of desupporting compilers
that don't have these features, and you're making a good argument
(that I think we all agree with) that the cost is small. But you
haven't really said what the benefits are.
In the case of static inline, the main problem with the status quo
AFAICS is that you have to do a little dance any time you'd otherwise
use a static inline function (for those following along at home, "git
grep INCLUDE_DEFINITIONS src/include" to see how this is done). Now,
it is obviously the case that the first time somebody has to do this
dance, they will be somewhat inconvenienced, but once you know how to
do it, it's not incredibly complicated. So, just to play the devil's
advocate here, who really cares? The way we're doing it right now
works everywhere and is as efficient on each platform as the compiler
on that platform can support. I accept that there is some developer
convenience to not having to worry about the INCLUDE_DEFINITIONS
thing, and maybe that's a sufficient reason to do it, but is that the
only benefit we're hoping to get?
I'd consider an argument for adopting one of these features to be much
stronger if were accompanied by arguments like:
- If we require feature X, we can reduce the size of the generated
code and improve performance.
- If we require feature X, we can reduce the risk of bugs.
- If we require feature X, static analyzers will be able to understand
our code better.
If everybody else here says "working around the lack of feature X is
too much of a pain in the butt and we want to adopt it purely too make
development easier", I'm not going to sit here and try to fight the
tide. But I personally don't find such arguments all that exciting.
It's not at all clear to me that static inline or variadic macros
would make our lives meaningfully better, and like Peter, I think //
comments are a not something we should adopt, because one style is
better than two. Designated initializers would have meaningful
documentation value and might help to decrease the risk of bugs, so
that almost seems more interesting to me than static inline. We'd
need to check what pgindent thinks of them, though, and how much
platform coverage we'd be surrendering.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-07-02 11:46:25 -0400, Robert Haas wrote:
In the case of static inline, the main problem with the status quo
AFAICS is that you have to do a little dance any time you'd otherwise
use a static inline function (for those following along at home, "git
grep INCLUDE_DEFINITIONS src/include" to see how this is done).
Now,
it is obviously the case that the first time somebody has to do this
dance, they will be somewhat inconvenienced, but once you know how to
do it, it's not incredibly complicated.
I obviously know the schema (having introduced it in pg), but I think
the costs are actually rather significant. It makes development more
complex, it makes things considerably harder to follow, and it's quite
annoying to test (manually redefine PG_USE_INLINE, recompile whole
tree).
Several times people also argued against using inlines with that trick
because it's slowing down older platforms.
So, just to play the devil's advocate here, who really cares?
I consider our time one of the most scarce resources around.
I'd consider an argument for adopting one of these features to be much
stronger if were accompanied by arguments like:- If we require feature X, we can reduce the size of the generated
code and improve performance.
Converting some of the bigger macros (I tested fastgetattr) to inliens,
actually does both.
See also http://archives.postgresql.org/message-id/4407.1435763473%40sss.pgh.pa.us
Now, all that is possible with the INCLUDE_DEFINITIONS stuff, but it
makes it considerably more expensive time/complexity wise.
If everybody else here says "working around the lack of feature X is
too much of a pain in the butt and we want to adopt it purely too make
development easier", I'm not going to sit here and try to fight the
tide. But I personally don't find such arguments all that exciting.
I find that an odd attitude.
I think // comments are a not something we should adopt, because one
style is better than two
I don't particularly care about // comments either. They do have the
advantage of allowing three more characters of actual content in one
line comments ...
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Robert Haas <robertmhaas@gmail.com> writes:
So far this thread is all about the costs of desupporting compilers
that don't have these features, and you're making a good argument
(that I think we all agree with) that the cost is small. But you
haven't really said what the benefits are.
I made the same remark with respect to varargs macros, and I continue
to think that the cost-benefit ratio there is pretty marginal.
However, I do think that there's a case to be made for adopting static
inline. The INCLUDE_DEFINITIONS dance is very inconvenient, so it
discourages people from using static inlines over macros, even in cases
where the macro approach is pretty evil (usually, because of multiple-
evaluation hazards). If we allowed static inlines then we could work
towards having a safer coding standard along the lines of "thou shalt
not write macros that evaluate their arguments more than once".
So the benefits here are easier development and less risk of bugs.
On the other side of the ledger, the costs are pretty minimal; we will
not actually break any platforms, at worst we'll make them unpleasant
to develop on because of lots of warning messages. We have some platforms
like that already, and it's not been a huge problem.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Thu, Jul 2, 2015 at 12:10 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Robert Haas <robertmhaas@gmail.com> writes:
So far this thread is all about the costs of desupporting compilers
that don't have these features, and you're making a good argument
(that I think we all agree with) that the cost is small. But you
haven't really said what the benefits are.I made the same remark with respect to varargs macros, and I continue
to think that the cost-benefit ratio there is pretty marginal.However, I do think that there's a case to be made for adopting static
inline. The INCLUDE_DEFINITIONS dance is very inconvenient, so it
discourages people from using static inlines over macros, even in cases
where the macro approach is pretty evil (usually, because of multiple-
evaluation hazards). If we allowed static inlines then we could work
towards having a safer coding standard along the lines of "thou shalt
not write macros that evaluate their arguments more than once".
So the benefits here are easier development and less risk of bugs.
On the other side of the ledger, the costs are pretty minimal; we will
not actually break any platforms, at worst we'll make them unpleasant
to develop on because of lots of warning messages. We have some platforms
like that already, and it's not been a huge problem.
OK, so do we want to rip out all instances of the static inline dance
in favor of more straightforward coding? Do we then shut pandemelon
and any other affected buildfarm members down as unsupported, or what?
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-04 15:20:14 -0400, Robert Haas wrote:
OK, so do we want to rip out all instances of the static inline dance
in favor of more straightforward coding? Do we then shut pandemelon
and any other affected buildfarm members down as unsupported, or what?
I think all that happens is that they'll log a couple more warnings
about defined but unused static functions. configure already defines
inline away if not supported.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@anarazel.de> writes:
On 2015-08-04 15:20:14 -0400, Robert Haas wrote:
OK, so do we want to rip out all instances of the static inline dance
in favor of more straightforward coding? Do we then shut pandemelon
and any other affected buildfarm members down as unsupported, or what?
I think all that happens is that they'll log a couple more warnings
about defined but unused static functions. configure already defines
inline away if not supported.
Right. We had already concluded that this would be safe to do, it's
just a matter of somebody being motivated to do it.
I'm not sure that there's any great urgency about changing the instances
that exist now; the real point of this discussion is that we will allow
new code to use static inlines in headers.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-04 15:45:44 -0400, Tom Lane wrote:
I'm not sure that there's any great urgency about changing the instances
that exist now; the real point of this discussion is that we will allow
new code to use static inlines in headers.
I agree that we don't have to (and probably shouldn't) make the required
configure changes and change definitions. But I do think some of the
current macro usage deserves to be cleaned up at some point. I,
somewhere during 9.4 or 9.5, redefined some of the larger macros into
static inlines and it both reduced the binary size and gave minor
performance benefits.
- Andres
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Tue, Aug 4, 2015 at 3:55 PM, Andres Freund <andres@anarazel.de> wrote:
On 2015-08-04 15:45:44 -0400, Tom Lane wrote:
I'm not sure that there's any great urgency about changing the instances
that exist now; the real point of this discussion is that we will allow
new code to use static inlines in headers.I agree that we don't have to (and probably shouldn't) make the required
configure changes and change definitions. But I do think some of the
current macro usage deserves to be cleaned up at some point. I,
somewhere during 9.4 or 9.5, redefined some of the larger macros into
static inlines and it both reduced the binary size and gave minor
performance benefits.
We typically recommend that people write their new code like the
existing code. If we say that the standards for new code are now
different from old code in this one way, I don't think that's going to
be very helpful to anyone.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-04 16:55:12 -0400, Robert Haas wrote:
On Tue, Aug 4, 2015 at 3:55 PM, Andres Freund <andres@anarazel.de> wrote:
On 2015-08-04 15:45:44 -0400, Tom Lane wrote:
I'm not sure that there's any great urgency about changing the instances
that exist now; the real point of this discussion is that we will allow
new code to use static inlines in headers.I agree that we don't have to (and probably shouldn't) make the required
configure changes and change definitions. But I do think some of the
current macro usage deserves to be cleaned up at some point. I,
somewhere during 9.4 or 9.5, redefined some of the larger macros into
static inlines and it both reduced the binary size and gave minor
performance benefits.We typically recommend that people write their new code like the
existing code. If we say that the standards for new code are now
different from old code in this one way, I don't think that's going to
be very helpful to anyone.
I'm coming around to actually changing more code initially. While I
don't particularly buy the severity of the "make it look like existing
code" issue, I do think it'll be rather confusing to have code dependent
on PG_USE_INLINE when it's statically defined.
So unless somebody protests I'm going to prepare (and commit after
posting) a patch to rip out the bits of code that currently depend on
PG_USE_INLINE.
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-05 14:05:24 +0200, Andres Freund wrote:
So unless somebody protests I'm going to prepare (and commit after
posting) a patch to rip out the bits of code that currently depend on
PG_USE_INLINE.
Here's that patch. I only removed code dependant on PG_USE_INLINE. We
might later want to change some of the harder to maintain macros to
inline functions, but that seems better done separately.
Regards,
Andres
Attachments:
0001-Rely-on-inline-functions-even-if-that-causes-warning.patchtext/x-patch; charset=us-asciiDownload
>From 72025848dc6de01c5ce014a4fde12d7a8610252d Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Wed, 5 Aug 2015 15:02:56 +0200
Subject: [PATCH] Rely on inline functions even if that causes warnings in
older compilers.
So far we have worked around the fact that some very old compilers do
not support 'inline' functions by only using inline functions
conditionally (or not at all). Since such compilers are very rare by
now, we have decided to rely on inline functions from 9.6 onwards.
To avoid breaking these old compilers inline is defined away when not
supported. That'll cause "function x defined but not used" type of
warnings, but since nobody develops on such compilers anymore that's
ok.
This change in policy will allow us to more easily employ inline
functions.
I chose to remove code previously conditional on PG_USE_INLINE as it
seemed confusing to have code dependent on a define that's always
defined.
Discussion: 20150701161447.GB30708@awork2.anarazel.de
---
config/c-compiler.m4 | 34 ----------
config/test_quiet_include.h | 18 -----
configure | 38 -----------
configure.in | 2 +-
src/backend/lib/ilist.c | 3 -
src/backend/nodes/list.c | 3 -
src/backend/port/atomics.c | 7 --
src/backend/utils/adt/arrayfuncs.c | 3 -
src/backend/utils/mmgr/mcxt.c | 3 -
src/backend/utils/sort/sortsupport.c | 3 -
src/include/access/gin_private.h | 8 +--
src/include/c.h | 28 --------
src/include/lib/ilist.h | 106 ++++++++----------------------
src/include/nodes/pg_list.h | 17 ++---
src/include/pg_config.h.in | 4 --
src/include/pg_config.h.win32 | 6 +-
src/include/port/atomics.h | 101 ++++++++--------------------
src/include/port/atomics/arch-x86.h | 4 --
src/include/port/atomics/fallback.h | 5 --
src/include/port/atomics/generic-acc.h | 8 +--
src/include/port/atomics/generic-gcc.h | 8 +--
src/include/port/atomics/generic-msvc.h | 8 ---
src/include/port/atomics/generic-sunpro.h | 4 --
src/include/port/atomics/generic-xlc.h | 8 ---
src/include/port/atomics/generic.h | 4 --
src/include/utils/arrayaccess.h | 19 +-----
src/include/utils/palloc.h | 11 +---
src/include/utils/sortsupport.h | 18 +----
28 files changed, 70 insertions(+), 411 deletions(-)
delete mode 100644 config/test_quiet_include.h
diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
index 050bfa5..397e1b0 100644
--- a/config/c-compiler.m4
+++ b/config/c-compiler.m4
@@ -17,40 +17,6 @@ fi])# PGAC_C_SIGNED
-# PGAC_C_INLINE
-# -------------
-# Check if the C compiler understands inline functions without being
-# noisy about unused static inline functions. Some older compilers
-# understand inline functions (as tested by AC_C_INLINE) but warn about
-# them if they aren't used in a translation unit.
-#
-# This test used to just define an inline function, but some compilers
-# (notably clang) got too smart and now warn about unused static
-# inline functions when defined inside a .c file, but not when defined
-# in an included header. Since the latter is what we want to use, test
-# to see if the warning appears when the function is in a header file.
-# Not pretty, but it works.
-#
-# Defines: inline, PG_USE_INLINE
-AC_DEFUN([PGAC_C_INLINE],
-[AC_C_INLINE
-AC_CACHE_CHECK([for quiet inline (no complaint if unreferenced)], pgac_cv_c_inline_quietly,
- [pgac_cv_c_inline_quietly=no
- if test "$ac_cv_c_inline" != no; then
- pgac_c_inline_save_werror=$ac_c_werror_flag
- ac_c_werror_flag=yes
- AC_LINK_IFELSE([AC_LANG_PROGRAM([#include "$srcdir/config/test_quiet_include.h"],[])],
- [pgac_cv_c_inline_quietly=yes])
- ac_c_werror_flag=$pgac_c_inline_save_werror
- fi])
-if test "$pgac_cv_c_inline_quietly" != no; then
- AC_DEFINE_UNQUOTED([PG_USE_INLINE], 1,
- [Define to 1 if "static inline" works without unwanted warnings from ]
- [compilations where static inline functions are defined but not called.])
-fi
-])# PGAC_C_INLINE
-
-
# PGAC_C_PRINTF_ARCHETYPE
# -----------------------
# Set the format archetype used by gcc to check printf type functions. We
diff --git a/config/test_quiet_include.h b/config/test_quiet_include.h
deleted file mode 100644
index 732b231..0000000
--- a/config/test_quiet_include.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * For the raison d'etre of this file, check the comment above the definition
- * of the PGAC_C_INLINE macro in config/c-compiler.m4.
- */
-static inline int
-fun()
-{
- return 0;
-}
-
-/*
- * "IBM XL C/C++ for AIX, V12.1" miscompiles, for 32-bit, some inline
- * expansions of ginCompareItemPointers() "long long" arithmetic. To take
- * advantage of inlining, build a 64-bit PostgreSQL.
- */
-#if defined(__ILP32__) && defined(__IBMC__)
-#error "known inlining bug"
-#endif
diff --git a/configure b/configure
index 5787ae8..ebb5cac 100755
--- a/configure
+++ b/configure
@@ -11006,44 +11006,6 @@ _ACEOF
;;
esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for quiet inline (no complaint if unreferenced)" >&5
-$as_echo_n "checking for quiet inline (no complaint if unreferenced)... " >&6; }
-if ${pgac_cv_c_inline_quietly+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- pgac_cv_c_inline_quietly=no
- if test "$ac_cv_c_inline" != no; then
- pgac_c_inline_save_werror=$ac_c_werror_flag
- ac_c_werror_flag=yes
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include "$srcdir/config/test_quiet_include.h"
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- pgac_cv_c_inline_quietly=yes
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- ac_c_werror_flag=$pgac_c_inline_save_werror
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_c_inline_quietly" >&5
-$as_echo "$pgac_cv_c_inline_quietly" >&6; }
-if test "$pgac_cv_c_inline_quietly" != no; then
-
-cat >>confdefs.h <<_ACEOF
-#define PG_USE_INLINE 1
-_ACEOF
-
-fi
-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for printf format archetype" >&5
$as_echo_n "checking for printf format archetype... " >&6; }
if ${pgac_cv_printf_archetype+:} false; then :
diff --git a/configure.in b/configure.in
index ece5e22..a28f9dd 100644
--- a/configure.in
+++ b/configure.in
@@ -1309,7 +1309,7 @@ fi
m4_defun([AC_PROG_CC_STDC], []) dnl We don't want that.
AC_C_BIGENDIAN
-PGAC_C_INLINE
+AC_C_INLINE
PGAC_PRINTF_ARCHETYPE
AC_C_FLEXIBLE_ARRAY_MEMBER
PGAC_C_SIGNED
diff --git a/src/backend/lib/ilist.c b/src/backend/lib/ilist.c
index 58550f7..c26baf3 100644
--- a/src/backend/lib/ilist.c
+++ b/src/backend/lib/ilist.c
@@ -18,9 +18,6 @@
*/
#include "postgres.h"
-/* See ilist.h */
-#define ILIST_INCLUDE_DEFINITIONS
-
#include "lib/ilist.h"
/*
diff --git a/src/backend/nodes/list.c b/src/backend/nodes/list.c
index a6737514..1dce42f 100644
--- a/src/backend/nodes/list.c
+++ b/src/backend/nodes/list.c
@@ -15,9 +15,6 @@
*/
#include "postgres.h"
-/* see pg_list.h */
-#define PG_LIST_INCLUDE_DEFINITIONS
-
#include "nodes/pg_list.h"
diff --git a/src/backend/port/atomics.c b/src/backend/port/atomics.c
index 439b3c1..cd953f9 100644
--- a/src/backend/port/atomics.c
+++ b/src/backend/port/atomics.c
@@ -13,13 +13,6 @@
*/
#include "postgres.h"
-/*
- * We want the functions below to be inline; but if the compiler doesn't
- * support that, fall back on providing them as regular functions. See
- * STATIC_IF_INLINE in c.h.
- */
-#define ATOMICS_INCLUDE_DEFINITIONS
-
#include "miscadmin.h"
#include "port/atomics.h"
#include "storage/spin.h"
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 42cdbc7..67c9b35 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -20,9 +20,6 @@
#endif
#include <math.h>
-/* See arrayaccess.h */
-#define ARRAYACCESS_INCLUDE_DEFINITIONS
-
#include "access/htup_details.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 34f4e72..12d29f7 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -19,9 +19,6 @@
*-------------------------------------------------------------------------
*/
-/* see palloc.h. Must be before postgres.h */
-#define MCXT_INCLUDE_DEFINITIONS
-
#include "postgres.h"
#include "miscadmin.h"
diff --git a/src/backend/utils/sort/sortsupport.c b/src/backend/utils/sort/sortsupport.c
index ffef965..daf38c7 100644
--- a/src/backend/utils/sort/sortsupport.c
+++ b/src/backend/utils/sort/sortsupport.c
@@ -15,9 +15,6 @@
#include "postgres.h"
-/* See sortsupport.h */
-#define SORTSUPPORT_INCLUDE_DEFINITIONS
-
#include "access/nbtree.h"
#include "fmgr.h"
#include "utils/lsyscache.h"
diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h
index 5f214d7..5095fc1 100644
--- a/src/include/access/gin_private.h
+++ b/src/include/access/gin_private.h
@@ -952,11 +952,8 @@ extern ItemPointer ginMergeItemPointers(ItemPointerData *a, uint32 na,
/*
* Merging the results of several gin scans compares item pointers a lot,
- * so we want this to be inlined. But if the compiler doesn't support that,
- * fall back on the non-inline version from itemptr.c. See STATIC_IF_INLINE in
- * c.h.
+ * so we want this to be inlined.
*/
-#ifdef PG_USE_INLINE
static inline int
ginCompareItemPointers(ItemPointer a, ItemPointer b)
{
@@ -970,8 +967,5 @@ ginCompareItemPointers(ItemPointer a, ItemPointer b)
else
return -1;
}
-#else
-#define ginCompareItemPointers(a, b) ItemPointerCompare(a, b)
-#endif /* PG_USE_INLINE */
#endif /* GIN_PRIVATE_H */
diff --git a/src/include/c.h b/src/include/c.h
index 92c5202..135fd94 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -920,34 +920,6 @@ typedef NameData *Name;
#endif
-/*
- * Function inlining support -- Allow modules to define functions that may be
- * inlined, if the compiler supports it.
- *
- * The function bodies must be defined in the module header prefixed by
- * STATIC_IF_INLINE, protected by a cpp symbol that the module's .c file must
- * define. If the compiler doesn't support inline functions, the function
- * definitions are pulled in by the .c file as regular (not inline) symbols.
- *
- * The header must also declare the functions' prototypes, protected by
- * !PG_USE_INLINE.
- */
-
-/* declarations which are only visible when not inlining and in the .c file */
-#ifdef PG_USE_INLINE
-#define STATIC_IF_INLINE static inline
-#else
-#define STATIC_IF_INLINE
-#endif /* PG_USE_INLINE */
-
-/* declarations which are marked inline when inlining, extern otherwise */
-#ifdef PG_USE_INLINE
-#define STATIC_IF_INLINE_DECLARE static inline
-#else
-#define STATIC_IF_INLINE_DECLARE extern
-#endif /* PG_USE_INLINE */
-
-
/* ----------------------------------------------------------------
* Section 8: random stuff
* ----------------------------------------------------------------
diff --git a/src/include/lib/ilist.h b/src/include/lib/ilist.h
index 7c20b9a..3954ae0 100644
--- a/src/include/lib/ilist.h
+++ b/src/include/lib/ilist.h
@@ -268,40 +268,13 @@ extern void slist_check(slist_head *head);
#define slist_check(head) ((void) (head))
#endif /* ILIST_DEBUG */
+/* doubly linked list implementation */
/*
- * We want the functions below to be inline; but if the compiler doesn't
- * support that, fall back on providing them as regular functions. See
- * STATIC_IF_INLINE in c.h.
- */
-#ifndef PG_USE_INLINE
-extern void dlist_init(dlist_head *head);
-extern bool dlist_is_empty(dlist_head *head);
-extern void dlist_push_head(dlist_head *head, dlist_node *node);
-extern void dlist_push_tail(dlist_head *head, dlist_node *node);
-extern void dlist_insert_after(dlist_node *after, dlist_node *node);
-extern void dlist_insert_before(dlist_node *before, dlist_node *node);
-extern void dlist_delete(dlist_node *node);
-extern dlist_node *dlist_pop_head_node(dlist_head *head);
-extern void dlist_move_head(dlist_head *head, dlist_node *node);
-extern bool dlist_has_next(dlist_head *head, dlist_node *node);
-extern bool dlist_has_prev(dlist_head *head, dlist_node *node);
-extern dlist_node *dlist_next_node(dlist_head *head, dlist_node *node);
-extern dlist_node *dlist_prev_node(dlist_head *head, dlist_node *node);
-extern dlist_node *dlist_head_node(dlist_head *head);
-extern dlist_node *dlist_tail_node(dlist_head *head);
-
-/* dlist macro support functions */
-extern void *dlist_tail_element_off(dlist_head *head, size_t off);
-extern void *dlist_head_element_off(dlist_head *head, size_t off);
-#endif /* !PG_USE_INLINE */
-
-#if defined(PG_USE_INLINE) || defined(ILIST_INCLUDE_DEFINITIONS)
-/*
* Initialize a doubly linked list.
* Previous state will be thrown away without any cleanup.
*/
-STATIC_IF_INLINE void
+static inline void
dlist_init(dlist_head *head)
{
head->head.next = head->head.prev = &head->head;
@@ -312,7 +285,7 @@ dlist_init(dlist_head *head)
*
* An empty list has either its first 'next' pointer set to NULL, or to itself.
*/
-STATIC_IF_INLINE bool
+static inline bool
dlist_is_empty(dlist_head *head)
{
dlist_check(head);
@@ -323,7 +296,7 @@ dlist_is_empty(dlist_head *head)
/*
* Insert a node at the beginning of the list.
*/
-STATIC_IF_INLINE void
+static inline void
dlist_push_head(dlist_head *head, dlist_node *node)
{
if (head->head.next == NULL) /* convert NULL header to circular */
@@ -340,7 +313,7 @@ dlist_push_head(dlist_head *head, dlist_node *node)
/*
* Insert a node at the end of the list.
*/
-STATIC_IF_INLINE void
+static inline void
dlist_push_tail(dlist_head *head, dlist_node *node)
{
if (head->head.next == NULL) /* convert NULL header to circular */
@@ -357,7 +330,7 @@ dlist_push_tail(dlist_head *head, dlist_node *node)
/*
* Insert a node after another *in the same list*
*/
-STATIC_IF_INLINE void
+static inline void
dlist_insert_after(dlist_node *after, dlist_node *node)
{
node->prev = after;
@@ -369,7 +342,7 @@ dlist_insert_after(dlist_node *after, dlist_node *node)
/*
* Insert a node before another *in the same list*
*/
-STATIC_IF_INLINE void
+static inline void
dlist_insert_before(dlist_node *before, dlist_node *node)
{
node->prev = before->prev;
@@ -381,7 +354,7 @@ dlist_insert_before(dlist_node *before, dlist_node *node)
/*
* Delete 'node' from its list (it must be in one).
*/
-STATIC_IF_INLINE void
+static inline void
dlist_delete(dlist_node *node)
{
node->prev->next = node->next;
@@ -391,7 +364,7 @@ dlist_delete(dlist_node *node)
/*
* Remove and return the first node from a list (there must be one).
*/
-STATIC_IF_INLINE dlist_node *
+static inline dlist_node *
dlist_pop_head_node(dlist_head *head)
{
dlist_node *node;
@@ -408,7 +381,7 @@ dlist_pop_head_node(dlist_head *head)
*
* Undefined behaviour if 'node' is not already part of the list.
*/
-STATIC_IF_INLINE void
+static inline void
dlist_move_head(dlist_head *head, dlist_node *node)
{
/* fast path if it's already at the head */
@@ -425,7 +398,7 @@ dlist_move_head(dlist_head *head, dlist_node *node)
* Check whether 'node' has a following node.
* Caution: unreliable if 'node' is not in the list.
*/
-STATIC_IF_INLINE bool
+static inline bool
dlist_has_next(dlist_head *head, dlist_node *node)
{
return node->next != &head->head;
@@ -435,7 +408,7 @@ dlist_has_next(dlist_head *head, dlist_node *node)
* Check whether 'node' has a preceding node.
* Caution: unreliable if 'node' is not in the list.
*/
-STATIC_IF_INLINE bool
+static inline bool
dlist_has_prev(dlist_head *head, dlist_node *node)
{
return node->prev != &head->head;
@@ -444,7 +417,7 @@ dlist_has_prev(dlist_head *head, dlist_node *node)
/*
* Return the next node in the list (there must be one).
*/
-STATIC_IF_INLINE dlist_node *
+static inline dlist_node *
dlist_next_node(dlist_head *head, dlist_node *node)
{
Assert(dlist_has_next(head, node));
@@ -454,7 +427,7 @@ dlist_next_node(dlist_head *head, dlist_node *node)
/*
* Return previous node in the list (there must be one).
*/
-STATIC_IF_INLINE dlist_node *
+static inline dlist_node *
dlist_prev_node(dlist_head *head, dlist_node *node)
{
Assert(dlist_has_prev(head, node));
@@ -462,7 +435,7 @@ dlist_prev_node(dlist_head *head, dlist_node *node)
}
/* internal support function to get address of head element's struct */
-STATIC_IF_INLINE void *
+static inline void *
dlist_head_element_off(dlist_head *head, size_t off)
{
Assert(!dlist_is_empty(head));
@@ -472,14 +445,14 @@ dlist_head_element_off(dlist_head *head, size_t off)
/*
* Return the first node in the list (there must be one).
*/
-STATIC_IF_INLINE dlist_node *
+static inline dlist_node *
dlist_head_node(dlist_head *head)
{
return (dlist_node *) dlist_head_element_off(head, 0);
}
/* internal support function to get address of tail element's struct */
-STATIC_IF_INLINE void *
+static inline void *
dlist_tail_element_off(dlist_head *head, size_t off)
{
Assert(!dlist_is_empty(head));
@@ -489,12 +462,11 @@ dlist_tail_element_off(dlist_head *head, size_t off)
/*
* Return the last node in the list (there must be one).
*/
-STATIC_IF_INLINE dlist_node *
+static inline dlist_node *
dlist_tail_node(dlist_head *head)
{
return (dlist_node *) dlist_tail_element_off(head, 0);
}
-#endif /* PG_USE_INLINE || ILIST_INCLUDE_DEFINITIONS */
/*
* Return the containing struct of 'type' where 'membername' is the dlist_node
@@ -572,32 +544,13 @@ dlist_tail_node(dlist_head *head)
(iter).cur = (iter).cur->prev)
-/*
- * We want the functions below to be inline; but if the compiler doesn't
- * support that, fall back on providing them as regular functions. See
- * STATIC_IF_INLINE in c.h.
- */
-#ifndef PG_USE_INLINE
-extern void slist_init(slist_head *head);
-extern bool slist_is_empty(slist_head *head);
-extern void slist_push_head(slist_head *head, slist_node *node);
-extern void slist_insert_after(slist_node *after, slist_node *node);
-extern slist_node *slist_pop_head_node(slist_head *head);
-extern bool slist_has_next(slist_head *head, slist_node *node);
-extern slist_node *slist_next_node(slist_head *head, slist_node *node);
-extern slist_node *slist_head_node(slist_head *head);
-extern void slist_delete_current(slist_mutable_iter *iter);
-
-/* slist macro support function */
-extern void *slist_head_element_off(slist_head *head, size_t off);
-#endif
+/* singly linked list implementation */
-#if defined(PG_USE_INLINE) || defined(ILIST_INCLUDE_DEFINITIONS)
/*
* Initialize a singly linked list.
* Previous state will be thrown away without any cleanup.
*/
-STATIC_IF_INLINE void
+static inline void
slist_init(slist_head *head)
{
head->head.next = NULL;
@@ -606,7 +559,7 @@ slist_init(slist_head *head)
/*
* Is the list empty?
*/
-STATIC_IF_INLINE bool
+static inline bool
slist_is_empty(slist_head *head)
{
slist_check(head);
@@ -617,7 +570,7 @@ slist_is_empty(slist_head *head)
/*
* Insert a node at the beginning of the list.
*/
-STATIC_IF_INLINE void
+static inline void
slist_push_head(slist_head *head, slist_node *node)
{
node->next = head->head.next;
@@ -629,7 +582,7 @@ slist_push_head(slist_head *head, slist_node *node)
/*
* Insert a node after another *in the same list*
*/
-STATIC_IF_INLINE void
+static inline void
slist_insert_after(slist_node *after, slist_node *node)
{
node->next = after->next;
@@ -639,7 +592,7 @@ slist_insert_after(slist_node *after, slist_node *node)
/*
* Remove and return the first node from a list (there must be one).
*/
-STATIC_IF_INLINE slist_node *
+static inline slist_node *
slist_pop_head_node(slist_head *head)
{
slist_node *node;
@@ -654,7 +607,7 @@ slist_pop_head_node(slist_head *head)
/*
* Check whether 'node' has a following node.
*/
-STATIC_IF_INLINE bool
+static inline bool
slist_has_next(slist_head *head, slist_node *node)
{
slist_check(head);
@@ -665,7 +618,7 @@ slist_has_next(slist_head *head, slist_node *node)
/*
* Return the next node in the list (there must be one).
*/
-STATIC_IF_INLINE slist_node *
+static inline slist_node *
slist_next_node(slist_head *head, slist_node *node)
{
Assert(slist_has_next(head, node));
@@ -673,7 +626,7 @@ slist_next_node(slist_head *head, slist_node *node)
}
/* internal support function to get address of head element's struct */
-STATIC_IF_INLINE void *
+static inline void *
slist_head_element_off(slist_head *head, size_t off)
{
Assert(!slist_is_empty(head));
@@ -683,7 +636,7 @@ slist_head_element_off(slist_head *head, size_t off)
/*
* Return the first node in the list (there must be one).
*/
-STATIC_IF_INLINE slist_node *
+static inline slist_node *
slist_head_node(slist_head *head)
{
return (slist_node *) slist_head_element_off(head, 0);
@@ -695,7 +648,7 @@ slist_head_node(slist_head *head)
* Caution: this modifies iter->cur, so don't use that again in the current
* loop iteration.
*/
-STATIC_IF_INLINE void
+static inline void
slist_delete_current(slist_mutable_iter *iter)
{
/*
@@ -711,7 +664,6 @@ slist_delete_current(slist_mutable_iter *iter)
*/
iter->cur = iter->prev;
}
-#endif /* PG_USE_INLINE || ILIST_INCLUDE_DEFINITIONS */
/*
* Return the containing struct of 'type' where 'membername' is the slist_node
diff --git a/src/include/nodes/pg_list.h b/src/include/nodes/pg_list.h
index 729456d..b7040df 100644
--- a/src/include/nodes/pg_list.h
+++ b/src/include/nodes/pg_list.h
@@ -71,34 +71,25 @@ struct ListCell
/*
* These routines are used frequently. However, we can't implement
* them as macros, since we want to avoid double-evaluation of macro
- * arguments. Therefore, we implement them using static inline functions
- * if supported by the compiler, or as regular functions otherwise.
- * See STATIC_IF_INLINE in c.h.
+ * arguments.
*/
-#ifndef PG_USE_INLINE
-extern ListCell *list_head(const List *l);
-extern ListCell *list_tail(List *l);
-extern int list_length(const List *l);
-#endif /* PG_USE_INLINE */
-#if defined(PG_USE_INLINE) || defined(PG_LIST_INCLUDE_DEFINITIONS)
-STATIC_IF_INLINE ListCell *
+static inline ListCell *
list_head(const List *l)
{
return l ? l->head : NULL;
}
-STATIC_IF_INLINE ListCell *
+static inline ListCell *
list_tail(List *l)
{
return l ? l->tail : NULL;
}
-STATIC_IF_INLINE int
+static inline int
list_length(const List *l)
{
return l ? l->length : 0;
}
-#endif /*-- PG_USE_INLINE || PG_LIST_INCLUDE_DEFINITIONS */
/*
* NB: There is an unfortunate legacy from a previous incarnation of
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 5688f75..9285c62 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -733,10 +733,6 @@
/* Define to gnu_printf if compiler supports it, else printf. */
#undef PG_PRINTF_ATTRIBUTE
-/* Define to 1 if "static inline" works without unwanted warnings from
- compilations where static inline functions are defined but not called. */
-#undef PG_USE_INLINE
-
/* PostgreSQL version as a string */
#undef PG_VERSION
diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32
index 22bbb91..ad61392 100644
--- a/src/include/pg_config.h.win32
+++ b/src/include/pg_config.h.win32
@@ -6,7 +6,7 @@
*
* HAVE_CBRT, HAVE_FUNCNAME_FUNC, HAVE_GETOPT, HAVE_GETOPT_H, HAVE_INTTYPES_H,
* HAVE_GETOPT_LONG, HAVE_LOCALE_T, HAVE_RINT, HAVE_STRINGS_H, HAVE_STRTOLL,
- * HAVE_STRTOULL, HAVE_STRUCT_OPTION, ENABLE_THREAD_SAFETY, PG_USE_INLINE,
+ * HAVE_STRTOULL, HAVE_STRUCT_OPTION, ENABLE_THREAD_SAFETY,
* inline, USE_SSE42_CRC32C_WITH_RUNTIME_CHECK
*/
@@ -622,10 +622,6 @@
/* Define to 1 to build with Bonjour support. (--with-bonjour) */
/* #undef USE_BONJOUR */
-/* Define to 1 if "static inline" works without unwanted warnings from
- compilations where static inline functions are defined but not called. */
-#define PG_USE_INLINE 1
-
/* Define to 1 if you want 64-bit integer timestamp and interval support.
(--enable-integer-datetimes) */
/* #undef USE_INTEGER_DATETIMES */
diff --git a/src/include/port/atomics.h b/src/include/port/atomics.h
index d94fea6..bb87945 100644
--- a/src/include/port/atomics.h
+++ b/src/include/port/atomics.h
@@ -118,46 +118,6 @@
*/
#include "port/atomics/generic.h"
-/*
- * Provide declarations for all functions here - on most platforms static
- * inlines are used and these aren't necessary, but when static inline is
- * unsupported these will be external functions.
- */
-STATIC_IF_INLINE_DECLARE void pg_atomic_init_flag(volatile pg_atomic_flag *ptr);
-STATIC_IF_INLINE_DECLARE bool pg_atomic_test_set_flag(volatile pg_atomic_flag *ptr);
-STATIC_IF_INLINE_DECLARE bool pg_atomic_unlocked_test_flag(volatile pg_atomic_flag *ptr);
-STATIC_IF_INLINE_DECLARE void pg_atomic_clear_flag(volatile pg_atomic_flag *ptr);
-
-STATIC_IF_INLINE_DECLARE void pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val);
-STATIC_IF_INLINE_DECLARE uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr);
-STATIC_IF_INLINE_DECLARE void pg_atomic_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val);
-STATIC_IF_INLINE_DECLARE uint32 pg_atomic_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 newval);
-STATIC_IF_INLINE_DECLARE bool pg_atomic_compare_exchange_u32(volatile pg_atomic_uint32 *ptr,
- uint32 *expected, uint32 newval);
-STATIC_IF_INLINE_DECLARE uint32 pg_atomic_fetch_add_u32(volatile pg_atomic_uint32 *ptr, int32 add_);
-STATIC_IF_INLINE_DECLARE uint32 pg_atomic_fetch_sub_u32(volatile pg_atomic_uint32 *ptr, int32 sub_);
-STATIC_IF_INLINE_DECLARE uint32 pg_atomic_fetch_and_u32(volatile pg_atomic_uint32 *ptr, uint32 and_);
-STATIC_IF_INLINE_DECLARE uint32 pg_atomic_fetch_or_u32(volatile pg_atomic_uint32 *ptr, uint32 or_);
-STATIC_IF_INLINE_DECLARE uint32 pg_atomic_add_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 add_);
-STATIC_IF_INLINE_DECLARE uint32 pg_atomic_sub_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 sub_);
-
-#ifdef PG_HAVE_ATOMIC_U64_SUPPORT
-
-STATIC_IF_INLINE_DECLARE void pg_atomic_init_u64(volatile pg_atomic_uint64 *ptr, uint64 val_);
-STATIC_IF_INLINE_DECLARE uint64 pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr);
-STATIC_IF_INLINE_DECLARE void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val);
-STATIC_IF_INLINE_DECLARE uint64 pg_atomic_exchange_u64(volatile pg_atomic_uint64 *ptr, uint64 newval);
-STATIC_IF_INLINE_DECLARE bool pg_atomic_compare_exchange_u64(volatile pg_atomic_uint64 *ptr,
- uint64 *expected, uint64 newval);
-STATIC_IF_INLINE_DECLARE uint64 pg_atomic_fetch_add_u64(volatile pg_atomic_uint64 *ptr, int64 add_);
-STATIC_IF_INLINE_DECLARE uint64 pg_atomic_fetch_sub_u64(volatile pg_atomic_uint64 *ptr, int64 sub_);
-STATIC_IF_INLINE_DECLARE uint64 pg_atomic_fetch_and_u64(volatile pg_atomic_uint64 *ptr, uint64 and_);
-STATIC_IF_INLINE_DECLARE uint64 pg_atomic_fetch_or_u64(volatile pg_atomic_uint64 *ptr, uint64 or_);
-STATIC_IF_INLINE_DECLARE uint64 pg_atomic_add_fetch_u64(volatile pg_atomic_uint64 *ptr, int64 add_);
-STATIC_IF_INLINE_DECLARE uint64 pg_atomic_sub_fetch_u64(volatile pg_atomic_uint64 *ptr, int64 sub_);
-
-#endif /* PG_HAVE_64_BIT_ATOMICS */
-
/*
* pg_compiler_barrier - prevent the compiler from moving code across
@@ -202,17 +162,11 @@ STATIC_IF_INLINE_DECLARE uint64 pg_atomic_sub_fetch_u64(volatile pg_atomic_uint6
#define pg_spin_delay() pg_spin_delay_impl()
/*
- * The following functions are wrapper functions around the platform specific
- * implementation of the atomic operations performing common checks.
- */
-#if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS)
-
-/*
* pg_atomic_init_flag - initialize atomic flag.
*
* No barrier semantics.
*/
-STATIC_IF_INLINE_DECLARE void
+static inline void
pg_atomic_init_flag(volatile pg_atomic_flag *ptr)
{
AssertPointerAlignment(ptr, sizeof(*ptr));
@@ -227,7 +181,7 @@ pg_atomic_init_flag(volatile pg_atomic_flag *ptr)
*
* Acquire (including read barrier) semantics.
*/
-STATIC_IF_INLINE_DECLARE bool
+static inline bool
pg_atomic_test_set_flag(volatile pg_atomic_flag *ptr)
{
AssertPointerAlignment(ptr, sizeof(*ptr));
@@ -242,7 +196,7 @@ pg_atomic_test_set_flag(volatile pg_atomic_flag *ptr)
*
* No barrier semantics.
*/
-STATIC_IF_INLINE_DECLARE bool
+static inline bool
pg_atomic_unlocked_test_flag(volatile pg_atomic_flag *ptr)
{
AssertPointerAlignment(ptr, sizeof(*ptr));
@@ -255,7 +209,7 @@ pg_atomic_unlocked_test_flag(volatile pg_atomic_flag *ptr)
*
* Release (including write barrier) semantics.
*/
-STATIC_IF_INLINE_DECLARE void
+static inline void
pg_atomic_clear_flag(volatile pg_atomic_flag *ptr)
{
AssertPointerAlignment(ptr, sizeof(*ptr));
@@ -271,7 +225,7 @@ pg_atomic_clear_flag(volatile pg_atomic_flag *ptr)
*
* No barrier semantics.
*/
-STATIC_IF_INLINE_DECLARE void
+static inline void
pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
{
AssertPointerAlignment(ptr, 4);
@@ -289,7 +243,7 @@ pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
*
* No barrier semantics.
*/
-STATIC_IF_INLINE uint32
+static inline uint32
pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
{
AssertPointerAlignment(ptr, 4);
@@ -304,7 +258,7 @@ pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
*
* No barrier semantics.
*/
-STATIC_IF_INLINE_DECLARE void
+static inline void
pg_atomic_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
{
AssertPointerAlignment(ptr, 4);
@@ -319,7 +273,7 @@ pg_atomic_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
*
* Full barrier semantics.
*/
-STATIC_IF_INLINE uint32
+static inline uint32
pg_atomic_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 newval)
{
AssertPointerAlignment(ptr, 4);
@@ -338,7 +292,7 @@ pg_atomic_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 newval)
*
* Full barrier semantics.
*/
-STATIC_IF_INLINE bool
+static inline bool
pg_atomic_compare_exchange_u32(volatile pg_atomic_uint32 *ptr,
uint32 *expected, uint32 newval)
{
@@ -355,7 +309,7 @@ pg_atomic_compare_exchange_u32(volatile pg_atomic_uint32 *ptr,
*
* Full barrier semantics.
*/
-STATIC_IF_INLINE uint32
+static inline uint32
pg_atomic_fetch_add_u32(volatile pg_atomic_uint32 *ptr, int32 add_)
{
AssertPointerAlignment(ptr, 4);
@@ -370,7 +324,7 @@ pg_atomic_fetch_add_u32(volatile pg_atomic_uint32 *ptr, int32 add_)
*
* Full barrier semantics.
*/
-STATIC_IF_INLINE uint32
+static inline uint32
pg_atomic_fetch_sub_u32(volatile pg_atomic_uint32 *ptr, int32 sub_)
{
AssertPointerAlignment(ptr, 4);
@@ -385,7 +339,7 @@ pg_atomic_fetch_sub_u32(volatile pg_atomic_uint32 *ptr, int32 sub_)
*
* Full barrier semantics.
*/
-STATIC_IF_INLINE uint32
+static inline uint32
pg_atomic_fetch_and_u32(volatile pg_atomic_uint32 *ptr, uint32 and_)
{
AssertPointerAlignment(ptr, 4);
@@ -399,7 +353,7 @@ pg_atomic_fetch_and_u32(volatile pg_atomic_uint32 *ptr, uint32 and_)
*
* Full barrier semantics.
*/
-STATIC_IF_INLINE uint32
+static inline uint32
pg_atomic_fetch_or_u32(volatile pg_atomic_uint32 *ptr, uint32 or_)
{
AssertPointerAlignment(ptr, 4);
@@ -413,7 +367,7 @@ pg_atomic_fetch_or_u32(volatile pg_atomic_uint32 *ptr, uint32 or_)
*
* Full barrier semantics.
*/
-STATIC_IF_INLINE uint32
+static inline uint32
pg_atomic_add_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 add_)
{
AssertPointerAlignment(ptr, 4);
@@ -428,7 +382,7 @@ pg_atomic_add_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 add_)
*
* Full barrier semantics.
*/
-STATIC_IF_INLINE uint32
+static inline uint32
pg_atomic_sub_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 sub_)
{
AssertPointerAlignment(ptr, 4);
@@ -444,7 +398,7 @@ pg_atomic_sub_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 sub_)
*/
#ifdef PG_HAVE_ATOMIC_U64_SUPPORT
-STATIC_IF_INLINE_DECLARE void
+static inline void
pg_atomic_init_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
{
AssertPointerAlignment(ptr, 8);
@@ -452,21 +406,21 @@ pg_atomic_init_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
pg_atomic_init_u64_impl(ptr, val);
}
-STATIC_IF_INLINE uint64
+static inline uint64
pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr)
{
AssertPointerAlignment(ptr, 8);
return pg_atomic_read_u64_impl(ptr);
}
-STATIC_IF_INLINE void
+static inline void
pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
{
AssertPointerAlignment(ptr, 8);
pg_atomic_write_u64_impl(ptr, val);
}
-STATIC_IF_INLINE uint64
+static inline uint64
pg_atomic_exchange_u64(volatile pg_atomic_uint64 *ptr, uint64 newval)
{
AssertPointerAlignment(ptr, 8);
@@ -474,7 +428,7 @@ pg_atomic_exchange_u64(volatile pg_atomic_uint64 *ptr, uint64 newval)
return pg_atomic_exchange_u64_impl(ptr, newval);
}
-STATIC_IF_INLINE bool
+static inline bool
pg_atomic_compare_exchange_u64(volatile pg_atomic_uint64 *ptr,
uint64 *expected, uint64 newval)
{
@@ -483,14 +437,14 @@ pg_atomic_compare_exchange_u64(volatile pg_atomic_uint64 *ptr,
return pg_atomic_compare_exchange_u64_impl(ptr, expected, newval);
}
-STATIC_IF_INLINE uint64
+static inline uint64
pg_atomic_fetch_add_u64(volatile pg_atomic_uint64 *ptr, int64 add_)
{
AssertPointerAlignment(ptr, 8);
return pg_atomic_fetch_add_u64_impl(ptr, add_);
}
-STATIC_IF_INLINE uint64
+static inline uint64
pg_atomic_fetch_sub_u64(volatile pg_atomic_uint64 *ptr, int64 sub_)
{
AssertPointerAlignment(ptr, 8);
@@ -498,28 +452,28 @@ pg_atomic_fetch_sub_u64(volatile pg_atomic_uint64 *ptr, int64 sub_)
return pg_atomic_fetch_sub_u64_impl(ptr, sub_);
}
-STATIC_IF_INLINE uint64
+static inline uint64
pg_atomic_fetch_and_u64(volatile pg_atomic_uint64 *ptr, uint64 and_)
{
AssertPointerAlignment(ptr, 8);
return pg_atomic_fetch_and_u64_impl(ptr, and_);
}
-STATIC_IF_INLINE uint64
+static inline uint64
pg_atomic_fetch_or_u64(volatile pg_atomic_uint64 *ptr, uint64 or_)
{
AssertPointerAlignment(ptr, 8);
return pg_atomic_fetch_or_u64_impl(ptr, or_);
}
-STATIC_IF_INLINE uint64
+static inline uint64
pg_atomic_add_fetch_u64(volatile pg_atomic_uint64 *ptr, int64 add_)
{
AssertPointerAlignment(ptr, 8);
return pg_atomic_add_fetch_u64_impl(ptr, add_);
}
-STATIC_IF_INLINE uint64
+static inline uint64
pg_atomic_sub_fetch_u64(volatile pg_atomic_uint64 *ptr, int64 sub_)
{
AssertPointerAlignment(ptr, 8);
@@ -529,9 +483,6 @@ pg_atomic_sub_fetch_u64(volatile pg_atomic_uint64 *ptr, int64 sub_)
#endif /* PG_HAVE_64_BIT_ATOMICS */
-#endif /* defined(PG_USE_INLINE) ||
- * defined(ATOMICS_INCLUDE_DEFINITIONS) */
-
#undef INSIDE_ATOMICS_H
#endif /* ATOMICS_H */
diff --git a/src/include/port/atomics/arch-x86.h b/src/include/port/atomics/arch-x86.h
index 168a49c..3f65acc 100644
--- a/src/include/port/atomics/arch-x86.h
+++ b/src/include/port/atomics/arch-x86.h
@@ -82,8 +82,6 @@ typedef struct pg_atomic_uint64
#endif /* defined(__GNUC__) && !defined(__INTEL_COMPILER) */
-#if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS)
-
#if !defined(PG_HAVE_SPIN_DELAY)
/*
* This sequence is equivalent to the PAUSE instruction ("rep" is
@@ -251,5 +249,3 @@ pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_)
#endif /* defined(__GNUC__) && !defined(__INTEL_COMPILER) */
#endif /* HAVE_ATOMICS */
-
-#endif /* defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) */
diff --git a/src/include/port/atomics/fallback.h b/src/include/port/atomics/fallback.h
index 4e04f97..df8ae56 100644
--- a/src/include/port/atomics/fallback.h
+++ b/src/include/port/atomics/fallback.h
@@ -102,8 +102,6 @@ typedef struct pg_atomic_uint32
#endif /* PG_HAVE_ATOMIC_U32_SUPPORT */
-#if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS)
-
#ifdef PG_HAVE_ATOMIC_FLAG_SIMULATION
#define PG_HAVE_ATOMIC_INIT_FLAG
@@ -143,6 +141,3 @@ extern bool pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr,
extern uint32 pg_atomic_fetch_add_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_);
#endif /* PG_HAVE_ATOMIC_U32_SIMULATION */
-
-
-#endif /* defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) */
diff --git a/src/include/port/atomics/generic-acc.h b/src/include/port/atomics/generic-acc.h
index c5639aa..e19a206 100644
--- a/src/include/port/atomics/generic-acc.h
+++ b/src/include/port/atomics/generic-acc.h
@@ -52,15 +52,13 @@ typedef struct pg_atomic_uint64
#endif /* defined(HAVE_ATOMICS) */
-#if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS)
-
#if defined(HAVE_ATOMICS)
#define MINOR_FENCE (_Asm_fence) (_UP_CALL_FENCE | _UP_SYS_FENCE | \
_DOWN_CALL_FENCE | _DOWN_SYS_FENCE )
#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32
-STATIC_IF_INLINE bool
+static inline bool
pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr,
uint32 *expected, uint32 newval)
{
@@ -88,7 +86,7 @@ pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr,
#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64
-STATIC_IF_INLINE bool
+static inline bool
pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr,
uint64 *expected, uint64 newval)
{
@@ -110,5 +108,3 @@ pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr,
#undef MINOR_FENCE
#endif /* defined(HAVE_ATOMICS) */
-
-#endif /* defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) */
diff --git a/src/include/port/atomics/generic-gcc.h b/src/include/port/atomics/generic-gcc.h
index 591c9fe..306c38f 100644
--- a/src/include/port/atomics/generic-gcc.h
+++ b/src/include/port/atomics/generic-gcc.h
@@ -57,6 +57,7 @@
# define pg_write_barrier_impl() __atomic_thread_fence(__ATOMIC_RELEASE)
#endif
+
#ifdef HAVE_ATOMICS
/* generic gcc based atomic flag implementation */
@@ -103,11 +104,6 @@ typedef struct pg_atomic_uint64
#endif /* defined(HAVE_GCC__ATOMIC_INT64_CAS) || defined(HAVE_GCC__SYNC_INT64_CAS) */
-/*
- * Implementation follows. Inlined or directly included from atomics.c
- */
-#if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS)
-
#ifdef PG_HAVE_ATOMIC_FLAG_SUPPORT
#if defined(HAVE_GCC__SYNC_CHAR_TAS) || defined(HAVE_GCC__SYNC_INT32_TAS)
@@ -231,6 +227,4 @@ pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_)
#endif /* !defined(PG_DISABLE_64_BIT_ATOMICS) */
-#endif /* defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) */
-
#endif /* defined(HAVE_ATOMICS) */
diff --git a/src/include/port/atomics/generic-msvc.h b/src/include/port/atomics/generic-msvc.h
index d259d6f..436baef 100644
--- a/src/include/port/atomics/generic-msvc.h
+++ b/src/include/port/atomics/generic-msvc.h
@@ -46,12 +46,6 @@ typedef struct __declspec(align(8)) pg_atomic_uint64
volatile uint64 value;
} pg_atomic_uint64;
-#endif /* defined(HAVE_ATOMICS) */
-
-
-#if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS)
-
-#if defined(HAVE_ATOMICS)
#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32
static inline bool
@@ -107,5 +101,3 @@ pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_)
#endif /* _WIN64 */
#endif /* HAVE_ATOMICS */
-
-#endif /* defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) */
diff --git a/src/include/port/atomics/generic-sunpro.h b/src/include/port/atomics/generic-sunpro.h
index d369207..867fab7 100644
--- a/src/include/port/atomics/generic-sunpro.h
+++ b/src/include/port/atomics/generic-sunpro.h
@@ -69,8 +69,6 @@ typedef struct pg_atomic_uint64
#endif /* defined(HAVE_ATOMICS) */
-#if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS)
-
#if defined(HAVE_ATOMICS)
#ifdef HAVE_ATOMIC_H
@@ -106,5 +104,3 @@ pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr,
#endif /* HAVE_ATOMIC_H */
#endif /* defined(HAVE_ATOMICS) */
-
-#endif /* defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) */
diff --git a/src/include/port/atomics/generic-xlc.h b/src/include/port/atomics/generic-xlc.h
index 0ad9168..4e26f88 100644
--- a/src/include/port/atomics/generic-xlc.h
+++ b/src/include/port/atomics/generic-xlc.h
@@ -35,12 +35,6 @@ typedef struct pg_atomic_uint64
#endif /* __64BIT__ */
-#endif /* defined(HAVE_ATOMICS) */
-
-#if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS)
-
-#if defined(HAVE_ATOMICS)
-
#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32
static inline bool
pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr,
@@ -91,5 +85,3 @@ pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_)
#endif /* PG_HAVE_ATOMIC_U64_SUPPORT */
#endif /* defined(HAVE_ATOMICS) */
-
-#endif /* defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) */
diff --git a/src/include/port/atomics/generic.h b/src/include/port/atomics/generic.h
index bb31df3..56a7c28 100644
--- a/src/include/port/atomics/generic.h
+++ b/src/include/port/atomics/generic.h
@@ -40,8 +40,6 @@
typedef pg_atomic_uint32 pg_atomic_flag;
#endif
-#if defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS)
-
#ifndef PG_HAVE_ATOMIC_READ_U32
#define PG_HAVE_ATOMIC_READ_U32
static inline uint32
@@ -383,5 +381,3 @@ pg_atomic_sub_fetch_u64_impl(volatile pg_atomic_uint64 *ptr, int64 sub_)
#endif
#endif /* PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64 */
-
-#endif /* defined(PG_USE_INLINE) || defined(ATOMICS_INCLUDE_DEFINITIONS) */
diff --git a/src/include/utils/arrayaccess.h b/src/include/utils/arrayaccess.h
index 72575d4..af808fd 100644
--- a/src/include/utils/arrayaccess.h
+++ b/src/include/utils/arrayaccess.h
@@ -44,20 +44,8 @@ typedef struct array_iter
int bitmask; /* mask for current bit in nulls bitmap */
} array_iter;
-/*
- * We want the functions below to be inline; but if the compiler doesn't
- * support that, fall back on providing them as regular functions. See
- * STATIC_IF_INLINE in c.h.
- */
-#ifndef PG_USE_INLINE
-extern void array_iter_setup(array_iter *it, AnyArrayType *a);
-extern Datum array_iter_next(array_iter *it, bool *isnull, int i,
- int elmlen, bool elmbyval, char elmalign);
-#endif /* !PG_USE_INLINE */
-#if defined(PG_USE_INLINE) || defined(ARRAYACCESS_INCLUDE_DEFINITIONS)
-
-STATIC_IF_INLINE void
+static inline void
array_iter_setup(array_iter *it, AnyArrayType *a)
{
if (VARATT_IS_EXPANDED_HEADER(a))
@@ -89,7 +77,7 @@ array_iter_setup(array_iter *it, AnyArrayType *a)
it->bitmask = 1;
}
-STATIC_IF_INLINE Datum
+static inline Datum
array_iter_next(array_iter *it, bool *isnull, int i,
int elmlen, bool elmbyval, char elmalign)
{
@@ -127,7 +115,4 @@ array_iter_next(array_iter *it, bool *isnull, int i,
return ret;
}
-#endif /* defined(PG_USE_INLINE) ||
- * defined(ARRAYACCESS_INCLUDE_DEFINITIONS) */
-
#endif /* ARRAYACCESS_H */
diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h
index e56f501..f2bcd00 100644
--- a/src/include/utils/palloc.h
+++ b/src/include/utils/palloc.h
@@ -98,10 +98,6 @@ extern void *MemoryContextAllocHuge(MemoryContext context, Size size);
extern void *repalloc_huge(void *pointer, Size size);
/*
- * MemoryContextSwitchTo can't be a macro in standard C compilers.
- * But we can make it an inline function if the compiler supports it.
- * See STATIC_IF_INLINE in c.h.
- *
* Although this header file is nominally backend-only, certain frontend
* programs like pg_controldata include it via postgres.h. For some compilers
* it's necessary to hide the inline definition of MemoryContextSwitchTo in
@@ -109,11 +105,7 @@ extern void *repalloc_huge(void *pointer, Size size);
*/
#ifndef FRONTEND
-#ifndef PG_USE_INLINE
-extern MemoryContext MemoryContextSwitchTo(MemoryContext context);
-#endif /* !PG_USE_INLINE */
-#if defined(PG_USE_INLINE) || defined(MCXT_INCLUDE_DEFINITIONS)
-STATIC_IF_INLINE MemoryContext
+static inline MemoryContext
MemoryContextSwitchTo(MemoryContext context)
{
MemoryContext old = CurrentMemoryContext;
@@ -121,7 +113,6 @@ MemoryContextSwitchTo(MemoryContext context)
CurrentMemoryContext = context;
return old;
}
-#endif /* PG_USE_INLINE || MCXT_INCLUDE_DEFINITIONS */
#endif /* FRONTEND */
/* Registration of memory context reset/delete callbacks */
diff --git a/src/include/utils/sortsupport.h b/src/include/utils/sortsupport.h
index 787404e..4258630 100644
--- a/src/include/utils/sortsupport.h
+++ b/src/include/utils/sortsupport.h
@@ -193,23 +193,10 @@ typedef struct SortSupportData
/*
- * ApplySortComparator should be inlined if possible. See STATIC_IF_INLINE
- * in c.h.
- */
-#ifndef PG_USE_INLINE
-extern int ApplySortComparator(Datum datum1, bool isNull1,
- Datum datum2, bool isNull2,
- SortSupport ssup);
-extern int ApplySortAbbrevFullComparator(Datum datum1, bool isNull1,
- Datum datum2, bool isNull2,
- SortSupport ssup);
-#endif /* !PG_USE_INLINE */
-#if defined(PG_USE_INLINE) || defined(SORTSUPPORT_INCLUDE_DEFINITIONS)
-/*
* Apply a sort comparator function and return a 3-way comparison result.
* This takes care of handling reverse-sort and NULLs-ordering properly.
*/
-STATIC_IF_INLINE int
+static inline int
ApplySortComparator(Datum datum1, bool isNull1,
Datum datum2, bool isNull2,
SortSupport ssup)
@@ -247,7 +234,7 @@ ApplySortComparator(Datum datum1, bool isNull1,
* authoritative comparator. This takes care of handling reverse-sort and
* NULLs-ordering properly.
*/
-STATIC_IF_INLINE int
+static inline int
ApplySortAbbrevFullComparator(Datum datum1, bool isNull1,
Datum datum2, bool isNull2,
SortSupport ssup)
@@ -279,7 +266,6 @@ ApplySortAbbrevFullComparator(Datum datum1, bool isNull1,
return compare;
}
-#endif /*-- PG_USE_INLINE || SORTSUPPORT_INCLUDE_DEFINITIONS */
/* Other functions in utils/sort/sortsupport.c */
extern void PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup);
--
2.3.0.149.gf3f4077.dirty
On 2015-08-05 15:08:29 +0200, Andres Freund wrote:
We might later want to change some of the harder to maintain macros to
inline functions, but that seems better done separately.
Here's a conversion for fastgetattr() and heap_getattr(). Not only is
the resulting code significantly more readable, but the conversion also
shrinks the code size:
$ ls -l src/backend/postgres_stock src/backend/postgres
-rwxr-xr-x 1 andres andres 37054832 Aug 5 15:18 src/backend/postgres_stock
-rwxr-xr-x 1 andres andres 37209288 Aug 5 15:23 src/backend/postgres
$ size src/backend/postgres_stock src/backend/postgres
text data bss dec hex filename
7026843 49982 298584 7375409 708a31 src/backend/postgres_stock
7023851 49982 298584 7372417 707e81 src/backend/postgres
stock is the binary compiled without the conversion.
A lot of the size difference is debugging information (which now needs
less duplicated information on each callsite), but you can see that the
text section (the actual executable code) shrank by 3k.
stripping the binary shows exactly that:
-rwxr-xr-x 1 andres andres 7076760 Aug 5 15:44 src/backend/postgres_s
-rwxr-xr-x 1 andres andres 7079512 Aug 5 15:45 src/backend/postgres_stock_s
To be sure this doesn't cause problems I ran a readonly pgbench. There's
a very slight, but reproducible, performance benefit. I don't think
that's a reason for the change, I just wanted to make sure there's no
regressions.
Regards,
Andres
Attachments:
0001-Convert-fastgetattr-and-heap_getattr-into-inline-fun.patchtext/x-patch; charset=us-asciiDownload
>From cca830c39a6c46caf0c68b340399cf60f04ad31f Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Wed, 5 Aug 2015 15:30:20 +0200
Subject: [PATCH] Convert fastgetattr() and heap_getattr() into inline
functions.
The current macro is very hard to read. Now that we can unconditionally
use inline functions there's no reason to keep them that way.
In my gcc 5 based environment this shaves of nearly 200k of the final
binary size. A lot of that is debugging information, but the .text
section alone shrinks by 3k.
---
src/backend/access/heap/heapam.c | 46 -----------
src/include/access/htup_details.h | 157 ++++++++++++++++++--------------------
2 files changed, 75 insertions(+), 128 deletions(-)
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 3701d8e..ff93b3c 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -983,52 +983,6 @@ heapgettup_pagemode(HeapScanDesc scan,
}
-#if defined(DISABLE_COMPLEX_MACRO)
-/*
- * This is formatted so oddly so that the correspondence to the macro
- * definition in access/htup_details.h is maintained.
- */
-Datum
-fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
- bool *isnull)
-{
- return (
- (attnum) > 0 ?
- (
- (*(isnull) = false),
- HeapTupleNoNulls(tup) ?
- (
- (tupleDesc)->attrs[(attnum) - 1]->attcacheoff >= 0 ?
- (
- fetchatt((tupleDesc)->attrs[(attnum) - 1],
- (char *) (tup)->t_data + (tup)->t_data->t_hoff +
- (tupleDesc)->attrs[(attnum) - 1]->attcacheoff)
- )
- :
- nocachegetattr((tup), (attnum), (tupleDesc))
- )
- :
- (
- att_isnull((attnum) - 1, (tup)->t_data->t_bits) ?
- (
- (*(isnull) = true),
- (Datum) NULL
- )
- :
- (
- nocachegetattr((tup), (attnum), (tupleDesc))
- )
- )
- )
- :
- (
- (Datum) NULL
- )
- );
-}
-#endif /* defined(DISABLE_COMPLEX_MACRO) */
-
-
/* ----------------------------------------------------------------
* heap access method interface
* ----------------------------------------------------------------
diff --git a/src/include/access/htup_details.h b/src/include/access/htup_details.h
index 8dd530bd..9d49c5e 100644
--- a/src/include/access/htup_details.h
+++ b/src/include/access/htup_details.h
@@ -673,6 +673,38 @@ struct MinimalTupleData
#define HeapTupleSetOid(tuple, oid) \
HeapTupleHeaderSetOid((tuple)->t_data, (oid))
+/* prototypes for functions in common/heaptuple.c */
+extern Size heap_compute_data_size(TupleDesc tupleDesc,
+ Datum *values, bool *isnull);
+extern void heap_fill_tuple(TupleDesc tupleDesc,
+ Datum *values, bool *isnull,
+ char *data, Size data_size,
+ uint16 *infomask, bits8 *bit);
+extern bool heap_attisnull(HeapTuple tup, int attnum);
+extern Datum nocachegetattr(HeapTuple tup, int attnum,
+ TupleDesc att);
+extern Datum heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
+ bool *isnull);
+extern HeapTuple heap_copytuple(HeapTuple tuple);
+extern void heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest);
+extern Datum heap_copy_tuple_as_datum(HeapTuple tuple, TupleDesc tupleDesc);
+extern HeapTuple heap_form_tuple(TupleDesc tupleDescriptor,
+ Datum *values, bool *isnull);
+extern HeapTuple heap_modify_tuple(HeapTuple tuple,
+ TupleDesc tupleDesc,
+ Datum *replValues,
+ bool *replIsnull,
+ bool *doReplace);
+extern void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc,
+ Datum *values, bool *isnull);
+extern void heap_freetuple(HeapTuple htup);
+extern MinimalTuple heap_form_minimal_tuple(TupleDesc tupleDescriptor,
+ Datum *values, bool *isnull);
+extern void heap_free_minimal_tuple(MinimalTuple mtup);
+extern MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup);
+extern HeapTuple heap_tuple_from_minimal_tuple(MinimalTuple mtup);
+extern MinimalTuple minimal_tuple_from_heap_tuple(HeapTuple htup);
+
/* ----------------
* fastgetattr
@@ -688,43 +720,34 @@ struct MinimalTupleData
* lookups, and call nocachegetattr() for the rest.
* ----------------
*/
+static inline Datum
+fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
+ bool *isnull)
+{
+ AssertArg(attnum > 0);
-#if !defined(DISABLE_COMPLEX_MACRO)
-
-#define fastgetattr(tup, attnum, tupleDesc, isnull) \
-( \
- AssertMacro((attnum) > 0), \
- (*(isnull) = false), \
- HeapTupleNoNulls(tup) ? \
- ( \
- (tupleDesc)->attrs[(attnum)-1]->attcacheoff >= 0 ? \
- ( \
- fetchatt((tupleDesc)->attrs[(attnum)-1], \
- (char *) (tup)->t_data + (tup)->t_data->t_hoff + \
- (tupleDesc)->attrs[(attnum)-1]->attcacheoff) \
- ) \
- : \
- nocachegetattr((tup), (attnum), (tupleDesc)) \
- ) \
- : \
- ( \
- att_isnull((attnum)-1, (tup)->t_data->t_bits) ? \
- ( \
- (*(isnull) = true), \
- (Datum)NULL \
- ) \
- : \
- ( \
- nocachegetattr((tup), (attnum), (tupleDesc)) \
- ) \
- ) \
-)
-#else /* defined(DISABLE_COMPLEX_MACRO) */
-
-extern Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
- bool *isnull);
-#endif /* defined(DISABLE_COMPLEX_MACRO) */
+ *isnull = false;
+
+ if (HeapTupleNoNulls(tup))
+ {
+ Form_pg_attribute attr = tupleDesc->attrs[attnum - 1];
+ if (attr->attcacheoff >= 0)
+ {
+ return fetchatt(attr,
+ (char *) tup->t_data +
+ tup->t_data->t_hoff +
+ attr->attcacheoff);
+ }
+ /* fall through to nocachegetattr */
+ }
+ else if (att_isnull(attnum - 1, tup->t_data->t_bits))
+ {
+ *isnull = true;
+ return (Datum) NULL;
+ }
+ return nocachegetattr(tup, attnum, tupleDesc);
+}
/* ----------------
* heap_getattr
@@ -741,53 +764,23 @@ extern Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
* pointer to the structure describing the row and all its fields.
* ----------------
*/
-#define heap_getattr(tup, attnum, tupleDesc, isnull) \
- ( \
- ((attnum) > 0) ? \
- ( \
- ((attnum) > (int) HeapTupleHeaderGetNatts((tup)->t_data)) ? \
- ( \
- (*(isnull) = true), \
- (Datum)NULL \
- ) \
- : \
- fastgetattr((tup), (attnum), (tupleDesc), (isnull)) \
- ) \
- : \
- heap_getsysattr((tup), (attnum), (tupleDesc), (isnull)) \
- )
-
+static inline Datum
+heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
+ bool *isnull)
+{
+ if (attnum > 0)
+ {
+ if (attnum > HeapTupleHeaderGetNatts((tup)->t_data))
+ {
+ *isnull = true;
+ return (Datum) NULL;
+ }
+ else
+ return fastgetattr(tup, attnum, tupleDesc, isnull);
+ }
+
+ return heap_getsysattr(tup, attnum, tupleDesc, isnull);
+}
-/* prototypes for functions in common/heaptuple.c */
-extern Size heap_compute_data_size(TupleDesc tupleDesc,
- Datum *values, bool *isnull);
-extern void heap_fill_tuple(TupleDesc tupleDesc,
- Datum *values, bool *isnull,
- char *data, Size data_size,
- uint16 *infomask, bits8 *bit);
-extern bool heap_attisnull(HeapTuple tup, int attnum);
-extern Datum nocachegetattr(HeapTuple tup, int attnum,
- TupleDesc att);
-extern Datum heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
- bool *isnull);
-extern HeapTuple heap_copytuple(HeapTuple tuple);
-extern void heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest);
-extern Datum heap_copy_tuple_as_datum(HeapTuple tuple, TupleDesc tupleDesc);
-extern HeapTuple heap_form_tuple(TupleDesc tupleDescriptor,
- Datum *values, bool *isnull);
-extern HeapTuple heap_modify_tuple(HeapTuple tuple,
- TupleDesc tupleDesc,
- Datum *replValues,
- bool *replIsnull,
- bool *doReplace);
-extern void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc,
- Datum *values, bool *isnull);
-extern void heap_freetuple(HeapTuple htup);
-extern MinimalTuple heap_form_minimal_tuple(TupleDesc tupleDescriptor,
- Datum *values, bool *isnull);
-extern void heap_free_minimal_tuple(MinimalTuple mtup);
-extern MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup);
-extern HeapTuple heap_tuple_from_minimal_tuple(MinimalTuple mtup);
-extern MinimalTuple minimal_tuple_from_heap_tuple(HeapTuple htup);
#endif /* HTUP_DETAILS_H */
--
2.3.0.149.gf3f4077.dirty
Andres Freund <andres@anarazel.de> writes:
On 2015-08-05 14:05:24 +0200, Andres Freund wrote:
So unless somebody protests I'm going to prepare (and commit after
posting) a patch to rip out the bits of code that currently depend on
PG_USE_INLINE.
Here's that patch. I only removed code dependant on PG_USE_INLINE. We
might later want to change some of the harder to maintain macros to
inline functions, but that seems better done separately.
Hmm. I notice that this removes Noah's hack from commit c53f73879f552a3c.
Do we care about breaking old versions of xlc, and if so, how are we going
to fix that? (I assume it should be possible to override AC_C_INLINE's
result, but I'm not sure where would be a good place to do so.)
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-05 10:08:10 -0400, Tom Lane wrote:
Andres Freund <andres@anarazel.de> writes:
On 2015-08-05 14:05:24 +0200, Andres Freund wrote:
So unless somebody protests I'm going to prepare (and commit after
posting) a patch to rip out the bits of code that currently depend on
PG_USE_INLINE.Here's that patch. I only removed code dependant on PG_USE_INLINE. We
might later want to change some of the harder to maintain macros to
inline functions, but that seems better done separately.Hmm. I notice that this removes Noah's hack from commit c53f73879f552a3c.
Do we care about breaking old versions of xlc, and if so, how are we going
to fix that? (I assume it should be possible to override AC_C_INLINE's
result, but I'm not sure where would be a good place to do so.)
Hm. That's a good point.
How about moving that error check into into the aix template file and
erroring out there? Since this is master I think it's perfectly fine to
refuse to work with the buggy unsupported 32 bit compiler. The argument
not to do so was that PG previously worked in the back branches
depending on the minor version, but that's not an argument on master.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@anarazel.de> writes:
On 2015-08-05 10:08:10 -0400, Tom Lane wrote:
Hmm. I notice that this removes Noah's hack from commit c53f73879f552a3c.
Do we care about breaking old versions of xlc, and if so, how are we going
to fix that? (I assume it should be possible to override AC_C_INLINE's
result, but I'm not sure where would be a good place to do so.)
Hm. That's a good point.
How about moving that error check into into the aix template file and
erroring out there? Since this is master I think it's perfectly fine to
refuse to work with the buggy unsupported 32 bit compiler. The argument
not to do so was that PG previously worked in the back branches
depending on the minor version, but that's not an argument on master.
The check as Noah wrote it rejects *all* 32-bit IBM compilers, not just
buggy ones. That was okay when the effect was only a rather minor
performance loss, but refusing to build at all would raise the stakes
quite a lot. Unless you are volunteering to find out how to tell broken
compilers from fixed ones more accurately, I think you need to confine
the effects of the check to disabling inlining.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-05 10:23:31 -0400, Tom Lane wrote:
Andres Freund <andres@anarazel.de> writes:
How about moving that error check into into the aix template file and
erroring out there? Since this is master I think it's perfectly fine to
refuse to work with the buggy unsupported 32 bit compiler. The argument
not to do so was that PG previously worked in the back branches
depending on the minor version, but that's not an argument on master.The check as Noah wrote it rejects *all* 32-bit IBM compilers, not just
buggy ones. That was okay when the effect was only a rather minor
performance loss, but refusing to build at all would raise the stakes
quite a lot. Unless you are volunteering to find out how to tell broken
compilers from fixed ones more accurately, I think you need to confine
the effects of the check to disabling inlining.
Wasn't the point that 32 bit AIX as a whole hasn't been supported for a
couple years now? My willingness to expend effort for that is rather
limited.
I mean I'd otherwise ok with a PG_FORCE_DISABLE_INLINE flag that takes
effect in c.h or so. That could easily be set in src/template/aix. Might
also be useful for investigatory purposes every couple years or so.
Andres
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@anarazel.de> writes:
Wasn't the point that 32 bit AIX as a whole hasn't been supported for a
couple years now? My willingness to expend effort for that is rather
limited.
Well, there's one in the buildfarm. We don't generally turn off
buildfarm critters just because the underlying OS is out of support
(the population would be quite a bit lower if we did).
I mean I'd otherwise ok with a PG_FORCE_DISABLE_INLINE flag that takes
effect in c.h or so. That could easily be set in src/template/aix. Might
also be useful for investigatory purposes every couple years or so.
+1, that could have other use-cases.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-05 10:32:48 -0400, Tom Lane wrote:
Andres Freund <andres@anarazel.de> writes:
Wasn't the point that 32 bit AIX as a whole hasn't been supported for a
couple years now? My willingness to expend effort for that is rather
limited.Well, there's one in the buildfarm.
Oh nice. That's new. I see it has been added less than a week ago ;)
We don't generally turn off buildfarm critters just because the
underlying OS is out of support (the population would be quite a bit
lower if we did).
I didn't know there was a buildfarm animal. We'd been pleading a bunch
of people over the last few years to add one. If there's an actual way
to see platforms breaking I'm more accepting to try and keep them alive.
I mean I'd otherwise ok with a PG_FORCE_DISABLE_INLINE flag that takes
effect in c.h or so. That could easily be set in src/template/aix. Might
also be useful for investigatory purposes every couple years or so.+1, that could have other use-cases.
Ok, lets' do it that way then. It seems the easiest way to test for this
is to use something like
# "IBM XL C/C++ for AIX, V12.1" miscompiles, for 32-bit, some inline
# expansions of ginCompareItemPointers() "long long" arithmetic. To
# take advantage of inlining, build a 64-bit PostgreSQL.
test $(getconf HARDWARE_BITMODE) == '32' then
CFLAGS="$CFLAGS -DPG_FORCE_DISABLE_INLINE"
fi
in the xlc part of the template?
do we want to add something like
$as_echo "$as_me: WARNING: disabling inlining on 32 bit aix due to compiler bugs"
? Seems like a good idea to me.
Andres
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@anarazel.de> writes:
Ok, lets' do it that way then. It seems the easiest way to test for this
is to use something like
# "IBM XL C/C++ for AIX, V12.1" miscompiles, for 32-bit, some inline
# expansions of ginCompareItemPointers() "long long" arithmetic. To
# take advantage of inlining, build a 64-bit PostgreSQL.
test $(getconf HARDWARE_BITMODE) == '32' then
CFLAGS="$CFLAGS -DPG_FORCE_DISABLE_INLINE"
fi
in the xlc part of the template?
Actually, much the easiest way to convert what Noah did would be to add
#if defined(__ILP32__) && defined(__IBMC__)
#define PG_FORCE_DISABLE_INLINE
#endif
in src/include/port/aix.h.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-05 11:12:34 -0400, Tom Lane wrote:
Andres Freund <andres@anarazel.de> writes:
Ok, lets' do it that way then. It seems the easiest way to test for this
is to use something like# "IBM XL C/C++ for AIX, V12.1" miscompiles, for 32-bit, some inline
# expansions of ginCompareItemPointers() "long long" arithmetic. To
# take advantage of inlining, build a 64-bit PostgreSQL.
test $(getconf HARDWARE_BITMODE) == '32' then
CFLAGS="$CFLAGS -DPG_FORCE_DISABLE_INLINE"
fiin the xlc part of the template?
(there's a ; missing and it should be CPPFLAGS rather than CFLAGS)
Actually, much the easiest way to convert what Noah did would be to add
#if defined(__ILP32__) && defined(__IBMC__)
#define PG_FORCE_DISABLE_INLINE
#endifin src/include/port/aix.h.
I'm ok with that too, although I do like the warning at configure
time. I'd go with the template approach due to that, but I don't feel
strongly about it.
Andres
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@anarazel.de> writes:
I'm ok with that too, although I do like the warning at configure
time. I'd go with the template approach due to that, but I don't feel
strongly about it.
Meh. I did *not* like the way you proposed doing that: it looked far too
dependent on autoconf internals (the kind that they change regularly).
If you can think of a way of emitting a warning that isn't going to break
in a future autoconf release, then ok.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-05 11:23:22 -0400, Tom Lane wrote:
Andres Freund <andres@anarazel.de> writes:
I'm ok with that too, although I do like the warning at configure
time. I'd go with the template approach due to that, but I don't feel
strongly about it.Meh. I did *not* like the way you proposed doing that: it looked far too
dependent on autoconf internals (the kind that they change regularly).
Hm, I'd actually checked that as_echo worked back till 9.0. But it
doesn't exist in much older releases.
If you can think of a way of emitting a warning that isn't going to break
in a future autoconf release, then ok.
echo "$as_me: WARNING: disabling inlining on 32 bit aix due to a bug in xlc" 2>&1
then. That'd have worked back in 7.4 and the worst that'd happen is that
$as_me is empty.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-05 17:19:05 +0200, Andres Freund wrote:
On 2015-08-05 11:12:34 -0400, Tom Lane wrote:
Andres Freund <andres@anarazel.de> writes:
Ok, lets' do it that way then. It seems the easiest way to test for this
is to use something like# "IBM XL C/C++ for AIX, V12.1" miscompiles, for 32-bit, some inline
# expansions of ginCompareItemPointers() "long long" arithmetic. To
# take advantage of inlining, build a 64-bit PostgreSQL.
test $(getconf HARDWARE_BITMODE) == '32' then
CFLAGS="$CFLAGS -DPG_FORCE_DISABLE_INLINE"
fi
So that approach doesn't work out well because the 32 bit xlc can be
installed on the 64 bit system.
Actually, much the easiest way to convert what Noah did would be to add
#if defined(__ILP32__) && defined(__IBMC__)
#define PG_FORCE_DISABLE_INLINE
#endifin src/include/port/aix.h.
Therefore I'm going to reshuffle things in that direction tomorrow. I'll
wait for other fallout first though. So far only gcc, xlc and clang (via
gcc frontend) have run...
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Aug 05, 2015 at 10:32:48AM -0400, Tom Lane wrote:
Andres Freund <andres@anarazel.de> writes:
Wasn't the point that 32 bit AIX as a whole hasn't been supported for a
couple years now? My willingness to expend effort for that is rather
limited.Well, there's one in the buildfarm. We don't generally turn off
buildfarm critters just because the underlying OS is out of support
(the population would be quite a bit lower if we did).
For the record, mandrill's OS and compiler are both in support and not so old
(June 2012 compiler, February 2013 OS). The last 32-bit AIX *kernel* did exit
support in 2012, but 32-bit executables remain the norm.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@anarazel.de> writes:
... I'm going to reshuffle things in that direction tomorrow. I'll
wait for other fallout first though. So far only gcc, xlc and clang (via
gcc frontend) have run...
In the department of "other fallout", pademelon is not happy:
cc -Ae -g +O0 -Wp,-H16384 -I../../../src/include -D_XOPEN_SOURCE_EXTENDED -I/usr/local/libxml2-2.6.23/include/libxml2 -I/usr/local/include -c -o pg_resetxlog.o pg_resetxlog.c
cc -Ae -g +O0 -Wp,-H16384 pg_resetxlog.o -L../../../src/port -L../../../src/common -L/usr/local/libxml2-2.6.23/lib -L/usr/local/lib -Wl,+b -Wl,'/home/bfarm/bf-data/HEAD/inst/lib' -Wl,-z -lpgcommon -lpgport -lxnet -lxml2 -lz -lreadline -ltermcap -lm -o pg_resetxlog
/usr/ccs/bin/ld: Unsatisfied symbols:
pg_atomic_clear_flag_impl (code)
pg_atomic_init_flag_impl (code)
pg_atomic_compare_exchange_u32_impl (code)
pg_atomic_fetch_add_u32_impl (code)
pg_atomic_test_set_flag_impl (code)
pg_atomic_init_u32_impl (code)
make[3]: *** [pg_resetxlog] Error 1
I'd have thought that port/atomics.c would be included in libpgport, but
it seems not. (But is pademelon really the only buildfarm critter relying
on the "fallback" atomics implementation?)
Another possible angle is: what the heck does pg_resetxlog need with
atomic ops, anyway? Should these things have a different, stub
implementation for FRONTEND code?
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-05 23:18:08 -0400, Tom Lane wrote:
Andres Freund <andres@anarazel.de> writes:
... I'm going to reshuffle things in that direction tomorrow. I'll
wait for other fallout first though. So far only gcc, xlc and clang (via
gcc frontend) have run...In the department of "other fallout", pademelon is not happy:
cc -Ae -g +O0 -Wp,-H16384 -I../../../src/include -D_XOPEN_SOURCE_EXTENDED -I/usr/local/libxml2-2.6.23/include/libxml2 -I/usr/local/include -c -o pg_resetxlog.o pg_resetxlog.c
cc -Ae -g +O0 -Wp,-H16384 pg_resetxlog.o -L../../../src/port -L../../../src/common -L/usr/local/libxml2-2.6.23/lib -L/usr/local/lib -Wl,+b -Wl,'/home/bfarm/bf-data/HEAD/inst/lib' -Wl,-z -lpgcommon -lpgport -lxnet -lxml2 -lz -lreadline -ltermcap -lm -o pg_resetxlog
/usr/ccs/bin/ld: Unsatisfied symbols:
pg_atomic_clear_flag_impl (code)
pg_atomic_init_flag_impl (code)
pg_atomic_compare_exchange_u32_impl (code)
pg_atomic_fetch_add_u32_impl (code)
pg_atomic_test_set_flag_impl (code)
pg_atomic_init_u32_impl (code)
make[3]: *** [pg_resetxlog] Error 1I'd have thought that port/atomics.c would be included in libpgport, but
it seems not.
Given that it requires spinlocks for the fallback, which in turn may
require semaphores, that didn't seem like a good idea. Thus atomics.c is
in src/backend/port not src/port (just like other locking stuff like
spinlocks, semaphores etc).
(But is pademelon really the only buildfarm critter relying
on the "fallback" atomics implementation?)
I don't think so. At least that didn't use to be the case. My guess is
that less ancient compilers don't emit code for unreferenced functions
and this thus doesn't show up.
Another possible angle is: what the heck does pg_resetxlog need with
atomic ops, anyway?
It really doesn't. It's just fallout from indirectly including lwlock.h
which includes an atomic variable. The include path leading to it is
In file included from /home/andres/src/postgresql/src/include/storage/lwlock.h:19:0,
from /home/andres/src/postgresql/src/include/storage/lock.h:18,
from /home/andres/src/postgresql/src/include/access/tuptoaster.h:18,
from /home/andres/src/postgresql/src/bin/pg_resetxlog/pg_resetxlog.c:49:
/home/andres/src/postgresql/src/include/port/atomics.h:41:2: error: #error "THOU SHALL NOT REQUIRE ATOMICS"
#error "THOU SHALL NOT REQUIRE ATOMICS"
There's other path's (slot.h) as well if that were fixed.
Should these things have a different, stub implementation for FRONTEND
code?
I'm honestly not yet sure what the best approach here would be.
One approach is to avoid including lwlock.h/slot.h in frontend
code. That'll require some minor surgery and adding a couple includes,
but it doesn't look that bad.
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-06 09:09:02 +0200, Andres Freund wrote:
It really doesn't. It's just fallout from indirectly including lwlock.h
which includes an atomic variable. The include path leading to it isIn file included from /home/andres/src/postgresql/src/include/storage/lwlock.h:19:0,
from /home/andres/src/postgresql/src/include/storage/lock.h:18,
from /home/andres/src/postgresql/src/include/access/tuptoaster.h:18,
from /home/andres/src/postgresql/src/bin/pg_resetxlog/pg_resetxlog.c:49:
/home/andres/src/postgresql/src/include/port/atomics.h:41:2: error: #error "THOU SHALL NOT REQUIRE ATOMICS"
#error "THOU SHALL NOT REQUIRE ATOMICS"There's other path's (slot.h) as well if that were fixed.
Should these things have a different, stub implementation for FRONTEND
code?I'm honestly not yet sure what the best approach here would be.
One approach is to avoid including lwlock.h/slot.h in frontend
code. That'll require some minor surgery and adding a couple includes,
but it doesn't look that bad.
Patch doing that attached.
It's easy enough right now, but I'm not entirely sure how feasible it is
going forward. I mean it's rather good if frontends do not end up
including s_lock.h, lwlock.h, atomics.h and such. But if some more code
ends up using lwlocks inline instead of referencing them that might get
harder. On the other hand no code doing that has business being included
by frontend code. In the end I think that this separation is worth some
pain.
As a consequence I think we should actually add a bunch of #ifdef
FRONTEND #error checks in code we definitely do not want to included in
frontend code. The attached patch so far adds a check to atomics.h,
lwlock.h and s_lock.h.
Before ea9df812d - "Relax the requirement that all lwlocks be stored in
a single array." it was kinda ok that lock.h includes lwlock.h since
that didn't expose its implementation details much. But after that it
started to need s_lock.h exposed (and now atomics.h as well). I think
that changed the game somewhat.
Comments?
- Andres
Attachments:
0001-Don-t-include-low-level-locking-code-from-frontend-c.patchtext/x-patch; charset=us-asciiDownload
>From f4b6d8876a269c0847d0d5b749ee673d0275b5aa Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Thu, 6 Aug 2015 12:53:56 +0200
Subject: [PATCH] Don't include low level locking code from frontend code.
Sinc eea9df812d lwlock.h also includes s_lock.h, and ab5194e6 extended
that to atomics.h. It's not good that frontend code if frontend code
includes that, so rearrange things that it doesnt' anymore.
To avoid that happening again put some checks agains this happening into
atomics.h, lwlock.h and s_lock.h.
---
contrib/pg_stat_statements/pg_stat_statements.c | 1 +
src/backend/access/heap/syncscan.c | 1 +
src/backend/access/nbtree/nbtutils.c | 1 +
src/backend/access/transam/twophase.c | 1 +
src/backend/access/transam/varsup.c | 1 +
src/backend/access/transam/xact.c | 1 +
src/backend/access/transam/xlog.c | 1 +
src/backend/commands/tablespace.c | 1 +
src/backend/replication/logical/origin.c | 1 +
src/backend/utils/cache/relcache.c | 1 +
src/include/port/atomics.h | 4 ++++
src/include/storage/lock.h | 1 -
src/include/storage/lwlock.h | 4 ++++
src/include/storage/proc.h | 1 +
src/include/storage/s_lock.h | 4 ++++
15 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 59b8a2e..3839b46 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -72,6 +72,7 @@
#include "pgstat.h"
#include "storage/fd.h"
#include "storage/ipc.h"
+#include "storage/lwlock.h"
#include "storage/spin.h"
#include "tcop/utility.h"
#include "utils/builtins.h"
diff --git a/src/backend/access/heap/syncscan.c b/src/backend/access/heap/syncscan.c
index 266c330..9a3b94b 100644
--- a/src/backend/access/heap/syncscan.c
+++ b/src/backend/access/heap/syncscan.c
@@ -48,6 +48,7 @@
#include "access/heapam.h"
#include "miscadmin.h"
+#include "storage/lwlock.h"
#include "utils/rel.h"
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index 91331ba..fa9b87b 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -21,6 +21,7 @@
#include "access/reloptions.h"
#include "access/relscan.h"
#include "miscadmin.h"
+#include "storage/lwlock.h"
#include "utils/array.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index 177d1e1..952ef98 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -60,6 +60,7 @@
#include "replication/syncrep.h"
#include "storage/fd.h"
#include "storage/ipc.h"
+#include "storage/lwlock.h"
#include "storage/predicate.h"
#include "storage/proc.h"
#include "storage/procarray.h"
diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index cf3e964..428c3ff 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -22,6 +22,7 @@
#include "commands/dbcommands.h"
#include "miscadmin.h"
#include "postmaster/autovacuum.h"
+#include "storage/lwlock.h"
#include "storage/pmsignal.h"
#include "storage/proc.h"
#include "utils/syscache.h"
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index b53d95f..732b14e 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -47,6 +47,7 @@
#include "replication/origin.h"
#include "storage/fd.h"
#include "storage/lmgr.h"
+#include "storage/lwlock.h"
#include "storage/predicate.h"
#include "storage/proc.h"
#include "storage/procarray.h"
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 68e33eb..1568888 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -56,6 +56,7 @@
#include "storage/ipc.h"
#include "storage/large_object.h"
#include "storage/latch.h"
+#include "storage/lwlock.h"
#include "storage/pmsignal.h"
#include "storage/predicate.h"
#include "storage/proc.h"
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index ff0d904..1f56b51 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -73,6 +73,7 @@
#include "postmaster/bgwriter.h"
#include "storage/fd.h"
#include "storage/lmgr.h"
+#include "storage/lwlock.h"
#include "storage/standby.h"
#include "utils/acl.h"
#include "utils/builtins.h"
diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
index f4ba86e..49f5476 100644
--- a/src/backend/replication/logical/origin.c
+++ b/src/backend/replication/logical/origin.c
@@ -88,6 +88,7 @@
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/lmgr.h"
+#include "storage/lwlock.h"
#include "storage/copydir.h"
#include "utils/builtins.h"
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 44e9509..d4b19cd 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -66,6 +66,7 @@
#include "rewrite/rewriteDefine.h"
#include "rewrite/rowsecurity.h"
#include "storage/lmgr.h"
+#include "storage/lwlock.h"
#include "storage/smgr.h"
#include "utils/array.h"
#include "utils/builtins.h"
diff --git a/src/include/port/atomics.h b/src/include/port/atomics.h
index bb87945..65cfa3f 100644
--- a/src/include/port/atomics.h
+++ b/src/include/port/atomics.h
@@ -37,6 +37,10 @@
#ifndef ATOMICS_H
#define ATOMICS_H
+#ifdef FRONTEND
+#error "atomics.h may not be included from frontend code"
+#endif
+
#define INSIDE_ATOMICS_H
#include <limits.h>
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h
index 96fe3a6..fb731b0 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -15,7 +15,6 @@
#define LOCK_H_
#include "storage/backendid.h"
-#include "storage/lwlock.h"
#include "storage/shmem.h"
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index cbd6318..f2ff6a0 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -14,6 +14,10 @@
#ifndef LWLOCK_H
#define LWLOCK_H
+#ifdef FRONTEND
+#error "lwlock.h may not be included from frontend code"
+#endif
+
#include "lib/ilist.h"
#include "storage/s_lock.h"
#include "port/atomics.h"
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index 202a672..fcbd9a5 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -18,6 +18,7 @@
#include "lib/ilist.h"
#include "storage/latch.h"
#include "storage/lock.h"
+#include "storage/lwlock.h"
#include "storage/pg_sema.h"
/*
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index 30f28b0..c461fda 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -96,6 +96,10 @@
#ifndef S_LOCK_H
#define S_LOCK_H
+#ifdef FRONTEND
+#error "s_lock.h may not be included from frontend code"
+#endif
+
#ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */
#if defined(__GNUC__) || defined(__INTEL_COMPILER)
--
2.3.0.149.gf3f4077.dirty
Andres Freund <andres@anarazel.de> writes:
One approach is to avoid including lwlock.h/slot.h in frontend
code. That'll require some minor surgery and adding a couple includes,
but it doesn't look that bad.
Patch doing that attached.
This seems kinda messy. Looking at the contents of lock.h, it seems like
getting rid of its dependency on lwlock.h is not really very appropriate,
because there is boatloads of other backend-only stuff in there. Why is
any frontend code including lock.h at all? If there is a valid reason,
should we refactor lock.h into two separate headers, one that is safe to
expose to frontends and one with the rest of the stuff?
Also, I think the reason for the #include is that lock.h has a couple
of macros that reference MainLWLockArray. The fact that you can omit
the #include lwlock.h is therefore only accidental: if we had done those
as static inline functions, this wouldn't work at all. So I think this
solution is not very future-proof either.
As a consequence I think we should actually add a bunch of #ifdef
FRONTEND #error checks in code we definitely do not want to included in
frontend code. The attached patch so far adds a check to atomics.h,
lwlock.h and s_lock.h.
I agree with that idea anyway.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Thu, Aug 6, 2015 at 3:09 AM, Andres Freund <andres@anarazel.de> wrote:
It really doesn't. It's just fallout from indirectly including lwlock.h
which includes an atomic variable. The include path leading to it isIn file included from /home/andres/src/postgresql/src/include/storage/lwlock.h:19:0,
from /home/andres/src/postgresql/src/include/storage/lock.h:18,
from /home/andres/src/postgresql/src/include/access/tuptoaster.h:18,
from /home/andres/src/postgresql/src/bin/pg_resetxlog/pg_resetxlog.c:49:
/home/andres/src/postgresql/src/include/port/atomics.h:41:2: error: #error "THOU SHALL NOT REQUIRE ATOMICS"
#error "THOU SHALL NOT REQUIRE ATOMICS"
Isn't that #include entirely superfluous?
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-06 10:29:39 -0400, Robert Haas wrote:
On Thu, Aug 6, 2015 at 3:09 AM, Andres Freund <andres@anarazel.de> wrote:
It really doesn't. It's just fallout from indirectly including lwlock.h
which includes an atomic variable. The include path leading to it isIn file included from /home/andres/src/postgresql/src/include/storage/lwlock.h:19:0,
from /home/andres/src/postgresql/src/include/storage/lock.h:18,
from /home/andres/src/postgresql/src/include/access/tuptoaster.h:18,
from /home/andres/src/postgresql/src/bin/pg_resetxlog/pg_resetxlog.c:49:
/home/andres/src/postgresql/src/include/port/atomics.h:41:2: error: #error "THOU SHALL NOT REQUIRE ATOMICS"
#error "THOU SHALL NOT REQUIRE ATOMICS"Isn't that #include entirely superfluous?
Which one?
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-06 10:27:52 -0400, Tom Lane wrote:
Andres Freund <andres@anarazel.de> writes:
One approach is to avoid including lwlock.h/slot.h in frontend
code. That'll require some minor surgery and adding a couple includes,
but it doesn't look that bad.Patch doing that attached.
This seems kinda messy. Looking at the contents of lock.h, it seems like
getting rid of its dependency on lwlock.h is not really very appropriate,
because there is boatloads of other backend-only stuff in there. Why is
any frontend code including lock.h at all? If there is a valid reason,
should we refactor lock.h into two separate headers, one that is safe to
expose to frontends and one with the rest of the stuff?
I think the primary reason for lock.h being included pretty widely is to
have the declaration of LOCKMODE. That's pretty widely used in headers
included by clients for various reasons. There's also a bit of fun
around xl_standby_locks.
I can have a go at trying to separate them, but I'm not convinced it's
going to look particularly pretty.
Also, I think the reason for the #include is that lock.h has a couple
of macros that reference MainLWLockArray. The fact that you can omit
the #include lwlock.h is therefore only accidental: if we had done those
as static inline functions, this wouldn't work at all. So I think this
solution is not very future-proof either.
Yea, I saw that and concluded I'm not particularly bothered by it. Most
of the other similar macros are in lwlock.h itself, and if it became a
problem we could just move them alongside.
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Thu, Aug 6, 2015 at 10:31 AM, Andres Freund <andres@anarazel.de> wrote:
On 2015-08-06 10:29:39 -0400, Robert Haas wrote:
On Thu, Aug 6, 2015 at 3:09 AM, Andres Freund <andres@anarazel.de> wrote:
It really doesn't. It's just fallout from indirectly including lwlock.h
which includes an atomic variable. The include path leading to it isIn file included from /home/andres/src/postgresql/src/include/storage/lwlock.h:19:0,
from /home/andres/src/postgresql/src/include/storage/lock.h:18,
from /home/andres/src/postgresql/src/include/access/tuptoaster.h:18,
from /home/andres/src/postgresql/src/bin/pg_resetxlog/pg_resetxlog.c:49:
/home/andres/src/postgresql/src/include/port/atomics.h:41:2: error: #error "THOU SHALL NOT REQUIRE ATOMICS"
#error "THOU SHALL NOT REQUIRE ATOMICS"Isn't that #include entirely superfluous?
Which one?
Never mind, I'm confused.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund wrote:
On 2015-08-06 10:27:52 -0400, Tom Lane wrote:
Andres Freund <andres@anarazel.de> writes:
One approach is to avoid including lwlock.h/slot.h in frontend
code. That'll require some minor surgery and adding a couple includes,
but it doesn't look that bad.Patch doing that attached.
This seems kinda messy. Looking at the contents of lock.h, it seems like
getting rid of its dependency on lwlock.h is not really very appropriate,
because there is boatloads of other backend-only stuff in there. Why is
any frontend code including lock.h at all? If there is a valid reason,
should we refactor lock.h into two separate headers, one that is safe to
expose to frontends and one with the rest of the stuff?I think the primary reason for lock.h being included pretty widely is to
have the declaration of LOCKMODE. That's pretty widely used in headers
included by clients for various reasons. There's also a bit of fun
around xl_standby_locks.
I think it is a good idea to split up LOCKMODE so that most headers do
not need to include lock.h at all; you will need to add an explicit
#include "storage/lock.h" to a lot of C files, but to me that's a good
thing.
See
http://doxygen.postgresql.org/lock_8h.html
Funnily enough, the "included by" graph is so large that my browser
(arguably a bit dated) fails to display it and shows a black rectangle
instead. Chromium shows it, though it's illegible.
--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-06 12:05:24 -0300, Alvaro Herrera wrote:
Andres Freund wrote:
On 2015-08-06 10:27:52 -0400, Tom Lane wrote:
Andres Freund <andres@anarazel.de> writes:
One approach is to avoid including lwlock.h/slot.h in frontend
code. That'll require some minor surgery and adding a couple includes,
but it doesn't look that bad.Patch doing that attached.
This seems kinda messy. Looking at the contents of lock.h, it seems like
getting rid of its dependency on lwlock.h is not really very appropriate,
because there is boatloads of other backend-only stuff in there. Why is
any frontend code including lock.h at all? If there is a valid reason,
should we refactor lock.h into two separate headers, one that is safe to
expose to frontends and one with the rest of the stuff?I think the primary reason for lock.h being included pretty widely is to
have the declaration of LOCKMODE. That's pretty widely used in headers
included by clients for various reasons. There's also a bit of fun
around xl_standby_locks.I think it is a good idea to split up LOCKMODE so that most headers do
not need to include lock.h at all; you will need to add an explicit
#include "storage/lock.h" to a lot of C files, but to me that's a good
thing.
I had to split of three things: LOCKMASK, the individual lock levels and
xl_standby_lock to be able to prohibit lock.h to be included by frontend
code. lockdefs.h works for me, counter proposals?
There weren't any places that needed additional lock.h includes. But
hashfn.c somewhat hilariously missed utils/hsearch.h ;)
Regards,
Andres
Attachments:
0001-Don-t-include-low-level-locking-code-from-frontend-c.patchtext/x-patch; charset=us-asciiDownload
>From bc9dc1910058a3e4638576261f24cb12471e7b15 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Thu, 6 Aug 2015 12:53:56 +0200
Subject: [PATCH] Don't include low level locking code from frontend code.
To avoid that happening again put some checks agains this happening into
atomics.h, lock.h, lwlock.h and s_lock.h.
---
src/backend/utils/hash/hashfn.c | 1 +
src/include/access/genam.h | 2 +-
src/include/access/hash.h | 2 +-
src/include/access/tuptoaster.h | 2 +-
src/include/catalog/objectaddress.h | 2 +-
src/include/port/atomics.h | 4 +++
src/include/storage/lock.h | 43 ++++------------------------
src/include/storage/lockdefs.h | 56 +++++++++++++++++++++++++++++++++++++
src/include/storage/lwlock.h | 4 +++
src/include/storage/procarray.h | 1 +
src/include/storage/s_lock.h | 4 +++
src/include/storage/standby.h | 2 +-
12 files changed, 80 insertions(+), 43 deletions(-)
create mode 100644 src/include/storage/lockdefs.h
diff --git a/src/backend/utils/hash/hashfn.c b/src/backend/utils/hash/hashfn.c
index 260d880..bdd438d 100644
--- a/src/backend/utils/hash/hashfn.c
+++ b/src/backend/utils/hash/hashfn.c
@@ -22,6 +22,7 @@
#include "postgres.h"
#include "access/hash.h"
+#include "utils/hsearch.h"
/*
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index d86590a..d9d05a0 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -17,7 +17,7 @@
#include "access/sdir.h"
#include "access/skey.h"
#include "nodes/tidbitmap.h"
-#include "storage/lock.h"
+#include "storage/lockdefs.h"
#include "utils/relcache.h"
#include "utils/snapshot.h"
diff --git a/src/include/access/hash.h b/src/include/access/hash.h
index 93cc8af..97cb859 100644
--- a/src/include/access/hash.h
+++ b/src/include/access/hash.h
@@ -24,7 +24,7 @@
#include "fmgr.h"
#include "lib/stringinfo.h"
#include "storage/bufmgr.h"
-#include "storage/lock.h"
+#include "storage/lockdefs.h"
#include "utils/relcache.h"
/*
diff --git a/src/include/access/tuptoaster.h b/src/include/access/tuptoaster.h
index 7d18535..77f637e 100644
--- a/src/include/access/tuptoaster.h
+++ b/src/include/access/tuptoaster.h
@@ -14,8 +14,8 @@
#define TUPTOASTER_H
#include "access/htup_details.h"
+#include "storage/lockdefs.h"
#include "utils/relcache.h"
-#include "storage/lock.h"
/*
* This enables de-toasting of index entries. Needed until VACUUM is
diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h
index 37808c0..0fc16ed 100644
--- a/src/include/catalog/objectaddress.h
+++ b/src/include/catalog/objectaddress.h
@@ -14,7 +14,7 @@
#define OBJECTADDRESS_H
#include "nodes/pg_list.h"
-#include "storage/lock.h"
+#include "storage/lockdefs.h"
#include "utils/acl.h"
#include "utils/relcache.h"
diff --git a/src/include/port/atomics.h b/src/include/port/atomics.h
index bb87945..65cfa3f 100644
--- a/src/include/port/atomics.h
+++ b/src/include/port/atomics.h
@@ -37,6 +37,10 @@
#ifndef ATOMICS_H
#define ATOMICS_H
+#ifdef FRONTEND
+#error "atomics.h may not be included from frontend code"
+#endif
+
#define INSIDE_ATOMICS_H
#include <limits.h>
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h
index 96fe3a6..a9cd08c 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -14,6 +14,11 @@
#ifndef LOCK_H_
#define LOCK_H_
+#ifdef FRONTEND
+#error "lock.h may not be included from frontend code"
+#endif
+
+#include "storage/lockdefs.h"
#include "storage/backendid.h"
#include "storage/lwlock.h"
#include "storage/shmem.h"
@@ -77,15 +82,6 @@ typedef struct
((vxid).backendId = (proc).backendId, \
(vxid).localTransactionId = (proc).lxid)
-
-/*
- * LOCKMODE is an integer (1..N) indicating a lock type. LOCKMASK is a bit
- * mask indicating a set of held or requested lock types (the bit 1<<mode
- * corresponds to a particular lock mode).
- */
-typedef int LOCKMASK;
-typedef int LOCKMODE;
-
/* MAX_LOCKMODES cannot be larger than the # of bits in LOCKMASK */
#define MAX_LOCKMODES 10
@@ -134,28 +130,6 @@ typedef uint16 LOCKMETHODID;
#define USER_LOCKMETHOD 2
/*
- * These are the valid values of type LOCKMODE for all the standard lock
- * methods (both DEFAULT and USER).
- */
-
-/* NoLock is not a lock mode, but a flag value meaning "don't get a lock" */
-#define NoLock 0
-
-#define AccessShareLock 1 /* SELECT */
-#define RowShareLock 2 /* SELECT FOR UPDATE/FOR SHARE */
-#define RowExclusiveLock 3 /* INSERT, UPDATE, DELETE */
-#define ShareUpdateExclusiveLock 4 /* VACUUM (non-FULL),ANALYZE, CREATE
- * INDEX CONCURRENTLY */
-#define ShareLock 5 /* CREATE INDEX (WITHOUT CONCURRENTLY) */
-#define ShareRowExclusiveLock 6 /* like EXCLUSIVE MODE, but allows ROW
- * SHARE */
-#define ExclusiveLock 7 /* blocks ROW SHARE/SELECT...FOR
- * UPDATE */
-#define AccessExclusiveLock 8 /* ALTER TABLE, DROP TABLE, VACUUM
- * FULL, and unqualified LOCK TABLE */
-
-
-/*
* LOCKTAG is the key information needed to look up a LOCK item in the
* lock hashtable. A LOCKTAG value uniquely identifies a lockable object.
*
@@ -536,13 +510,6 @@ extern void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode);
extern Size LockShmemSize(void);
extern LockData *GetLockStatusData(void);
-typedef struct xl_standby_lock
-{
- TransactionId xid; /* xid of holder of AccessExclusiveLock */
- Oid dbOid;
- Oid relOid;
-} xl_standby_lock;
-
extern xl_standby_lock *GetRunningTransactionLocks(int *nlocks);
extern const char *GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode);
diff --git a/src/include/storage/lockdefs.h b/src/include/storage/lockdefs.h
new file mode 100644
index 0000000..bfbcdba
--- /dev/null
+++ b/src/include/storage/lockdefs.h
@@ -0,0 +1,56 @@
+/*-------------------------------------------------------------------------
+ *
+ * lockdefs.h
+ * Frontend exposed parts of postgres' low level lock mechanism
+ *
+ * The split between lockdefs.h and lock.h is not very principled. This file
+ * contains definition that have to (indirectly) be available when included by
+ * FRONTEND code.
+ *
+ * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/storage/lockdefs.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef LOCKDEFS_H_
+#define LOCKDEFS_H_
+
+/*
+ * LOCKMODE is an integer (1..N) indicating a lock type. LOCKMASK is a bit
+ * mask indicating a set of held or requested lock types (the bit 1<<mode
+ * corresponds to a particular lock mode).
+ */
+typedef int LOCKMASK;
+typedef int LOCKMODE;
+
+/*
+ * These are the valid values of type LOCKMODE for all the standard lock
+ * methods (both DEFAULT and USER).
+ */
+
+/* NoLock is not a lock mode, but a flag value meaning "don't get a lock" */
+#define NoLock 0
+
+#define AccessShareLock 1 /* SELECT */
+#define RowShareLock 2 /* SELECT FOR UPDATE/FOR SHARE */
+#define RowExclusiveLock 3 /* INSERT, UPDATE, DELETE */
+#define ShareUpdateExclusiveLock 4 /* VACUUM (non-FULL),ANALYZE, CREATE
+ * INDEX CONCURRENTLY */
+#define ShareLock 5 /* CREATE INDEX (WITHOUT CONCURRENTLY) */
+#define ShareRowExclusiveLock 6 /* like EXCLUSIVE MODE, but allows ROW
+ * SHARE */
+#define ExclusiveLock 7 /* blocks ROW SHARE/SELECT...FOR
+ * UPDATE */
+#define AccessExclusiveLock 8 /* ALTER TABLE, DROP TABLE, VACUUM
+ * FULL, and unqualified LOCK TABLE */
+
+typedef struct xl_standby_lock
+{
+ TransactionId xid; /* xid of holder of AccessExclusiveLock */
+ Oid dbOid;
+ Oid relOid;
+} xl_standby_lock;
+
+#endif /* LOCKDEF_H_ */
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index cbd6318..f2ff6a0 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -14,6 +14,10 @@
#ifndef LWLOCK_H
#define LWLOCK_H
+#ifdef FRONTEND
+#error "lwlock.h may not be included from frontend code"
+#endif
+
#include "lib/ilist.h"
#include "storage/s_lock.h"
#include "port/atomics.h"
diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h
index a9b40ed..834f99b 100644
--- a/src/include/storage/procarray.h
+++ b/src/include/storage/procarray.h
@@ -14,6 +14,7 @@
#ifndef PROCARRAY_H
#define PROCARRAY_H
+#include "storage/lock.h"
#include "storage/standby.h"
#include "utils/relcache.h"
#include "utils/snapshot.h"
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index 30f28b0..c461fda 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -96,6 +96,10 @@
#ifndef S_LOCK_H
#define S_LOCK_H
+#ifdef FRONTEND
+#error "s_lock.h may not be included from frontend code"
+#endif
+
#ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */
#if defined(__GNUC__) || defined(__INTEL_COMPILER)
diff --git a/src/include/storage/standby.h b/src/include/storage/standby.h
index 7626c4c..40b329b 100644
--- a/src/include/storage/standby.h
+++ b/src/include/storage/standby.h
@@ -16,7 +16,7 @@
#include "access/xlogreader.h"
#include "lib/stringinfo.h"
-#include "storage/lock.h"
+#include "storage/lockdefs.h"
#include "storage/procsignal.h"
#include "storage/relfilenode.h"
--
2.3.0.149.gf3f4077.dirty
Andres Freund wrote:
I had to split of three things: LOCKMASK, the individual lock levels and
xl_standby_lock to be able to prohibit lock.h to be included by frontend
code. lockdefs.h works for me, counter proposals?There weren't any places that needed additional lock.h includes.
Ah, but that's because you cheated and didn't remove the include from
namespace.h ...
But hashfn.c somewhat hilariously missed utils/hsearch.h ;)
hah.
diff --git a/src/include/storage/lockdefs.h b/src/include/storage/lockdefs.h new file mode 100644 index 0000000..bfbcdba --- /dev/null +++ b/src/include/storage/lockdefs.h @@ -0,0 +1,56 @@ +/*------------------------------------------------------------------------- + * + * lockdefs.h + * Frontend exposed parts of postgres' low level lock mechanism + * + * The split between lockdefs.h and lock.h is not very principled.
No kidding!
--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-06 12:29:15 -0300, Alvaro Herrera wrote:
Andres Freund wrote:
I had to split of three things: LOCKMASK, the individual lock levels and
xl_standby_lock to be able to prohibit lock.h to be included by frontend
code. lockdefs.h works for me, counter proposals?There weren't any places that needed additional lock.h includes.
Ah, but that's because you cheated and didn't remove the include from
namespace.h ...
Well, it's not included from frontend code, so I didn't see the need?
Going through all the backend code and replacing lock.h by lockdefs.h
and some other includes doesn't seem particularly beneficial to me.
FWIW, removing it from namespace.h is relatively easy. It starts to get
a lot more noisy when you want to touch heapam.h.
diff --git a/src/include/storage/lockdefs.h b/src/include/storage/lockdefs.h new file mode 100644 index 0000000..bfbcdba --- /dev/null +++ b/src/include/storage/lockdefs.h @@ -0,0 +1,56 @@ +/*------------------------------------------------------------------------- + * + * lockdefs.h + * Frontend exposed parts of postgres' low level lock mechanism + * + * The split between lockdefs.h and lock.h is not very principled.No kidding!
Do you have a good suggestion about the split? I wanted to expose the
minimal amount necessary, and those were the ones.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund wrote:
On 2015-08-06 12:29:15 -0300, Alvaro Herrera wrote:
Ah, but that's because you cheated and didn't remove the include from
namespace.h ...Well, it's not included from frontend code, so I didn't see the need?
Going through all the backend code and replacing lock.h by lockdefs.h
and some other includes doesn't seem particularly beneficial to me.FWIW, removing it from namespace.h is relatively easy. It starts to get
a lot more noisy when you want to touch heapam.h.
Ah, heapam.h is the granddaddy of all header messes, isn't it. (Actually
it's execnodes.h or something like that.)
diff --git a/src/include/storage/lockdefs.h b/src/include/storage/lockdefs.h new file mode 100644 index 0000000..bfbcdba --- /dev/null +++ b/src/include/storage/lockdefs.h @@ -0,0 +1,56 @@ +/*------------------------------------------------------------------------- + * + * lockdefs.h + * Frontend exposed parts of postgres' low level lock mechanism + * + * The split between lockdefs.h and lock.h is not very principled.No kidding!
Do you have a good suggestion about the split? I wanted to expose the
minimal amount necessary, and those were the ones.
Nope, nothing useful, sorry.
--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Thu, Aug 06, 2015 at 05:34:50PM +0200, Andres Freund wrote:
On 2015-08-06 12:29:15 -0300, Alvaro Herrera wrote:
Andres Freund wrote:
@@ -0,0 +1,56 @@ +/*------------------------------------------------------------------------- + * + * lockdefs.h + * Frontend exposed parts of postgres' low level lock mechanism + * + * The split between lockdefs.h and lock.h is not very principled.No kidding!
Do you have a good suggestion about the split? I wanted to expose the
minimal amount necessary, and those were the ones.
lock.h includes lwlock.h only for the benefit of the three LockHashPartition*
macros. Those macros are pieces of the lock.c implementation that cross into
proc.c, not pieces of the lock.c public API. I suggest instead making a
lock_internals.h for those macros and for anything else private to the various
files of the lock implementation. For example, the PROCLOCK struct and the
functions that take arguments of that type would fit in lock_internals.h.
With that, indirect frontend lock.h inclusion will work fine.
Thanks,
nm
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-06 23:23:43 -0400, Noah Misch wrote:
On Thu, Aug 06, 2015 at 05:34:50PM +0200, Andres Freund wrote:
On 2015-08-06 12:29:15 -0300, Alvaro Herrera wrote:
Andres Freund wrote:
@@ -0,0 +1,56 @@ +/*------------------------------------------------------------------------- + * + * lockdefs.h + * Frontend exposed parts of postgres' low level lock mechanism + * + * The split between lockdefs.h and lock.h is not very principled.No kidding!
Do you have a good suggestion about the split? I wanted to expose the
minimal amount necessary, and those were the ones.lock.h includes lwlock.h only for the benefit of the three LockHashPartition*
macros. Those macros are pieces of the lock.c implementation that cross into
proc.c, not pieces of the lock.c public API.
I argued that way as well upthread. But I do think that Tom has a good
point when he argues that frontend code really has no business including
lock.h in total. The only reason we need it is because a few headers we
need to include have LOCKMODE parameters and/or contain macros that
refer to lock levels. So I do think that having a version that doesn't
expose any unnecessary details is a good idea.
With that, indirect frontend lock.h inclusion will work fine.
But there seems little reason trying to support doing so. It's not very
hard to imagine that lock.c and by extension lock.h get more complicated
in the future as it's already a scalability bottleneck. that very well
might require including atomics, spinlocks and the like in lock.h.
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-05 21:39:26 -0400, Noah Misch wrote:
On Wed, Aug 05, 2015 at 10:32:48AM -0400, Tom Lane wrote:
Andres Freund <andres@anarazel.de> writes:
Wasn't the point that 32 bit AIX as a whole hasn't been supported for a
couple years now? My willingness to expend effort for that is rather
limited.Well, there's one in the buildfarm. We don't generally turn off
buildfarm critters just because the underlying OS is out of support
(the population would be quite a bit lower if we did).For the record, mandrill's OS and compiler are both in support and not so old
(June 2012 compiler, February 2013 OS). The last 32-bit AIX *kernel* did exit
support in 2012, but 32-bit executables remain the norm.
Ugh, sorry, I misunderstood you then in the earlier thread.
Unless you have a better idea I'll now move the detection of that case
to aix.h.
I rather liked being able to emit a warning about disabling inlines
*once* during configuration, but it's also probably not worth a lot of
effort given how few users that platform has.
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund wrote:
lock.h includes lwlock.h only for the benefit of the three LockHashPartition*
macros. Those macros are pieces of the lock.c implementation that cross into
proc.c, not pieces of the lock.c public API.I argued that way as well upthread. But I do think that Tom has a good
point when he argues that frontend code really has no business including
lock.h in total. The only reason we need it is because a few headers we
need to include have LOCKMODE parameters and/or contain macros that
refer to lock levels. So I do think that having a version that doesn't
expose any unnecessary details is a good idea.With that, indirect frontend lock.h inclusion will work fine.
But there seems little reason trying to support doing so. It's not very
hard to imagine that lock.c and by extension lock.h get more complicated
in the future as it's already a scalability bottleneck. that very well
might require including atomics, spinlocks and the like in lock.h.
I don't disagree with any of your points, but nevertheless I think the
split suggested by Noah is a good one (it's more principled than the one
you suggest, at any rate) and perhaps it would be a good compromise to
do both things in a fell swoop.
--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Fri, Aug 07, 2015 at 03:20:00PM +0200, Andres Freund wrote:
Unless you have a better idea I'll now move the detection of that case
to aix.h.
Nope, that seemed right to me.
I rather liked being able to emit a warning about disabling inlines
*once* during configuration, but it's also probably not worth a lot of
effort given how few users that platform has.
If we were precisely detecting buggy compilers, the warning would have more
value; users could take it as a signal to consider upgrading or downgrading.
Given the test's present coarseness, I don't see much value.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Thu, Aug 6, 2015 at 11:34 AM, Andres Freund <andres@anarazel.de> wrote:
On 2015-08-06 12:29:15 -0300, Alvaro Herrera wrote:
Andres Freund wrote:
I had to split of three things: LOCKMASK, the individual lock levels and
xl_standby_lock to be able to prohibit lock.h to be included by frontend
code. lockdefs.h works for me, counter proposals?There weren't any places that needed additional lock.h includes.
Ah, but that's because you cheated and didn't remove the include from
namespace.h ...Well, it's not included from frontend code, so I didn't see the need?
Going through all the backend code and replacing lock.h by lockdefs.h
and some other includes doesn't seem particularly beneficial to me.
It may not be included from any IN CORE frontend code, but that is not
the same thing as saying it's not included from any frontend code at
all. For example, EDB has code that includes namespace.h in frontend
code. That compiled before this commit; now it doesn't.
It turns out the fix is pretty simple: the code in question is
including namespace.h, but it doesn't need to. So I can just remove
the include in this instance. But I don't think it's always going to
be that simple. A significant reduction in the number of headers that
can be compiled from frontend code WILL inconvenience extension
authors.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-07 12:30:04 -0400, Robert Haas wrote:
It may not be included from any IN CORE frontend code, but that is not
the same thing as saying it's not included from any frontend code at
all. For example, EDB has code that includes namespace.h in frontend
code. That compiled before this commit; now it doesn't.
Nothing in namespace.h seems to be of any possible use for frontend
code. If there were possible use-cases I'd be inclined to agree, but you
obvoiusly can't use any of the functions, the structs and the guc make
no sense either. So I really don't why we should cater for that?
I think the likelihood of actually breaking correct working extension
code that uses namespace.h that'd be broken if we removed lock.h from
namespace.h is an order of magnitude bigger than the possible impact on
frontend code.
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-07 19:11:52 +0200, Andres Freund wrote:
I think the likelihood of actually breaking correct working extension
code that uses namespace.h that'd be broken if we removed lock.h from
namespace.h is an order of magnitude bigger than the possible impact on
frontend code.
Same with dropping lwlock.h from lock.h. I tried both and the former
required more than 20 added headers in backend code, and the latter
about 5. I'm pretty sure the same would be true external extensions.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Fri, Aug 7, 2015 at 1:11 PM, Andres Freund <andres@anarazel.de> wrote:
On 2015-08-07 12:30:04 -0400, Robert Haas wrote:
It may not be included from any IN CORE frontend code, but that is not
the same thing as saying it's not included from any frontend code at
all. For example, EDB has code that includes namespace.h in frontend
code. That compiled before this commit; now it doesn't.Nothing in namespace.h seems to be of any possible use for frontend
code. If there were possible use-cases I'd be inclined to agree, but you
obvoiusly can't use any of the functions, the structs and the guc make
no sense either. So I really don't why we should cater for that?I think the likelihood of actually breaking correct working extension
code that uses namespace.h that'd be broken if we removed lock.h from
namespace.h is an order of magnitude bigger than the possible impact on
frontend code.
Well, I just work here, but it seems silly to me to reorgnize the
headers so that you can include fewer definitions where necessary, but
then not revise the existing headers to use the slimmed-down versions
where possible. Yeah, somebody might have to adjust their #includes
and that is annoying, but I don't think the cost of your new #error
directives is going to be zero.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-07 14:15:58 -0400, Robert Haas wrote:
On Fri, Aug 7, 2015 at 1:11 PM, Andres Freund <andres@anarazel.de> wrote:
On 2015-08-07 12:30:04 -0400, Robert Haas wrote:
It may not be included from any IN CORE frontend code, but that is not
the same thing as saying it's not included from any frontend code at
all. For example, EDB has code that includes namespace.h in frontend
code. That compiled before this commit; now it doesn't.Nothing in namespace.h seems to be of any possible use for frontend
code. If there were possible use-cases I'd be inclined to agree, but you
obvoiusly can't use any of the functions, the structs and the guc make
no sense either. So I really don't why we should cater for that?I think the likelihood of actually breaking correct working extension
code that uses namespace.h that'd be broken if we removed lock.h from
namespace.h is an order of magnitude bigger than the possible impact on
frontend code.Well, I just work here, but it seems silly to me to reorgnize the
headers so that you can include fewer definitions where necessary, but
then not revise the existing headers to use the slimmed-down versions
where possible. Yeah, somebody might have to adjust their #includes
and that is annoying, but I don't think the cost of your new #error
directives is going to be zero.
So first your argument was that it broke stuff and now you want to break
more?
I am not really against removing removing lock.h from a few more places,
but normally you were the one arguing against breaking working code by
reorganizing headers when there's no really clear win. Removing lock.h
from namespace.h and removing lwlock.h from lock.h will have a
noticeably higher cost than what I committed and in contrast to the
benefit of separating frontend code from backend implementation details
(which caused linker errors) the only benefit will be a bit less code
included.
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Fri, Aug 7, 2015 at 2:27 PM, Andres Freund <andres@anarazel.de> wrote:
On 2015-08-07 14:15:58 -0400, Robert Haas wrote:
On Fri, Aug 7, 2015 at 1:11 PM, Andres Freund <andres@anarazel.de> wrote:
On 2015-08-07 12:30:04 -0400, Robert Haas wrote:
It may not be included from any IN CORE frontend code, but that is not
the same thing as saying it's not included from any frontend code at
all. For example, EDB has code that includes namespace.h in frontend
code. That compiled before this commit; now it doesn't.Nothing in namespace.h seems to be of any possible use for frontend
code. If there were possible use-cases I'd be inclined to agree, but you
obvoiusly can't use any of the functions, the structs and the guc make
no sense either. So I really don't why we should cater for that?I think the likelihood of actually breaking correct working extension
code that uses namespace.h that'd be broken if we removed lock.h from
namespace.h is an order of magnitude bigger than the possible impact on
frontend code.Well, I just work here, but it seems silly to me to reorgnize the
headers so that you can include fewer definitions where necessary, but
then not revise the existing headers to use the slimmed-down versions
where possible. Yeah, somebody might have to adjust their #includes
and that is annoying, but I don't think the cost of your new #error
directives is going to be zero.So first your argument was that it broke stuff and now you want to break
more?I am not really against removing removing lock.h from a few more places,
but normally you were the one arguing against breaking working code by
reorganizing headers when there's no really clear win. Removing lock.h
from namespace.h and removing lwlock.h from lock.h will have a
noticeably higher cost than what I committed and in contrast to the
benefit of separating frontend code from backend implementation details
(which caused linker errors) the only benefit will be a bit less code
included.
Well, we can wait and see if we get any more complaints before doing
anything, if you like. We've got a year before any of this is going
to be released, so there's no rush. My point, which I think is valid,
is that if the set of #includes you need to compile your stuff
changes, that's easy to fix. If one of the #includes you need to
compile your stuff starts doing #error, you're hosed.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Robert Haas <robertmhaas@gmail.com> writes:
Well, I just work here, but it seems silly to me to reorgnize the
headers so that you can include fewer definitions where necessary, but
then not revise the existing headers to use the slimmed-down versions
where possible. Yeah, somebody might have to adjust their #includes
and that is annoying, but I don't think the cost of your new #error
directives is going to be zero.
I'm a bit concerned about that too; what it means is that any addition
of new #includes in backend header files carries a nontrivial risk of
breaking frontend code that used to be fine (at least on most platforms).
As an example, the proximate cause of the pademelon breakage was that
pg_resetxlog needs to #include tuptoaster.h to get TOAST_MAX_CHUNK_SIZE.
That was perfectly safe up till commit 2ef085d0e6960f50, when somebody
semi-randomly decided that it'd be a good idea to declare a function
taking a LOCKMODE argument in that header.
Eventually I think we're going to have to spend some effort on making a
clearer separation between "front end safe" and "not front end safe"
header files. Until we do that, though, adding these #error directives
may just do more harm than good. We don't know which backend headers
are being used by third-party code, but we can be 100% sure it's more
than what's used by the frontend code in the core distribution.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-07 14:32:35 -0400, Tom Lane wrote:
Robert Haas <robertmhaas@gmail.com> writes:
Well, I just work here, but it seems silly to me to reorgnize the
headers so that you can include fewer definitions where necessary, but
then not revise the existing headers to use the slimmed-down versions
where possible. Yeah, somebody might have to adjust their #includes
and that is annoying, but I don't think the cost of your new #error
directives is going to be zero.I'm a bit concerned about that too; what it means is that any addition
of new #includes in backend header files carries a nontrivial risk of
breaking frontend code that used to be fine (at least on most platforms).
As an example, the proximate cause of the pademelon breakage was that
pg_resetxlog needs to #include tuptoaster.h to get TOAST_MAX_CHUNK_SIZE.
That was perfectly safe up till commit 2ef085d0e6960f50, when somebody
semi-randomly decided that it'd be a good idea to declare a function
taking a LOCKMODE argument in that header.Eventually I think we're going to have to spend some effort on making a
clearer separation between "front end safe" and "not front end safe"
header files. Until we do that, though, adding these #error directives
may just do more harm than good. We don't know which backend headers
are being used by third-party code, but we can be 100% sure it's more
than what's used by the frontend code in the core distribution.
Right now the #errors are in only in places that'd also break without
them, but only on the old platforms without inline support and in a more
subtle way.
I'm ok with getting lock.h from the list of headers where that's the
case, done by removing lwlock.h from it, which I proposed that
upthread. But then you objected to that approach.
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@anarazel.de> writes:
On 2015-08-07 14:32:35 -0400, Tom Lane wrote:
Eventually I think we're going to have to spend some effort on making a
clearer separation between "front end safe" and "not front end safe"
header files. Until we do that, though, adding these #error directives
may just do more harm than good. We don't know which backend headers
are being used by third-party code, but we can be 100% sure it's more
than what's used by the frontend code in the core distribution.
Right now the #errors are in only in places that'd also break without
them, but only on the old platforms without inline support and in a more
subtle way.
Indeed, but the buildfarm results say that the set of such platforms is
nearly empty. It's very likely that a lot of third-party authors won't
ever care if their code doesn't build on such platforms; certainly not
nearly as much as they'll care if their code doesn't build *at all*,
and they have no recourse except to modify the PG headers because they
need some symbol that happens to be defined in a header that also has
some lock-related junk.
My point is simply that adding those #errors represents a large bet that
the separation between frontend and backend headers is clean enough.
I really doubt that it is, and I don't see anyone volunteering to put
adequate time into fixing that right now. I'm afraid we'll put in
ugly, hurried, piecemeal hacks in response to complaints.
I'm ok with getting lock.h from the list of headers where that's the
case, done by removing lwlock.h from it, which I proposed that
upthread. But then you objected to that approach.
Well, we're still discussing what's the best compromise.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-07 14:48:43 -0400, Tom Lane wrote:
Indeed, but the buildfarm results say that the set of such platforms is
nearly empty. It's very likely that a lot of third-party authors won't
ever care if their code doesn't build on such platforms; certainly not
nearly as much as they'll care if their code doesn't build *at all*,
and they have no recourse except to modify the PG headers because they
need some symbol that happens to be defined in a header that also has
some lock-related junk.
I'm all for de-supporting platforms without working inlining support,
but if we do so, we should do it explicitly. Imo that's what it comes
down to.
It's imo more or less a happy optimization accident that apparently all
inlining supporting compilers never emit references from the contents of
static inline functions that aren't referenced.
There is one instance of code that tried to work around that:
#ifndef FRONTEND
#ifndef PG_USE_INLINE
extern MemoryContext MemoryContextSwitchTo(MemoryContext context);
#endif /* !PG_USE_INLINE */
#if defined(PG_USE_INLINE) || defined(MCXT_INCLUDE_DEFINITIONS)
STATIC_IF_INLINE MemoryContext
MemoryContextSwitchTo(MemoryContext context)
{
MemoryContext old = CurrentMemoryContext;
CurrentMemoryContext = context;
return old;
}
#endif /* PG_USE_INLINE || MCXT_INCLUDE_DEFINITIONS */
#endif /* FRONTEND */
You re-added the #ifndef FRONTEND there in a9baeb361d635 referencing a
buildfarm failure. It seems to originally have been added in
7507b193bc54 referencing buildfarm member warthog which unfortunately
doesn't exist anymore...
My point is simply that adding those #errors represents a large bet that
the separation between frontend and backend headers is clean enough.
I really doubt that it is, and I don't see anyone volunteering to put
adequate time into fixing that right now.
I agree that there's a lot of work needed to make that separation
cleaner. I'm not so sure these files are relevantly often needed in
frontend cdoe.
I'm afraid we'll put in ugly, hurried, piecemeal hacks in response to
complaints.
I think we should leave them in for now. It's the beginning of the cycle
and imo the removal of lock.h from the headers where it was referenced
was a good step. We might find some more easy cases - the removal of
lock.h from tuptoaster.h and other headers included by frontend code imo
is a good thing. If it proves to bothersome we can still take it out.
Andres
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund wrote:
You re-added the #ifndef FRONTEND there in a9baeb361d635 referencing a
buildfarm failure. It seems to originally have been added in
7507b193bc54 referencing buildfarm member warthog which unfortunately
doesn't exist anymore...
FWIW we make a point of not reusing buildfarm member names, so that this
kind of history is not completely obliterated. You can still see
warthog's history here:
http://buildfarm.postgresql.org/cgi-bin/show_history.pl?nm=warthog&br=HEAD
--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Fri, Aug 07, 2015 at 03:18:06PM +0200, Andres Freund wrote:
On 2015-08-06 23:23:43 -0400, Noah Misch wrote:
On Thu, Aug 06, 2015 at 05:34:50PM +0200, Andres Freund wrote:
On 2015-08-06 12:29:15 -0300, Alvaro Herrera wrote:
Andres Freund wrote:
@@ -0,0 +1,56 @@ +/*------------------------------------------------------------------------- + * + * lockdefs.h + * Frontend exposed parts of postgres' low level lock mechanism + * + * The split between lockdefs.h and lock.h is not very principled.No kidding!
Do you have a good suggestion about the split? I wanted to expose the
minimal amount necessary, and those were the ones.lock.h includes lwlock.h only for the benefit of the three LockHashPartition*
macros. Those macros are pieces of the lock.c implementation that cross into
proc.c, not pieces of the lock.c public API.I argued that way as well upthread. But I do think that Tom has a good
point when he argues that frontend code really has no business including
lock.h in total. The only reason we need it is because a few headers we
need to include have LOCKMODE parameters and/or contain macros that
refer to lock levels. So I do think that having a version that doesn't
expose any unnecessary details is a good idea.
I agree that lock.h offers little to frontend code. Headers that the
lockdefs.h patch made usable in the frontend, particularly genam.h and hash.h,
are no better. The lock.h/lockdefs.h unprincipled split would do more harm
than letting frontends continue to pull in lock.h. If we're going to do
something unprincipled, let's make it small, perhaps this:
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -17,3 +17,5 @@
#include "storage/backendid.h"
+#ifndef FRONTEND
#include "storage/lwlock.h"
+#endif
#include "storage/shmem.h"
On another note, I'm perplexed by the high speed commits from this thread.
Commit de6fd1c landed just 191 minutes after you posted the first version of
its patch. Now lockdefs.h is committed, right in the middle of discussing it.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-07 20:16:20 -0400, Noah Misch wrote:
I agree that lock.h offers little to frontend code. Headers that the
lockdefs.h patch made usable in the frontend, particularly genam.h and hash.h,
are no better.
It's not that simple. Those two, and tuptoaster.h, are actually somewhat
validly included by frontend code via the rmgr descriptor routines.
The lock.h/lockdefs.h unprincipled split would do more harm
than letting frontends continue to pull in lock.h.
Why? Consider what happens when lock.h/c gets more complicated and
e.g. grows some atomics. None of the frontend code should see that, and
it's not much effort to keep it that way. Allowing client code to see
LOCKMODE isn't something that's going to cause any harm.
On another note, I'm perplexed by the high speed commits from this thread.
Commit de6fd1c landed just 191 minutes after you posted the first version of
its patch. Now lockdefs.h is committed, right in the middle of discussing it.
Hm. We'd essentially decided what we're going to do about the inline
stuff weeks ago, so I don't feel particularly bad pushing it quickly. A
lot of platform dependent stuff like this is going to have some
iterations to deal with compilers you don't have access to. The only
reason I committed the lockdefs.h split relatively quickly is that I
wanted to get the buildfarm green to see wether there are other problems
hiding behind the linker error. Which does, so far, not appear to be the
case.
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@anarazel.de> writes:
On 2015-08-07 20:16:20 -0400, Noah Misch wrote:
On another note, I'm perplexed by the high speed commits from this thread.
Commit de6fd1c landed just 191 minutes after you posted the first version of
its patch. Now lockdefs.h is committed, right in the middle of discussing it.
Hm. We'd essentially decided what we're going to do about the inline
stuff weeks ago, so I don't feel particularly bad pushing it quickly. A
lot of platform dependent stuff like this is going to have some
iterations to deal with compilers you don't have access to. The only
reason I committed the lockdefs.h split relatively quickly is that I
wanted to get the buildfarm green to see wether there are other problems
hiding behind the linker error. Which does, so far, not appear to be the
case.
FWIW, I agree with that: leaving buildfarm members red for any sustained
amount of time is a bad practice. Code cleanliness is something we can
argue about at leisure, but if you have critters that aren't building
then you don't know what might be hiding behind that. We've had bad
experiences in the past with leaving that sort of thing unfixed.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Sat, Aug 08, 2015 at 02:30:47AM +0200, Andres Freund wrote:
On 2015-08-07 20:16:20 -0400, Noah Misch wrote:
I agree that lock.h offers little to frontend code. Headers that the
lockdefs.h patch made usable in the frontend, particularly genam.h and hash.h,
are no better.It's not that simple. Those two, and tuptoaster.h, are actually somewhat
validly included by frontend code via the rmgr descriptor routines.
genam.h is a dependency of the non-frontend-relevant content of some
frontend-relevant headers, _exactly_ as lock.h has been. I count zero things
in genam.h that a frontend program could harness. The frontend includes
hash.h for two hashdesc.c prototypes, less than the material you moved out of
lock.h for frontend benefit. Yes, it is that simple.
The lock.h/lockdefs.h unprincipled split would do more harm
than letting frontends continue to pull in lock.h.Why?
Your header comment for lockdefs.h sums up the harm nicely. Additionally, the
term "defs" does nothing to explain the split. "lock2.h" would be no less
evocative.
Consider what happens when lock.h/c gets more complicated and
e.g. grows some atomics. None of the frontend code should see that, and
it's not much effort to keep it that way. Allowing client code to see
LOCKMODE isn't something that's going to cause any harm.
Readying the headers for that day brings some value, but you added a worse
mess to achieve it. The overall achievement has negative value.
nm
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-05 15:46:36 +0200, Andres Freund wrote:
On 2015-08-05 15:08:29 +0200, Andres Freund wrote:
We might later want to change some of the harder to maintain macros to
inline functions, but that seems better done separately.Here's a conversion for fastgetattr() and heap_getattr(). Not only is
the resulting code significantly more readable, but the conversion also
shrinks the code size:$ ls -l src/backend/postgres_stock src/backend/postgres
-rwxr-xr-x 1 andres andres 37054832 Aug 5 15:18 src/backend/postgres_stock
-rwxr-xr-x 1 andres andres 37209288 Aug 5 15:23 src/backend/postgres$ size src/backend/postgres_stock src/backend/postgres
text data bss dec hex filename
7026843 49982 298584 7375409 708a31 src/backend/postgres_stock
7023851 49982 298584 7372417 707e81 src/backend/postgresstock is the binary compiled without the conversion.
A lot of the size difference is debugging information (which now needs
less duplicated information on each callsite), but you can see that the
text section (the actual executable code) shrank by 3k.stripping the binary shows exactly that:
-rwxr-xr-x 1 andres andres 7076760 Aug 5 15:44 src/backend/postgres_s
-rwxr-xr-x 1 andres andres 7079512 Aug 5 15:45 src/backend/postgres_stock_sTo be sure this doesn't cause problems I ran a readonly pgbench. There's
a very slight, but reproducible, performance benefit. I don't think
that's a reason for the change, I just wanted to make sure there's no
regressions.
Slightly updated version attached. The only changes are updates to some
comments referencing the 'fastgetattr macro' and the like. Oh, and an
additional newline.
In my opinion this drastically increases readability and thus should be
applied. Will do so sometime tomorrow unless there's protest.
Btw, I found that many changes are much more readable when changing
git's config to use histogramm diffs (git config --global diff.algorithm
histogram or --histogram).
Regards,
Andres
Attachments:
0001-Convert-fastgetattr-and-heap_getattr-into-inline-fun.patchtext/x-patch; charset=us-asciiDownload
>From db76501e9c987c9a0b847ea8a2256a1ec9150b37 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Tue, 11 Aug 2015 13:02:45 +0200
Subject: [PATCH] Convert fastgetattr() and heap_getattr() into inline
functions.
The current macro is very hard to read. Now that we can unconditionally
use inline functions there's no reason to keep them that way.
In my gcc 5 based environment this shaves of nearly 200k of the final
binary size. A lot of that is debugging information, but the
.text (i.e. code) section alone shrinks by 3k.
Discussion: 20150805134636.GF12598@awork2.anarazel.de
---
src/backend/access/common/heaptuple.c | 6 +-
src/backend/access/heap/heapam.c | 46 ----------
src/include/access/htup_details.h | 160 ++++++++++++++++------------------
3 files changed, 78 insertions(+), 134 deletions(-)
diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c
index 045e0a7..017c551 100644
--- a/src/backend/access/common/heaptuple.c
+++ b/src/backend/access/common/heaptuple.c
@@ -328,8 +328,8 @@ heap_attisnull(HeapTuple tup, int attnum)
/* ----------------
* nocachegetattr
*
- * This only gets called from fastgetattr() macro, in cases where
- * we can't use a cacheoffset and the value is not null.
+ * This only gets called from fastgetattr(), in cases where we can't use
+ * a cacheoffset and the value is not null.
*
* This caches attribute offsets in the attribute descriptor.
*
@@ -544,7 +544,7 @@ nocachegetattr(HeapTuple tuple,
*
* Fetch the value of a system attribute for a tuple.
*
- * This is a support routine for the heap_getattr macro. The macro
+ * This is a support routine for the heap_getattr. The inline function
* has already determined that the attnum refers to a system attribute.
* ----------------
*/
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 3701d8e..ff93b3c 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -983,52 +983,6 @@ heapgettup_pagemode(HeapScanDesc scan,
}
-#if defined(DISABLE_COMPLEX_MACRO)
-/*
- * This is formatted so oddly so that the correspondence to the macro
- * definition in access/htup_details.h is maintained.
- */
-Datum
-fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
- bool *isnull)
-{
- return (
- (attnum) > 0 ?
- (
- (*(isnull) = false),
- HeapTupleNoNulls(tup) ?
- (
- (tupleDesc)->attrs[(attnum) - 1]->attcacheoff >= 0 ?
- (
- fetchatt((tupleDesc)->attrs[(attnum) - 1],
- (char *) (tup)->t_data + (tup)->t_data->t_hoff +
- (tupleDesc)->attrs[(attnum) - 1]->attcacheoff)
- )
- :
- nocachegetattr((tup), (attnum), (tupleDesc))
- )
- :
- (
- att_isnull((attnum) - 1, (tup)->t_data->t_bits) ?
- (
- (*(isnull) = true),
- (Datum) NULL
- )
- :
- (
- nocachegetattr((tup), (attnum), (tupleDesc))
- )
- )
- )
- :
- (
- (Datum) NULL
- )
- );
-}
-#endif /* defined(DISABLE_COMPLEX_MACRO) */
-
-
/* ----------------------------------------------------------------
* heap access method interface
* ----------------------------------------------------------------
diff --git a/src/include/access/htup_details.h b/src/include/access/htup_details.h
index 8dd530bd..2f20b07 100644
--- a/src/include/access/htup_details.h
+++ b/src/include/access/htup_details.h
@@ -673,91 +673,6 @@ struct MinimalTupleData
#define HeapTupleSetOid(tuple, oid) \
HeapTupleHeaderSetOid((tuple)->t_data, (oid))
-
-/* ----------------
- * fastgetattr
- *
- * Fetch a user attribute's value as a Datum (might be either a
- * value, or a pointer into the data area of the tuple).
- *
- * This must not be used when a system attribute might be requested.
- * Furthermore, the passed attnum MUST be valid. Use heap_getattr()
- * instead, if in doubt.
- *
- * This gets called many times, so we macro the cacheable and NULL
- * lookups, and call nocachegetattr() for the rest.
- * ----------------
- */
-
-#if !defined(DISABLE_COMPLEX_MACRO)
-
-#define fastgetattr(tup, attnum, tupleDesc, isnull) \
-( \
- AssertMacro((attnum) > 0), \
- (*(isnull) = false), \
- HeapTupleNoNulls(tup) ? \
- ( \
- (tupleDesc)->attrs[(attnum)-1]->attcacheoff >= 0 ? \
- ( \
- fetchatt((tupleDesc)->attrs[(attnum)-1], \
- (char *) (tup)->t_data + (tup)->t_data->t_hoff + \
- (tupleDesc)->attrs[(attnum)-1]->attcacheoff) \
- ) \
- : \
- nocachegetattr((tup), (attnum), (tupleDesc)) \
- ) \
- : \
- ( \
- att_isnull((attnum)-1, (tup)->t_data->t_bits) ? \
- ( \
- (*(isnull) = true), \
- (Datum)NULL \
- ) \
- : \
- ( \
- nocachegetattr((tup), (attnum), (tupleDesc)) \
- ) \
- ) \
-)
-#else /* defined(DISABLE_COMPLEX_MACRO) */
-
-extern Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
- bool *isnull);
-#endif /* defined(DISABLE_COMPLEX_MACRO) */
-
-
-/* ----------------
- * heap_getattr
- *
- * Extract an attribute of a heap tuple and return it as a Datum.
- * This works for either system or user attributes. The given attnum
- * is properly range-checked.
- *
- * If the field in question has a NULL value, we return a zero Datum
- * and set *isnull == true. Otherwise, we set *isnull == false.
- *
- * <tup> is the pointer to the heap tuple. <attnum> is the attribute
- * number of the column (field) caller wants. <tupleDesc> is a
- * pointer to the structure describing the row and all its fields.
- * ----------------
- */
-#define heap_getattr(tup, attnum, tupleDesc, isnull) \
- ( \
- ((attnum) > 0) ? \
- ( \
- ((attnum) > (int) HeapTupleHeaderGetNatts((tup)->t_data)) ? \
- ( \
- (*(isnull) = true), \
- (Datum)NULL \
- ) \
- : \
- fastgetattr((tup), (attnum), (tupleDesc), (isnull)) \
- ) \
- : \
- heap_getsysattr((tup), (attnum), (tupleDesc), (isnull)) \
- )
-
-
/* prototypes for functions in common/heaptuple.c */
extern Size heap_compute_data_size(TupleDesc tupleDesc,
Datum *values, bool *isnull);
@@ -790,4 +705,79 @@ extern MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup);
extern HeapTuple heap_tuple_from_minimal_tuple(MinimalTuple mtup);
extern MinimalTuple minimal_tuple_from_heap_tuple(HeapTuple htup);
+
+/* ----------------
+ * fastgetattr
+ *
+ * Fetch a user attribute's value as a Datum (might be either a
+ * value, or a pointer into the data area of the tuple).
+ *
+ * This must not be used when a system attribute might be requested.
+ * Furthermore, the passed attnum MUST be valid. Use heap_getattr()
+ * instead, if in doubt.
+ *
+ * This gets called many times, so we inline the cacheable and NULL
+ * lookups, and call nocachegetattr() for the rest.
+ * ----------------
+ */
+static inline Datum
+fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
+ bool *isnull)
+{
+ AssertArg(attnum > 0);
+
+ *isnull = false;
+
+ if (HeapTupleNoNulls(tup))
+ {
+ Form_pg_attribute attr = tupleDesc->attrs[attnum - 1];
+
+ if (attr->attcacheoff >= 0)
+ {
+ return fetchatt(attr,
+ (char *) tup->t_data +
+ tup->t_data->t_hoff +
+ attr->attcacheoff);
+ }
+ /* fall through to nocachegetattr */
+ }
+ else if (att_isnull(attnum - 1, tup->t_data->t_bits))
+ {
+ *isnull = true;
+ return (Datum) NULL;
+ }
+
+ return nocachegetattr(tup, attnum, tupleDesc);
+}
+
+/* ----------------
+ * heap_getattr
+ *
+ * Extract an attribute of a heap tuple and return it as a Datum.
+ * This works for either system or user attributes. The given attnum
+ * is properly range-checked.
+ *
+ * If the field in question has a NULL value, we return a zero Datum
+ * and set *isnull == true. Otherwise, we set *isnull == false.
+ * ----------------
+ */
+static inline Datum
+heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
+ bool *isnull)
+{
+ if (attnum > 0)
+ {
+ if (attnum > HeapTupleHeaderGetNatts((tup)->t_data))
+ {
+ *isnull = true;
+ return (Datum) NULL;
+ }
+ else
+ return fastgetattr(tup, attnum, tupleDesc, isnull);
+ }
+
+ return heap_getsysattr(tup, attnum, tupleDesc, isnull);
+}
+
+
#endif /* HTUP_DETAILS_H */
--
2.3.0.149.gf3f4077.dirty
On Tue, Aug 11, 2015 at 01:04:48PM +0200, Andres Freund wrote:
On 2015-08-05 15:46:36 +0200, Andres Freund wrote:
On 2015-08-05 15:08:29 +0200, Andres Freund wrote:
We might later want to change some of the harder to maintain macros to
inline functions, but that seems better done separately.Here's a conversion for fastgetattr() and heap_getattr()
Slightly updated version attached.
In my opinion this drastically increases readability and thus should be
applied. Will do so sometime tomorrow unless there's protest.
-1 to introducing more inline functions before committable code replaces what
you've already pushed for this thread.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-11 22:34:40 -0400, Noah Misch wrote:
On Tue, Aug 11, 2015 at 01:04:48PM +0200, Andres Freund wrote:
On 2015-08-05 15:46:36 +0200, Andres Freund wrote:
On 2015-08-05 15:08:29 +0200, Andres Freund wrote:
We might later want to change some of the harder to maintain macros to
inline functions, but that seems better done separately.Here's a conversion for fastgetattr() and heap_getattr()
Slightly updated version attached.
In my opinion this drastically increases readability and thus should be
applied. Will do so sometime tomorrow unless there's protest.-1 to introducing more inline functions before committable code replaces what
you've already pushed for this thread.
Seriously?
I've no problem with "fixing" anything. So far we have don't seem to
have to come to a agreement what exactly that fix would be. Tom has
stated that he doesn't want lock.h made smaller on account of frontend
code including it, and you see that as the right way.
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-08 02:30:44 -0400, Noah Misch wrote:
On Sat, Aug 08, 2015 at 02:30:47AM +0200, Andres Freund wrote:
On 2015-08-07 20:16:20 -0400, Noah Misch wrote:
I agree that lock.h offers little to frontend code. Headers that the
lockdefs.h patch made usable in the frontend, particularly genam.h and hash.h,
are no better.It's not that simple. Those two, and tuptoaster.h, are actually somewhat
validly included by frontend code via the rmgr descriptor routines.genam.h is a dependency of the non-frontend-relevant content of some
frontend-relevant headers, _exactly_ as lock.h has been. I count zero things
in genam.h that a frontend program could harness. The frontend includes
hash.h for two hashdesc.c prototypes, less than the material you moved out of
lock.h for frontend benefit. Yes, it is that simple.
The point is that it's included from various headers and that there's
really no need to include lock.h from a header that just wants to
declare a LOCKMODE as it's parameter. There's no other contents in
lock.h afaics that fit the billet similarly. To me it's a rather
worthwhile goald to want *am.h not to pull in details of the locking
implementations, but they're going to have to define a LOCKMODE
parameter and the values passed in. We're not entirely there, but it's
not much further work.
We could split some stuff in a more 'locking internals' oriented headers
(PROC_QUEUE, LockMethodData and dependants, LOCKTAG and depenedants),
but afaics it'd not be a proper lock_internal.h header either, because
there's code like index.c that currently does SET_LOCKTAG_RELATION
itself.
The lock.h/lockdefs.h unprincipled split would do more harm
than letting frontends continue to pull in lock.h.Why?
Your header comment for lockdefs.h sums up the harm nicely. Additionally, the
term "defs" does nothing to explain the split. "lock2.h" would be no less
evocative.
Oh, come on. It's not the only header that's split that way (see
xlogdefs.h). Splitting away some key definitions so not all the
internals are dragged in when needing just the simplest definitions is
not an absurd concept.
Consider what happens when lock.h/c gets more complicated and
e.g. grows some atomics. None of the frontend code should see that, and
it's not much effort to keep it that way. Allowing client code to see
LOCKMODE isn't something that's going to cause any harm.Readying the headers for that day brings some value, but you added a worse
mess to achieve it. The overall achievement has negative value.
I honestly can't follow. Why is it so absurd to avoid including lock.h
from more code, including FRONTEND one? Or is it just the lockdefs.h
split along the 'as-currently-required' line that you object to?
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Tue, Aug 11, 2015 at 10:34 PM, Noah Misch <noah@leadboat.com> wrote:
In my opinion this drastically increases readability and thus should be
applied. Will do so sometime tomorrow unless there's protest.-1 to introducing more inline functions before committable code replaces what
you've already pushed for this thread.
This appears to be intended as an insult, but maybe I'm misreading it.
I am not thrilled with the rate at which this stuff is getting whacked
around. Less-significant changes have been debated for far longer,
and I really doubt that the rate at which Andres is committing changes
in this area is healthy. I don't doubt that he has good intentions,
though.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-12 13:00:25 -0400, Robert Haas wrote:
On Tue, Aug 11, 2015 at 10:34 PM, Noah Misch <noah@leadboat.com> wrote:
In my opinion this drastically increases readability and thus should be
applied. Will do so sometime tomorrow unless there's protest.-1 to introducing more inline functions before committable code replaces what
you've already pushed for this thread.This appears to be intended as an insult, but maybe I'm misreading it.
I read it as one.
I am not thrilled with the rate at which this stuff is getting whacked
around. Less-significant changes have been debated for far longer,
and I really doubt that the rate at which Andres is committing changes
in this area is healthy.
There was one "feature" patch committed about the actual topic so far
(de6fd1c), and then some fixes to handle the portability fallout and a
admittedly stypid typo. We've debated the inline thing for years now and
seem to have a come to a conclusion about a month ago
(http://archives.postgresql.org/message-id/27127.1435791908%40sss.pgh.pa.us). You
then brought up the thread again
(CA+TgmoaaVfx1KVz5WBkvi1o6oZRxzF0micStTAO7gGUV5a4MwQ@mail.gmail.com)
sometimes after that I started to work on a patch.
Maybe I should have waited bit more to commit the initial, rather
mechanical, conversion to inlines patch, although I don't see what
that'd really have bought us:
This kind of patch (tinkering with autoconf, portability and the like)
normally triggers just about no feedback until it has caused
problems. The buildfarm exists to catch such portability problems.
The issue we're actually arguing about (lockdefs split) was indeed
necessitated by a portability issue (30786.1438831088@sss.pgh.pa.us).
One that actually has existed at least since atomics went in - it just
happens that most (but not all, c.f. a9baeb361d and 7507b19) compilers
that support inlines don't emit references to symbols referenced in a
unused inline function. Since nobody noticed that issue in the 1+ years
atomics was learning to walk on list, and not in the 8 months since it
was committed, it's quite obviously not obvious.
WRT the lockdefs.h split. It wasn't my idea (IIRC Alvaro's; I wanted to
do something closes to what Noah suggested before Tom objected to lock.h
in FRONTEND programs!), and I did wait for a day, while the buildfarm
was red!, after posting it. At least two committers did comment on the
approach before I pushed it. We've seen far more hot-needled patches to
fix the buildfarm in topics with less portability risks. I could have
left the buildfarm red for longer, but that might have hidden more
severe portability problems. It's not like I committed that patch after
somebody had suggested another way: Noah only commented after I had
already pushed the split.
The only actual separate patch since then (fastgetattr as inline
function) was posted 2015-08-05 and I yesterday suggested to push it
today. And it's just replacing two existing macros by inline functions.
Imo there are far more complex patches regularly get committed by
various people, with less discussion and review.
There's afaik nothing broken due to either the inline patch or the
lockdefs split right now. There's one portability bandaid, judged to be
ugly by some, that we're discussing right now, and I'm happy to rejigger
it if the various people with contradicting opinions can come to an
agreement.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Aug 12, 2015 at 2:57 PM, Andres Freund <andres@anarazel.de> wrote:
The only actual separate patch since then (fastgetattr as inline
function) was posted 2015-08-05 and I yesterday suggested to push it
today. And it's just replacing two existing macros by inline functions.
I'm a little concerned about that one. Your testing shows that's a
win for you, but is it a win for everyone? Maybe we should go ahead
and do it anyway, but I'm not sure.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 08/12/2015 11:25 PM, Robert Haas wrote:
On Wed, Aug 12, 2015 at 2:57 PM, Andres Freund <andres@anarazel.de> wrote:
The only actual separate patch since then (fastgetattr as inline
function) was posted 2015-08-05 and I yesterday suggested to push it
today. And it's just replacing two existing macros by inline functions.I'm a little concerned about that one. Your testing shows that's a
win for you, but is it a win for everyone? Maybe we should go ahead
and do it anyway, but I'm not sure.
Andres didn't mention how big the performance benefit he saw with
pgbench was, but I bet it was barely distinguishible from noise. But
that's OK. In fact, there's no reason to believe this would make any
difference to performance. The point is to make the code more readable,
and it certainly achieves that.
- Heikki
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Aug 12, 2015 at 1:34 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
Andres didn't mention how big the performance benefit he saw with pgbench
was, but I bet it was barely distinguishible from noise. But that's OK. In
fact, there's no reason to believe this would make any difference to
performance. The point is to make the code more readable, and it certainly
achieves that.
+1
--
Peter Geoghegan
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-12 16:25:17 -0400, Robert Haas wrote:
On Wed, Aug 12, 2015 at 2:57 PM, Andres Freund <andres@anarazel.de> wrote:
The only actual separate patch since then (fastgetattr as inline
function) was posted 2015-08-05 and I yesterday suggested to push it
today. And it's just replacing two existing macros by inline functions.I'm a little concerned about that one. Your testing shows that's a
win for you, but is it a win for everyone? Maybe we should go ahead
and do it anyway, but I'm not sure.
I don't think it's likely to affect performance in any significant way
in either direction. I mean, the absolute worst case would be that a
formerly in-place fastgetattr() call gets changed into a function call
in the same translation unit. That might or might not have a performance
impact in either direction, but it's not going to be large. The only
reason this has improved performance is imo that it shrank the code size
a bit (increasing cache hit ratio, increase use of the branch prediction
unit etc.).
In all the profiles I've seen where fastgetattr (or rather the in-place
code it has) is responsible for some portion of the runtime it was the
actual looping, the cache misses, et al, not the stack and the indirect
call. It's debatable that it's inline (via macro or inline function) in
the first place.
The advantage is not performance, it's readability. I've several times
re-wrapped fastgetattr() just to understand what it does, because I
otherwise find the code so hard to read. Maybe I just utterly suck at
reading macros...
You might argue that it's nothing we have touched frequently. And you're
right. But I think that's a mistake. We spend far too much time in the
various pieces of code dissembling tuples, and I think at some point
somebody really needs to spend time on this.
Regards,
Andres
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-12 23:34:38 +0300, Heikki Linnakangas wrote:
Andres didn't mention how big the performance benefit he saw with pgbench
was, but I bet it was barely distinguishible from noise.
I think it was discernible (I played around with changing unrelated code
trying to exclude unrelated layout issues), but it definitely was
small. I think the only reason it had any effect is the reduced overall
code size.
The point is to make the code more readable, and it certainly achieves
that.
Exactly.
- Andres
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Aug 12, 2015 at 4:34 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
Andres didn't mention how big the performance benefit he saw with pgbench
was, but I bet it was barely distinguishible from noise. But that's OK. In
fact, there's no reason to believe this would make any difference to
performance. The point is to make the code more readable, and it certainly
achieves that.
I think that when Bruce macro-ized this ten years ago or whenever it
was, he got a significant performance benefit from it; otherwise I
don't think he would have done it. It may well be that the march of
time has improved compiler technology to the point where no benefit
remains, and that's fine. But just as with any other part of the
code, we shouldn't start with the premise that the existing code is
bad the way it is. If a careful analysis leads us to that conclusion,
that's fine.
In this particular case, I am more concerned about making sure that
people who have an opinion get a chance to air it than I am with the
outcome. I have no reason to believe that we shouldn't make this
change; I merely want to make sure that anyone who does have a concern
about this (or other changes in this area) has a chance to be heard
before we get too far down the path. Nobody's going to want to turn
back the clock once we do this.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Hi,
On 2015-08-06 12:43:06 -0300, Alvaro Herrera wrote:
Andres Freund wrote:
On 2015-08-06 12:29:15 -0300, Alvaro Herrera wrote:
Ah, but that's because you cheated and didn't remove the include from
namespace.h ...Well, it's not included from frontend code, so I didn't see the need?
Going through all the backend code and replacing lock.h by lockdefs.h
and some other includes doesn't seem particularly beneficial to me.FWIW, removing it from namespace.h is relatively easy. It starts to get
a lot more noisy when you want to touch heapam.h.Ah, heapam.h is the granddaddy of all header messes, isn't it. (Actually
it's execnodes.h or something like that.)
diff --git a/src/include/storage/lockdefs.h b/src/include/storage/lockdefs.h new file mode 100644 index 0000000..bfbcdba --- /dev/null +++ b/src/include/storage/lockdefs.h @@ -0,0 +1,56 @@ +/*------------------------------------------------------------------------- + * + * lockdefs.h + * Frontend exposed parts of postgres' low level lock mechanism + * + * The split between lockdefs.h and lock.h is not very principled.No kidding!
Do you have a good suggestion about the split? I wanted to expose the
minimal amount necessary, and those were the ones.Nope, nothing useful, sorry.
To pick up on the general discussion and on the points you made here:
I actually think the split came out to work far better than I'd
anticipated. Having a slimmed-down version of lock.h for code that just
needs to declare/pass lockmode parameters seems to improve our layering
considerably. I got round to Alvaro's and Roberts position that
removing lock.h from namespace.h and heapam.h would be a really nice
improvemen on that front.
Attached is a WIP patch to that end. After the further changes only few
headers still have to include lock.h and they're pretty firmly in the
backend-only territory. It also allows to remove the uglyness of passing
around LOCKMODE as an int in parserOpenTable().
Imo lockdefs.h should be updated to describe that it contains the part
of the lock infrastructure needed by indirect users of lock.h
infrastructure, and that that currently unfortunately may include some
frontend programs.
I *also* think that removing lwlock.h from lock.h would be a good
idea. In my opinion it's a bad idea to pointlessly expose so much
low-level things to the wider world, even if it's only needed by
relatively low level things. Given that dependent macros are in
lwlock.h, it seems pretty sane to move LockHash* there too.
We could additionally move all but LOCKMETHODID, LockTagType,
LockAcquire*(), LockRelease() and probably one or two more to
lock_internals.h (although I'd maybe rather name it lock_details?). I
think it'd be an improvement, although possibly not a tremendous one
given how many places it's likely going to be included from.
Greetings,
Andres Freund
Attachments:
0001-WIP-Decrease-usage-of-lock.h-further.patchtext/x-patch; charset=us-asciiDownload
>From f9a74a50c5c02b1a3276385468ae41359741f9fa Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Fri, 14 Aug 2015 19:36:04 +0200
Subject: [PATCH] WIP: Decrease usage of lock.h further.
---
contrib/pg_stat_statements/pg_stat_statements.c | 2 ++
src/backend/access/common/reloptions.c | 1 +
src/backend/access/heap/syncscan.c | 2 ++
src/backend/access/nbtree/nbtutils.c | 2 ++
src/backend/access/transam/commit_ts.c | 1 +
src/backend/catalog/toasting.c | 1 -
src/backend/commands/discard.c | 1 +
src/backend/commands/policy.c | 1 -
src/backend/commands/tablecmds.c | 1 -
src/backend/parser/parse_relation.c | 6 +-----
src/backend/tsearch/ts_typanalyze.c | 1 +
src/backend/utils/adt/array_typanalyze.c | 1 +
src/backend/utils/cache/ts_cache.c | 1 +
src/include/access/heapam.h | 2 +-
src/include/access/reloptions.h | 2 +-
src/include/catalog/namespace.h | 2 +-
src/include/catalog/pg_inherits_fn.h | 2 +-
src/include/catalog/toasting.h | 2 +-
src/include/commands/cluster.h | 2 +-
src/include/commands/tablecmds.h | 2 +-
src/include/commands/vacuum.h | 2 +-
src/include/nodes/execnodes.h | 1 +
src/include/parser/parse_oper.h | 1 +
src/include/parser/parse_relation.h | 3 ++-
24 files changed, 25 insertions(+), 17 deletions(-)
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 59b8a2e..a3b40e8 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -72,6 +72,8 @@
#include "pgstat.h"
#include "storage/fd.h"
#include "storage/ipc.h"
+#include "storage/lwlock.h"
+#include "storage/shmem.h"
#include "storage/spin.h"
#include "tcop/utility.h"
#include "utils/builtins.h"
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 7479d40..8c75ff5 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -26,6 +26,7 @@
#include "commands/tablespace.h"
#include "commands/view.h"
#include "nodes/makefuncs.h"
+#include "storage/lock.h"
#include "utils/array.h"
#include "utils/attoptcache.h"
#include "utils/builtins.h"
diff --git a/src/backend/access/heap/syncscan.c b/src/backend/access/heap/syncscan.c
index 266c330..58241d0 100644
--- a/src/backend/access/heap/syncscan.c
+++ b/src/backend/access/heap/syncscan.c
@@ -49,6 +49,8 @@
#include "access/heapam.h"
#include "miscadmin.h"
#include "utils/rel.h"
+#include "storage/lwlock.h"
+#include "storage/shmem.h"
/* GUC variables */
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index 91331ba..f36086d 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -25,6 +25,8 @@
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/rel.h"
+#include "storage/lwlock.h"
+#include "storage/shmem.h"
typedef struct BTSortArrayContext
diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c
index 5ad35c0..a8d2cc2 100644
--- a/src/backend/access/transam/commit_ts.c
+++ b/src/backend/access/transam/commit_ts.c
@@ -32,6 +32,7 @@
#include "funcapi.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "storage/shmem.h"
#include "utils/builtins.h"
#include "utils/snapmgr.h"
#include "utils/timestamp.h"
diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c
index 3652d7b..8e8f32e 100644
--- a/src/backend/catalog/toasting.c
+++ b/src/backend/catalog/toasting.c
@@ -27,7 +27,6 @@
#include "catalog/toasting.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
-#include "storage/lock.h"
#include "utils/builtins.h"
#include "utils/rel.h"
#include "utils/syscache.h"
diff --git a/src/backend/commands/discard.c b/src/backend/commands/discard.c
index b40ef35..6ba4efb 100644
--- a/src/backend/commands/discard.c
+++ b/src/backend/commands/discard.c
@@ -19,6 +19,7 @@
#include "commands/discard.h"
#include "commands/prepare.h"
#include "commands/sequence.h"
+#include "storage/lock.h"
#include "utils/guc.h"
#include "utils/portal.h"
diff --git a/src/backend/commands/policy.c b/src/backend/commands/policy.c
index bcf4a8f..977c315 100644
--- a/src/backend/commands/policy.c
+++ b/src/backend/commands/policy.c
@@ -35,7 +35,6 @@
#include "parser/parse_relation.h"
#include "rewrite/rewriteManip.h"
#include "rewrite/rowsecurity.h"
-#include "storage/lock.h"
#include "utils/acl.h"
#include "utils/array.h"
#include "utils/builtins.h"
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 126b119..b625bac 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -77,7 +77,6 @@
#include "rewrite/rewriteManip.h"
#include "storage/bufmgr.h"
#include "storage/lmgr.h"
-#include "storage/lock.h"
#include "storage/predicate.h"
#include "storage/smgr.h"
#include "utils/acl.h"
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index 0b2dacf..e8c6313 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -1110,13 +1110,9 @@ chooseScalarFunctionAlias(Node *funcexpr, char *funcname,
* This is essentially just the same as heap_openrv(), except that it caters
* to some parser-specific error reporting needs, notably that it arranges
* to include the RangeVar's parse location in any resulting error.
- *
- * Note: properly, lockmode should be declared LOCKMODE not int, but that
- * would require importing storage/lock.h into parse_relation.h. Since
- * LOCKMODE is typedef'd as int anyway, that seems like overkill.
*/
Relation
-parserOpenTable(ParseState *pstate, const RangeVar *relation, int lockmode)
+parserOpenTable(ParseState *pstate, const RangeVar *relation, LOCKMODE lockmode)
{
Relation rel;
ParseCallbackState pcbstate;
diff --git a/src/backend/tsearch/ts_typanalyze.c b/src/backend/tsearch/ts_typanalyze.c
index 432b582..c799a5c 100644
--- a/src/backend/tsearch/ts_typanalyze.c
+++ b/src/backend/tsearch/ts_typanalyze.c
@@ -18,6 +18,7 @@
#include "commands/vacuum.h"
#include "tsearch/ts_type.h"
#include "utils/builtins.h"
+#include "utils/hsearch.h"
/* A hash key for lexemes */
diff --git a/src/backend/utils/adt/array_typanalyze.c b/src/backend/utils/adt/array_typanalyze.c
index ffe8035..201614c 100644
--- a/src/backend/utils/adt/array_typanalyze.c
+++ b/src/backend/utils/adt/array_typanalyze.c
@@ -19,6 +19,7 @@
#include "commands/vacuum.h"
#include "utils/array.h"
#include "utils/datum.h"
+#include "utils/hsearch.h"
#include "utils/lsyscache.h"
#include "utils/typcache.h"
diff --git a/src/backend/utils/cache/ts_cache.c b/src/backend/utils/cache/ts_cache.c
index 5b1c358..a10d649 100644
--- a/src/backend/utils/cache/ts_cache.c
+++ b/src/backend/utils/cache/ts_cache.c
@@ -42,6 +42,7 @@
#include "utils/builtins.h"
#include "utils/catcache.h"
#include "utils/fmgroids.h"
+#include "utils/hsearch.h"
#include "utils/inval.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index 75e6b72..e7f99af 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -19,7 +19,7 @@
#include "nodes/lockoptions.h"
#include "nodes/primnodes.h"
#include "storage/bufpage.h"
-#include "storage/lock.h"
+#include "storage/lockdefs.h"
#include "utils/relcache.h"
#include "utils/snapshot.h"
diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h
index 2a3cbcd..3e45a50 100644
--- a/src/include/access/reloptions.h
+++ b/src/include/access/reloptions.h
@@ -22,7 +22,7 @@
#include "access/htup.h"
#include "access/tupdesc.h"
#include "nodes/pg_list.h"
-#include "storage/lock.h"
+#include "storage/lockdefs.h"
/* types supported by reloptions */
typedef enum relopt_type
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index f3b005f..b4c04dd 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -15,7 +15,7 @@
#define NAMESPACE_H
#include "nodes/primnodes.h"
-#include "storage/lock.h"
+#include "storage/lockdefs.h"
/*
diff --git a/src/include/catalog/pg_inherits_fn.h b/src/include/catalog/pg_inherits_fn.h
index 3ff1947..d64ec94 100644
--- a/src/include/catalog/pg_inherits_fn.h
+++ b/src/include/catalog/pg_inherits_fn.h
@@ -15,7 +15,7 @@
#define PG_INHERITS_FN_H
#include "nodes/pg_list.h"
-#include "storage/lock.h"
+#include "storage/lockdefs.h"
extern List *find_inheritance_children(Oid parentrelId, LOCKMODE lockmode);
extern List *find_all_inheritors(Oid parentrelId, LOCKMODE lockmode,
diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h
index fb2f035..a06772a 100644
--- a/src/include/catalog/toasting.h
+++ b/src/include/catalog/toasting.h
@@ -14,7 +14,7 @@
#ifndef TOASTING_H
#define TOASTING_H
-#include "storage/lock.h"
+#include "storage/lockdefs.h"
/*
* toasting.c prototypes
diff --git a/src/include/commands/cluster.h b/src/include/commands/cluster.h
index 098d09b..f32b3fe 100644
--- a/src/include/commands/cluster.h
+++ b/src/include/commands/cluster.h
@@ -14,7 +14,7 @@
#define CLUSTER_H
#include "nodes/parsenodes.h"
-#include "storage/lock.h"
+#include "storage/lockdefs.h"
#include "utils/relcache.h"
diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h
index f269c63..00366f5 100644
--- a/src/include/commands/tablecmds.h
+++ b/src/include/commands/tablecmds.h
@@ -18,7 +18,7 @@
#include "catalog/dependency.h"
#include "catalog/objectaddress.h"
#include "nodes/parsenodes.h"
-#include "storage/lock.h"
+#include "storage/lockdefs.h"
#include "utils/relcache.h"
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index e3a31af..e688adf 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -19,7 +19,7 @@
#include "catalog/pg_type.h"
#include "nodes/parsenodes.h"
#include "storage/buf.h"
-#include "storage/lock.h"
+#include "storage/lockdefs.h"
#include "utils/relcache.h"
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 5796de8..c65de97 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -20,6 +20,7 @@
#include "lib/pairingheap.h"
#include "nodes/params.h"
#include "nodes/plannodes.h"
+#include "utils/hsearch.h"
#include "utils/reltrigger.h"
#include "utils/sortsupport.h"
#include "utils/tuplestore.h"
diff --git a/src/include/parser/parse_oper.h b/src/include/parser/parse_oper.h
index ed5332d..8346566 100644
--- a/src/include/parser/parse_oper.h
+++ b/src/include/parser/parse_oper.h
@@ -15,6 +15,7 @@
#define PARSE_OPER_H
#include "access/htup.h"
+#include "utils/hsearch.h"
#include "parser/parse_node.h"
diff --git a/src/include/parser/parse_relation.h b/src/include/parser/parse_relation.h
index e2875a0..cd95b88 100644
--- a/src/include/parser/parse_relation.h
+++ b/src/include/parser/parse_relation.h
@@ -15,6 +15,7 @@
#define PARSE_RELATION_H
#include "parser/parse_node.h"
+#include "storage/lockdefs.h"
/*
@@ -60,7 +61,7 @@ extern Node *colNameToVar(ParseState *pstate, char *colname, bool localonly,
extern void markVarForSelectPriv(ParseState *pstate, Var *var,
RangeTblEntry *rte);
extern Relation parserOpenTable(ParseState *pstate, const RangeVar *relation,
- int lockmode);
+ LOCKMODE lockmode);
extern RangeTblEntry *addRangeTableEntry(ParseState *pstate,
RangeVar *relation,
Alias *alias,
--
2.3.0.149.gf3f4077.dirty
On Fri, Aug 14, 2015 at 2:40 PM, Andres Freund <andres@anarazel.de> wrote:
To pick up on the general discussion and on the points you made here:
I actually think the split came out to work far better than I'd
anticipated. Having a slimmed-down version of lock.h for code that just
needs to declare/pass lockmode parameters seems to improve our layering
considerably. I got round to Alvaro's and Roberts position that
removing lock.h from namespace.h and heapam.h would be a really nice
improvemen on that front.Attached is a WIP patch to that end. After the further changes only few
headers still have to include lock.h and they're pretty firmly in the
backend-only territory. It also allows to remove the uglyness of passing
around LOCKMODE as an int in parserOpenTable().
Yes, I like this.
Imo lockdefs.h should be updated to describe that it contains the part
of the lock infrastructure needed by indirect users of lock.h
infrastructure, and that that currently unfortunately may include some
frontend programs.
Sure.
I *also* think that removing lwlock.h from lock.h would be a good
idea. In my opinion it's a bad idea to pointlessly expose so much
low-level things to the wider world, even if it's only needed by
relatively low level things. Given that dependent macros are in
lwlock.h, it seems pretty sane to move LockHash* there too.
Hmm. I dunno, lwlock.h is a pretty hideous layering violation as it
is. I'd like to find a way to make that better, not worse.
We could additionally move all but LOCKMETHODID, LockTagType,
LockAcquire*(), LockRelease() and probably one or two more to
lock_internals.h (although I'd maybe rather name it lock_details?). I
think it'd be an improvement, although possibly not a tremendous one
given how many places it's likely going to be included from.
What benefit would we get out of this?
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Tue, Aug 11, 2015 at 01:04:48PM +0200, Andres Freund wrote:
On 2015-08-05 15:46:36 +0200, Andres Freund wrote:
Here's a conversion for fastgetattr() and heap_getattr().
In my opinion this drastically increases readability and thus should be
applied.
Atomics were a miner's canary for pademelon's trouble with post-de6fd1c
inlining. Expect pademelon to break whenever a frontend-included file gains
an inline function that calls a backend function. Atomics were the initial
examples, but this patch adds more:
$ make -s PROFILE='-O0 -DPG_FORCE_DISABLE_INLINE=1'
pg_resetxlog.o: In function `fastgetattr':
/data/nmisch/src/pg/postgresql/src/bin/pg_resetxlog/../../../src/include/access/htup_details.h:754: undefined reference to `nocachegetattr'
pg_resetxlog.o: In function `heap_getattr':
/data/nmisch/src/pg/postgresql/src/bin/pg_resetxlog/../../../src/include/access/htup_details.h:783: undefined reference to `heap_getsysattr'
The htup_details.h case is trickier in a way, because pg_resetxlog has a
legitimate need for SizeofHeapTupleHeader via TOAST_MAX_CHUNK_SIZE. Expect
this class of problem to recur as we add more inline functions. Our method to
handle these first two instances will set a precedent.
That gave me new respect for STATIC_IF_INLINE. While it does add tedious work
to the task of introducing a new batch of inline functions, the work is
completely mechanical. Anyone can write it; anyone can review it; there's one
correct way to write it. Header surgery like
0001-Don-t-include-low-level-locking-code-from-frontend-c.patch requires
expert design from scratch, and it (trivially) breaks builds for a sample of
non-core code. Let's return to STATIC_IF_INLINE and convert fastgetattr()
therewith. (A possible future line of inquiry is to generate the
STATIC_IF_INLINE transformation at build time, so the handwritten headers can
use C99 inlining directly as though it is always available.)
Thanks,
nm
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On August 15, 2015 6:47:09 PM GMT+02:00, Noah Misch <noah@leadboat.com> wrote:
On Tue, Aug 11, 2015 at 01:04:48PM +0200, Andres Freund wrote:
On 2015-08-05 15:46:36 +0200, Andres Freund wrote:
Here's a conversion for fastgetattr() and heap_getattr().
In my opinion this drastically increases readability and thus should
be
applied.
Atomics were a miner's canary for pademelon's trouble with post-de6fd1c
inlining. Expect pademelon to break whenever a frontend-included file
gains
an inline function that calls a backend function. Atomics were the
initial
examples, but this patch adds more:$ make -s PROFILE='-O0 -DPG_FORCE_DISABLE_INLINE=1'
pg_resetxlog.o: In function `fastgetattr':
/data/nmisch/src/pg/postgresql/src/bin/pg_resetxlog/../../../src/include/access/htup_details.h:754:
undefined reference to `nocachegetattr'
pg_resetxlog.o: In function `heap_getattr':
/data/nmisch/src/pg/postgresql/src/bin/pg_resetxlog/../../../src/include/access/htup_details.h:783:
undefined reference to `heap_getsysattr'The htup_details.h case is trickier in a way, because pg_resetxlog has
a
legitimate need for SizeofHeapTupleHeader via TOAST_MAX_CHUNK_SIZE.
Expect
this class of problem to recur as we add more inline functions. Our
method to
handle these first two instances will set a precedent.That gave me new respect for STATIC_IF_INLINE. While it does add
tedious work
to the task of introducing a new batch of inline functions, the work is
completely mechanical. Anyone can write it; anyone can review it;
there's one
correct way to write it. Header surgery like
0001-Don-t-include-low-level-locking-code-from-frontend-c.patch
requires
expert design from scratch, and it (trivially) breaks builds for a
sample of
non-core code. Let's return to STATIC_IF_INLINE and convert
fastgetattr()
therewith. (A possible future line of inquiry is to generate the
STATIC_IF_INLINE transformation at build time, so the handwritten
headers can
use C99 inlining directly as though it is always available.)
I'll respond in detail later. But wouldn't it be easy in this case to just ifndef FRONTEND things in this case?
---
Please excuse brevity and formatting - I am writing this on my mobile phone.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@anarazel.de> writes:
On August 15, 2015 6:47:09 PM GMT+02:00, Noah Misch <noah@leadboat.com> wrote:
That gave me new respect for STATIC_IF_INLINE. While it does add
tedious work to the task of introducing a new batch of inline
functions, the work is completely mechanical. Anyone can write it;
anyone can review it; there's one correct way to write it. Header
surgery like
0001-Don-t-include-low-level-locking-code-from-frontend-c.patch
requires expert design from scratch, and it (trivially) breaks builds
for a sample of non-core code. Let's return to STATIC_IF_INLINE and
convert fastgetattr() therewith. (A possible future line of inquiry is
to generate the STATIC_IF_INLINE transformation at build time, so the
handwritten headers can use C99 inlining directly as though it is
always available.)
I'll respond in detail later. But wouldn't it be easy in this case to
just ifndef FRONTEND things in this case?
I think that's missing Noah's point. Yeah, we'll probably always be able
to hack things to continue to work, but the key word there is "hack".
And if we don't have buildfarm coverage for compilers that are stupid
about inlining, we can expect to break the case regularly. (pademelon
won't last forever, though maybe by the time that box dies we'll figure
we no longer need to care about such compilers.)
I'm not especially in love with STATIC_IF_INLINE, but it did offer a
mechanical if tedious solution.
Realistically, with what we're doing now, we *have* broken things for
stupid-about-inlines compilers; because even if everything in the core
distribution builds, we've almost certainly created failures for
third-party modules that need to #include headers that no contrib
module includes.
Maybe we should just say "okay, we're raising the bar for 9.6: compilers
that don't elide unused static inlines need not apply". But I'd be
happier if we had a clear idea which those were. And if we go that route,
we ought to add a configure test checking it.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-15 12:47:09 -0400, Noah Misch wrote:
Atomics were a miner's canary for pademelon's trouble with post-de6fd1c
inlining. Expect pademelon to break whenever a frontend-included file gains
an inline function that calls a backend function. Atomics were the initial
examples, but this patch adds more:
That's a good point.
$ make -s PROFILE='-O0 -DPG_FORCE_DISABLE_INLINE=1'
pg_resetxlog.o: In function `fastgetattr':
/data/nmisch/src/pg/postgresql/src/bin/pg_resetxlog/../../../src/include/access/htup_details.h:754: undefined reference to `nocachegetattr'
pg_resetxlog.o: In function `heap_getattr':
/data/nmisch/src/pg/postgresql/src/bin/pg_resetxlog/../../../src/include/access/htup_details.h:783: undefined reference to `heap_getsysattr'The htup_details.h case is trickier in a way, because pg_resetxlog has a
legitimate need for SizeofHeapTupleHeader via TOAST_MAX_CHUNK_SIZE. Expect
this class of problem to recur as we add more inline functions. Our method to
handle these first two instances will set a precedent.That gave me new respect for STATIC_IF_INLINE. While it does add tedious work
to the task of introducing a new batch of inline functions, the work is
completely mechanical. Anyone can write it; anyone can review it; there's one
correct way to write it.
What's the advantage of using STATIC_IF_INLINE over just #ifndef
FRONTEND? That doesn't work well for entire headers in my opinion, but
for individual functions it shouldn't be a problem? In fact we've done
it for years for MemoryContextSwitchTo(). And by the problem definition
such functions cannot be required by frontend code.
STATIC_IF_INLINE is really tedious because to know whether it works you
essentially need to recompile postgres with inlines enabled/disabled.
In fact STATIC_IF_INLINE does *not* even help here unless we also detect
compilers that support inlining but balk when inline functions reference
symbols not available. There was an example of that in the buildfarm as
of 2014, c.f. a9baeb361d63 . We'd have to disable inlining for such
compilers.
Header surgery like
0001-Don-t-include-low-level-locking-code-from-frontend-c.patch
requires expert design from scratch, and it (trivially) breaks builds
for a sample of non-core code.
I agree that such surgery isn't always a good idea. In my opinion the
removing proc.h from the number of headers in the above and the followon
WIP patch I posted has value completely independently from fixing
problems.
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Sun, Aug 16, 2015 at 02:03:01AM +0200, Andres Freund wrote:
On 2015-08-15 12:47:09 -0400, Noah Misch wrote:
$ make -s PROFILE='-O0 -DPG_FORCE_DISABLE_INLINE=1'
pg_resetxlog.o: In function `fastgetattr':
/data/nmisch/src/pg/postgresql/src/bin/pg_resetxlog/../../../src/include/access/htup_details.h:754: undefined reference to `nocachegetattr'
pg_resetxlog.o: In function `heap_getattr':
/data/nmisch/src/pg/postgresql/src/bin/pg_resetxlog/../../../src/include/access/htup_details.h:783: undefined reference to `heap_getsysattr'
What's the advantage of using STATIC_IF_INLINE over just #ifndef
FRONTEND?
In fact STATIC_IF_INLINE does *not* even help here unless we also detect
compilers that support inlining but balk when inline functions reference
symbols not available. There was an example of that in the buildfarm as
of 2014, c.f. a9baeb361d63 . We'd have to disable inlining for such
compilers.
Neat; I didn't know that. Solaris Studio 12.3 (newest version as of Oct 2014)
still does that when optimization is disabled, and I place sufficient value on
keeping inlining enabled for such a new compiler. The policy would then be
(already is?) to wrap in "#ifdef FRONTEND" any inline function that uses a
backend symbol. When a header is dedicated to such functions, we might avoid
the whole header in the frontend instead of wrapping each function. That
policy works for me.
On Sat, Aug 15, 2015 at 01:48:17PM -0400, Tom Lane wrote:
Realistically, with what we're doing now, we *have* broken things for
stupid-about-inlines compilers; because even if everything in the core
distribution builds, we've almost certainly created failures for
third-party modules that need to #include headers that no contrib
module includes.
Only FRONTEND code (e.g. repmgr, pg_reorg) will be at hazard, not ordinary
third-party (backend) modules. We could have a test frontend that includes
every header minus a blacklist, but I don't think it's essential. External
FRONTEND code is an order of magnitude less common than external backend code.
Unlike backend module development, we don't document the existence of the
FRONTEND programming environment.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-15 23:50:09 -0400, Noah Misch wrote:
On Sun, Aug 16, 2015 at 02:03:01AM +0200, Andres Freund wrote:
On 2015-08-15 12:47:09 -0400, Noah Misch wrote:
$ make -s PROFILE='-O0 -DPG_FORCE_DISABLE_INLINE=1'
pg_resetxlog.o: In function `fastgetattr':
/data/nmisch/src/pg/postgresql/src/bin/pg_resetxlog/../../../src/include/access/htup_details.h:754: undefined reference to `nocachegetattr'
pg_resetxlog.o: In function `heap_getattr':
/data/nmisch/src/pg/postgresql/src/bin/pg_resetxlog/../../../src/include/access/htup_details.h:783: undefined reference to `heap_getsysattr'What's the advantage of using STATIC_IF_INLINE over just #ifndef
FRONTEND?In fact STATIC_IF_INLINE does *not* even help here unless we also detect
compilers that support inlining but balk when inline functions reference
symbols not available. There was an example of that in the buildfarm as
of 2014, c.f. a9baeb361d63 . We'd have to disable inlining for such
compilers.Neat; I didn't know that.
Personally I don't find that particularly neat, rather annoying actually
:P
Solaris Studio 12.3 (newest version as of Oct 2014) still does that
when optimization is disabled, and I place sufficient value on keeping
inlining enabled for such a new compiler.
Ah, that's cool. I was wondering generally how we could find an animal
to detect that case once pademelon met its untimely (or timely by now?)
end.
The policy would then be
(already is?) to wrap in "#ifdef FRONTEND" any inline function that uses a
backend symbol. When a header is dedicated to such functions, we might avoid
the whole header in the frontend instead of wrapping each function. That
policy works for me.
Cool. I was wondering before where we'd document policy around
this. sources.sgml?
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Sun, Aug 16, 2015 at 05:58:17AM +0200, Andres Freund wrote:
On 2015-08-15 23:50:09 -0400, Noah Misch wrote:
On Sun, Aug 16, 2015 at 02:03:01AM +0200, Andres Freund wrote:
On 2015-08-15 12:47:09 -0400, Noah Misch wrote:
$ make -s PROFILE='-O0 -DPG_FORCE_DISABLE_INLINE=1'
pg_resetxlog.o: In function `fastgetattr':
/data/nmisch/src/pg/postgresql/src/bin/pg_resetxlog/../../../src/include/access/htup_details.h:754: undefined reference to `nocachegetattr'
pg_resetxlog.o: In function `heap_getattr':
/data/nmisch/src/pg/postgresql/src/bin/pg_resetxlog/../../../src/include/access/htup_details.h:783: undefined reference to `heap_getsysattr'What's the advantage of using STATIC_IF_INLINE over just #ifndef
FRONTEND?In fact STATIC_IF_INLINE does *not* even help here unless we also detect
compilers that support inlining but balk when inline functions reference
symbols not available. There was an example of that in the buildfarm as
of 2014, c.f. a9baeb361d63 . We'd have to disable inlining for such
compilers.
Solaris Studio 12.3 (newest version as of Oct 2014) still does that
when optimization is disabled, and I place sufficient value on keeping
inlining enabled for such a new compiler.Ah, that's cool. I was wondering generally how we could find an animal
to detect that case once pademelon met its untimely (or timely by now?)
end.
I would just make a "gcc -O0 -DPG_FORCE_DISABLE_INLINE=1" animal, since the
Solaris machine time supply is small.
The policy would then be
(already is?) to wrap in "#ifdef FRONTEND" any inline function that uses a
backend symbol. When a header is dedicated to such functions, we might avoid
the whole header in the frontend instead of wrapping each function. That
policy works for me.Cool. I was wondering before where we'd document policy around
this. sources.sgml?
+1. Most coding rules go undocumented, but I'm in favor of changing that as
the opportunity arises.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Fri, Aug 14, 2015 at 08:40:13PM +0200, Andres Freund wrote:
On 2015-08-06 12:29:15 -0300, Alvaro Herrera wrote:
+ * lockdefs.h + * Frontend exposed parts of postgres' low level lock mechanism
I actually think the split came out to work far better than I'd
anticipated. Having a slimmed-down version of lock.h for code that just
needs to declare/pass lockmode parameters seems to improve our layering
considerably. I got round to Alvaro's and Roberts position that
removing lock.h from namespace.h and heapam.h would be a really nice
improvemen on that front.
I assessed 0001-WIP-Decrease-usage-of-lock.h-further.patch and reassessed
0001-Don-t-include-low-level-locking-code-from-frontend-c.patch (commit
4eda0a6). I changed the details of my position compared to my last review.
As we see from the patches' need to add #include statements to .c files and
from Robert's report of a broken EDB build, this change creates work for
maintainers of non-core code, both backend code (modules) and frontend code
(undocumented, but folks do it). That's to be expected and doesn't take a
great deal of justification, but users should get benefits in connection with
the work. This brings to mind the htup_details.h introduction, which created
so much busy work in non-core code. I don't expect the lock.h split to be
quite that disruptive. Statistics on PGXN modules:
29 modules mention htup_details.h
8 modules mention lwlock.h
7 modules mention LWLock
4 modules mention lock.h
1 module mentions LockAcquire()
Four modules (imcs, pg_stat_kcache, query_histogram, query_recorder) mentioned
LWLock without mentioning lwlock.h. These patches (trivially) break the imcs
build. The other three failed to build for unrelated reasons, but I suspect
these patches give those modules one more thing to update. What do users get
out of this? They'll learn if their code is not portable to pademelon, but
#warning "atomics.h in frontend code is not portable" would communicate the
same without compelling non-core code to care. Other than that benefit,
making headers #error-on-FRONTEND mostly lets us congratulate ourselves for
having introduced the start of a header layer distinction. I'd be for that if
PostgreSQL were new, but I can't justify doing it at the user cost already
apparent. That would be bad business.
Therefore, I urge you to instead add the aforementioned #warning and wrap with
#ifdef FRONTEND the two #include "port/atomics.h" in headers. That tightly
limits build breakage; it can only break frontend code, which is rare outside
core. Hackers will surely notice if a patch makes the warning bleat, so
mistakes won't survive long. Non-core frontend code, if willing to cede a
shred of portability, can experiment with atomics. Folks could do nifty
things with that.
Thanks,
nm
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@anarazel.de> writes:
On 2015-08-15 23:50:09 -0400, Noah Misch wrote:
Solaris Studio 12.3 (newest version as of Oct 2014) still does that
when optimization is disabled, and I place sufficient value on keeping
inlining enabled for such a new compiler.
Ah, that's cool. I was wondering generally how we could find an animal
to detect that case once pademelon met its untimely (or timely by now?)
end.
Yeah. If we get to the point where we can't actually find any toolchains
that work that way, it may be time to revise our portability policy. But
for now Solaris Studio is a good-enough reason to not move the goalposts.
The policy would then be
(already is?) to wrap in "#ifdef FRONTEND" any inline function that uses a
backend symbol. When a header is dedicated to such functions, we might avoid
the whole header in the frontend instead of wrapping each function. That
policy works for me.
Works for me as well, as long as we have buildfarm critters that will
notice oversights.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-16 03:31:48 -0400, Noah Misch wrote:
As we see from the patches' need to add #include statements to .c files and
from Robert's report of a broken EDB build, this change creates work for
maintainers of non-core code, both backend code (modules) and frontend code
(undocumented, but folks do it). That's to be expected and doesn't take a
great deal of justification, but users should get benefits in connection with
the work. This brings to mind the htup_details.h introduction, which created
so much busy work in non-core code. I don't expect the lock.h split to be
quite that disruptive. Statistics on PGXN modules:
Four modules (imcs, pg_stat_kcache, query_histogram, query_recorder) mentioned
LWLock without mentioning lwlock.h. These patches (trivially) break the imcs
build. The other three failed to build for unrelated reasons, but I suspect
these patches give those modules one more thing to update. What do users get
out of this? They'll learn if their code is not portable to pademelon, but
#warning "atomics.h in frontend code is not portable" would communicate the
same without compelling non-core code to care.
I'd love to make it a #warning intead of an error, but unfortunately
that's not standard C :(
Other than that benefit, making headers #error-on-FRONTEND mostly lets
us congratulate ourselves for having introduced the start of a header
layer distinction. I'd be for that if PostgreSQL were new, but I
can't justify doing it at the user cost already apparent. That would
be bad business.
To me that's basically saying that we'll never ever have any better
separation between frontend/backend headers since each incremental
improvement won't be justifiable. Adding an explicit include which
exists in all version of postgres is really rather low cost, you don't
even need version dependant define. The modules you name are, as you
noticed, likely to require minor surgery for new major versions anyway,
being rather low level.
As you say breaking C code over major releases doesn't have to meet a
high barrier, and getting rid of the wart of lock.h being used that
widely seems to be more than suffient to meet that qualification.
If others think this is the right way, ok, I can live with that and
implement it, but I won't agree.
Therefore, I urge you to instead add the aforementioned #warning and wrap with
#ifdef FRONTEND the two #include "port/atomics.h" in headers. That tightly
limits build breakage; it can only break frontend code, which is rare outside
core. Hackers will surely notice if a patch makes the warning bleat, so
mistakes won't survive long.
Non-core frontend code, if willing to cede a shred of portability, can
experiment with atomics. Folks could do nifty things with that.
I don't think that's something worth keeping in mind from our side. If
you don't care about portability you can just use C11 atomics or
such.
If somebody actually wants to add FRONTEND support for the fallback code
- possibly falling back to pthread mutexes - ok, but before that...
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Jul 1, 2015 at 11:14 AM, Andres Freund <andres@anarazel.de> wrote:
Hi,
During the 9.5 cycle, and earlier, the topic of increasing our minimum
bar for compilers came up a bunch of times. Specifically whether we
still should continue to use C90 as a baseline.
Minor question: is there any value to keeping the client side code to
older standards? On a previous project compiled libpq on many legacy
architectures because we were using it as frontend to backup software.
The project didn't end up taking off so it's no big deal to me, but
just throwing it out there: libpq has traditionally enjoyed broader
compiler support than the full project (borland, windows back in the
day).
merlin
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Jul 1, 2015 at 5:14 PM, Andres Freund <andres@anarazel.de> wrote:
During the 9.5 cycle, and earlier, the topic of increasing our minimum
bar for compilers came up a bunch of times. Specifically whether we
still should continue to use C90 as a baseline.I think the time has come to rely at least on some newer features.
I don't have much opinion on the topic (aside from "it's nice that we
run on old systems" but that's neither here nor there).
But I'm not clear from the discussion exactly which compilers we're
thinking of ruling out. For GCC are we talking about bumping the
minimum version required or are all current versions of GCC new enough
and we're only talking about old HPUX/Solaris/etc compilers?
--
greg
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-17 15:51:33 +0100, Greg Stark wrote:
But I'm not clear from the discussion exactly which compilers we're
thinking of ruling out.
None.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Sat, Aug 15, 2015 at 8:03 PM, Andres Freund <andres@anarazel.de> wrote:
That gave me new respect for STATIC_IF_INLINE. While it does add tedious work
to the task of introducing a new batch of inline functions, the work is
completely mechanical. Anyone can write it; anyone can review it; there's one
correct way to write it.What's the advantage of using STATIC_IF_INLINE over just #ifndef
FRONTEND? That doesn't work well for entire headers in my opinion, but
for individual functions it shouldn't be a problem? In fact we've done
it for years for MemoryContextSwitchTo(). And by the problem definition
such functions cannot be required by frontend code.STATIC_IF_INLINE is really tedious because to know whether it works you
essentially need to recompile postgres with inlines enabled/disabled.In fact STATIC_IF_INLINE does *not* even help here unless we also detect
compilers that support inlining but balk when inline functions reference
symbols not available. There was an example of that in the buildfarm as
of 2014, c.f. a9baeb361d63 . We'd have to disable inlining for such
compilers.
The advantage of STATIC_IF_INLINE is that we had everything working in
that model. We seem to be replacing problems that we had solved and
code that worked on our entire buildfarm with new problems that we
haven't solved yet and which don't seem to be a whole lot simpler than
the ones they replaced.
As far as I can see, the anticipated benefits of what we're doing here are:
- Get a cleaner separation of frontend and backend headers (this could
also be done independently of STATIC_IF_INLINE, but removing
STATIC_IF_INLINE increases the urgency).
- Eliminate multiple evaluations hazards.
- Modest improvements to code generation.
And the costs are:
- Lots of warnings with compilers that are not smart about static
inline, and probably significantly worse code generation.
- The possibility that may repeatedly break #define FRONTEND
compilation when we add static inline functions, where instead adding
macros would not have caused breakage, thus resulting in continual
tinkering with the header files.
What I'm basically worried about is that second one. Actually, what
I'm specifically worried about is that we will break somebody's #ifdef
FRONTEND code, they will eventually complain, and we will refuse to
fix it because we don't think their use case is valid. If that
happens even a few times, it will lead me to think that this whole
effort was misguided. :-(
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-17 12:30:56 -0400, Robert Haas wrote:
- The possibility that may repeatedly break #define FRONTEND
compilation when we add static inline functions, where instead adding
macros would not have caused breakage, thus resulting in continual
tinkering with the header files.
Again, that's really independent. Inlines have that problem, even with
STATIC_IF_INLINE. C.f. MemoryContextSwitch() and a9baeb361d.
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-17 12:30:56 -0400, Robert Haas wrote:
As far as I can see, the anticipated benefits of what we're doing here are:
- Get a cleaner separation of frontend and backend headers (this could
also be done independently of STATIC_IF_INLINE, but removing
STATIC_IF_INLINE increases the urgency).
- Eliminate multiple evaluations hazards.
- Modest improvements to code generation.
Plus:
* Not having 7k long macros, that e.g. need extra flags to even be
supported. C.f. http://archives.postgresql.org/message-id/4407.1435763473%40sss.pgh.pa.us
* Easier development due to actual type checking and such. Compare the
errors from heap_getattr as a macro being passed a boolean with the
same from an inline function: Inline:
/home/andres/src/postgresql/src/backend/executor/spi.c: In function ‘SPI_getvalue’:
/home/andres/src/postgresql/src/backend/executor/spi.c:883:46: error: incompatible type for argument 4 of ‘heap_getattr’
val = heap_getattr(tuple, fnumber, tupdesc, isnull);
^
In file included from /home/andres/src/postgresql/src/backend/executor/spi.c:17:0:
/home/andres/src/postgresql/src/include/access/htup_details.h:765:1: note: expected ‘_Bool *’ but argument is of type ‘_Bool’
heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
^
Macro:
In file included from /home/andres/src/postgresql/src/backend/executor/spi.c:17:0:
/home/andres/src/postgresql/src/backend/executor/spi.c: In function ‘SPI_getvalue’:
/home/andres/src/postgresql/src/include/access/htup_details.h:750:6: error: invalid type argument of unary ‘*’ (have ‘int’)
(*(isnull) = true), \
^
/home/andres/src/postgresql/src/backend/executor/spi.c:883:8: note: in expansion of macro ‘heap_getattr’
val = heap_getattr(tuple, fnumber, tupdesc, isnull);
^
/home/andres/src/postgresql/src/include/access/htup_details.h:750:23: warning: left-hand operand of comma expression has no effect [-Wunused-value]
(*(isnull) = true), \
^
/home/andres/src/postgresql/src/backend/executor/spi.c:883:8: note: in expansion of macro ‘heap_getattr’
val = heap_getattr(tuple, fnumber, tupdesc, isnull);
^
/home/andres/src/postgresql/src/include/access/htup_details.h:697:3: error: invalid type argument of unary ‘*’ (have ‘int’)
(*(isnull) = false), \
^
/home/andres/src/postgresql/src/include/access/htup_details.h:754:5: note: in expansion of macro ‘fastgetattr’
fastgetattr((tup), (attnum), (tupleDesc), (isnull)) \
^
/home/andres/src/postgresql/src/backend/executor/spi.c:883:8: note: in expansion of macro ‘heap_getattr’
val = heap_getattr(tuple, fnumber, tupdesc, isnull);
^
/home/andres/src/postgresql/src/include/access/htup_details.h:713:5: error: invalid type argument of unary ‘*’ (have ‘int’)
(*(isnull) = true), \
^
/home/andres/src/postgresql/src/include/access/htup_details.h:754:5: note: in expansion of macro ‘fastgetattr’
fastgetattr((tup), (attnum), (tupleDesc), (isnull)) \
^
/home/andres/src/postgresql/src/backend/executor/spi.c:883:8: note: in expansion of macro ‘heap_getattr’
val = heap_getattr(tuple, fnumber, tupdesc, isnull);
^
/home/andres/src/postgresql/src/include/access/htup_details.h:713:22: warning: left-hand operand of comma expression has no effect [-Wunused-value]
(*(isnull) = true), \
^
/home/andres/src/postgresql/src/include/access/htup_details.h:754:5: note: in expansion of macro ‘fastgetattr’
fastgetattr((tup), (attnum), (tupleDesc), (isnull)) \
^
/home/andres/src/postgresql/src/backend/executor/spi.c:883:8: note: in expansion of macro ‘heap_getattr’
val = heap_getattr(tuple, fnumber, tupdesc, isnull);
^
/home/andres/src/postgresql/src/include/access/htup_details.h:697:21: warning: left-hand operand of comma expression has no effect [-Wunused-value]
(*(isnull) = false), \
^
/home/andres/src/postgresql/src/include/access/htup_details.h:754:5: note: in expansion of macro ‘fastgetattr’
fastgetattr((tup), (attnum), (tupleDesc), (isnull)) \
^
/home/andres/src/postgresql/src/backend/executor/spi.c:883:8: note: in expansion of macro ‘heap_getattr’
val = heap_getattr(tuple, fnumber, tupdesc, isnull);
^
/home/andres/src/postgresql/src/include/access/htup_details.h:757:50: warning: passing argument 4 of ‘heap_getsysattr’ makes pointer from integer without a cast [-Wint-conversion]
heap_getsysattr((tup), (attnum), (tupleDesc), (isnull)) \
^
/home/andres/src/postgresql/src/backend/executor/spi.c:883:8: note: in expansion of macro ‘heap_getattr’
val = heap_getattr(tuple, fnumber, tupdesc, isnull);
^
/home/andres/src/postgresql/src/include/access/htup_details.h:771:14: note: expected ‘bool * {aka char *}’ but argument is of type ‘bool {aka char}’
extern Datum heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
^
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Mon, Aug 17, 2015 at 12:36 PM, Andres Freund <andres@anarazel.de> wrote:
On 2015-08-17 12:30:56 -0400, Robert Haas wrote:
- The possibility that may repeatedly break #define FRONTEND
compilation when we add static inline functions, where instead adding
macros would not have caused breakage, thus resulting in continual
tinkering with the header files.Again, that's really independent. Inlines have that problem, even with
STATIC_IF_INLINE. C.f. MemoryContextSwitch() and a9baeb361d.
Inlines, yes, but macros don't.
I'm not saying we shouldn't do this, but I *am* saying that we need to
be prepared to treat breaking FRONTEND compilation as a problem, not
just today and tomorrow, but way off into the future. It's not at all
a stretch to think that we could still be hitting fallout from these
changes in 2-3 years time.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Mon, Aug 17, 2015 at 12:06:42PM +0200, Andres Freund wrote:
On 2015-08-16 03:31:48 -0400, Noah Misch wrote:
I'd love to make it a #warning intead of an error, but unfortunately
that's not standard C :(
Okay.
Other than that benefit, making headers #error-on-FRONTEND mostly lets
us congratulate ourselves for having introduced the start of a header
layer distinction. I'd be for that if PostgreSQL were new, but I
can't justify doing it at the user cost already apparent. That would
be bad business.To me that's basically saying that we'll never ever have any better
separation between frontend/backend headers since each incremental
improvement won't be justifiable.
Exactly. This is one of those proposals that can never repay its costs.
Header refactoring seduces hackers, but the benefits don't materialize.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-16 05:58:17 +0200, Andres Freund wrote:
On 2015-08-15 23:50:09 -0400, Noah Misch wrote:
The policy would then be
(already is?) to wrap in "#ifdef FRONTEND" any inline function that uses a
backend symbol. When a header is dedicated to such functions, we might avoid
the whole header in the frontend instead of wrapping each function. That
policy works for me.Cool. I was wondering before where we'd document policy around
this. sources.sgml?
As Noah I think it'd be good if we, over time, started to document a few
more things one currently have to pick up over time. I'm wondering
whether these should be subsections under a new sect1 ('Code Structure'?
Don't like that much), or all independent sect1s.
Stuff I'd like to see documented there over time includes:
1) Definition of the standard that we require, i.e. for now C89.
2) error handling with setjmp, specifically that and when volatile has
to be used.
3) Signal handlers, and what you can/cannod do.
4) That we rely on 4 byte aligned single-copy atomicity (i.e. some
recent value is read, not a mixture of two), but that we do not realy
on atomic 8 byte writes/reads.
The WIP patch I have on C89 and static inline is:
<sect1 id="source-structure">
<title>Structure</title>
<simplesect>
<title>C Standard</title>
<para>
Code in <productname>PostgreSQL</> should only rely on language
features available in the C89 standard. That means a conforming
C89 compiler has to be able to compile postgres. Features from
later revision of the C standard or compiler specific features
can be used, if a fallback is provided.
</para>
<para>
For example <literal>static inline</> and
<literal>_StaticAssert()</literal> are used, even though they are
from newer revisions of the C standard. If not available we
respectively fall back to defining the functions without inline,
and to using a C89 compatible replacement that also emits errors,
but emits far less readable errors.
</para>
</simplesect>
<simplesect>
<title>Function-Like Macros and Inline Functions</title>
<para>
Both, macros with arguments and <literal>static inline</>
functions, may be used. The latter are preferrable if there are
multiple-evaluation hazards when written as a macro, as e.g. the
case with
<programlisting>
#define Max(x, y) ((x) > (y) ? (x) : (y))
</programlisting>
or when the macro would be very long. In other cases it's only
possible to use macros, or at least easier. For example because
expressions of various types need to be passed to the macro.
</para>
<para>
When defining an inline function in a header that references
symbols (i.e. variables, functions) that are only available as
part of the backend, the function may not be visible when included
from frontend code.
<programlisting>
#ifndef FRONTEND
static inline MemoryContext
MemoryContextSwitchTo(MemoryContext context)
{
MemoryContext old = CurrentMemoryContext;
CurrentMemoryContext = context;
return old;
}
#endif /* FRONTEND */
</programlisting>
In this example <literal>CurrentMemoryContext</>, which is only
available in the backend, is referenced and the function thus
hidden with a <literal>#ifndef FRONTEND</literal>. This rule
exists because some compilers emit references to symbols
contained in inline functions even if the function is not used.
</para>
</simplesect>
</sect1>
That's not yet perfect, but shows what I'm thinking of. Comments?
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@anarazel.de> writes:
As Noah I think it'd be good if we, over time, started to document a few
more things one currently have to pick up over time. I'm wondering
whether these should be subsections under a new sect1 ('Code Structure'?
Don't like that much), or all independent sect1s.
"Structure" is certainly not what this material is. Maybe "Miscellaneous
Coding Conventions" is the best we can do for a title. The items seem too
short to be their own <sect1>'s.
That's not yet perfect, but shows what I'm thinking of. Comments?
Needs a bit of copy-editing in places, but +1 overall.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Thu, Aug 27, 2015 at 4:31 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
That's not yet perfect, but shows what I'm thinking of. Comments?
Needs a bit of copy-editing in places, but +1 overall.
Yeah. I bet there's a lot more useful stuff we could include also,
but everything Andres mentioned is certainly good to put in there.
Alternatively, some of this stuff could go into a README file instead
of the documentation, but I think we've been leaning toward
documenting more C stuff lately, and I'm fine with that.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Robert Haas <robertmhaas@gmail.com> writes:
Yeah. I bet there's a lot more useful stuff we could include also,
but everything Andres mentioned is certainly good to put in there.
Alternatively, some of this stuff could go into a README file instead
of the documentation, but I think we've been leaning toward
documenting more C stuff lately, and I'm fine with that.
I think we've mostly used READMEs for documentation that's relevant to
particular subparts of the source tree, eg, planner, nbtree, etc. Stuff
like this would only make sense if you put it in a top-level README, which
is a file that contains user-facing info in most projects including ours.
So I think sticking it into some portion of Part VII (Internals) is the
right approach.
It strikes me that the information in backend/utils/mmgr/README would be
a good candidate to move into the Internals SGML, too. Almost none of
that is "stuff you only care about when reading utils/mmgr/".
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Tom Lane wrote:
It strikes me that the information in backend/utils/mmgr/README would be
a good candidate to move into the Internals SGML, too. Almost none of
that is "stuff you only care about when reading utils/mmgr/".
Completely agreed.
--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Thu, Aug 27, 2015 at 11:31:44AM -0400, Tom Lane wrote:
Andres Freund <andres@anarazel.de> writes:
As Noah I think it'd be good if we, over time, started to document a few
more things one currently have to pick up over time. I'm wondering
whether these should be subsections under a new sect1 ('Code Structure'?
Don't like that much), or all independent sect1s."Structure" is certainly not what this material is. Maybe "Miscellaneous
Coding Conventions" is the best we can do for a title. The items seem too
short to be their own <sect1>'s.
"C Language Features" comes to mind. I assume we're talking about names for a
<sect1> inside <chapter id="source">.
That's not yet perfect, but shows what I'm thinking of. Comments?
Needs a bit of copy-editing in places, but +1 overall.
+1
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Aug 5, 2015 at 03:46:36PM +0200, Andres Freund wrote:
On 2015-08-05 15:08:29 +0200, Andres Freund wrote:
We might later want to change some of the harder to maintain macros to
inline functions, but that seems better done separately.Here's a conversion for fastgetattr() and heap_getattr(). Not only is
the resulting code significantly more readable, but the conversion also
shrinks the code size:
Hey, the fastgetattr() macro was a work of art! ;-) (And more of my
hacks disappear.)
--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com
+ Everyone has their own god. +
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Aug 12, 2015 at 04:47:55PM -0400, Robert Haas wrote:
On Wed, Aug 12, 2015 at 4:34 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
Andres didn't mention how big the performance benefit he saw with pgbench
was, but I bet it was barely distinguishible from noise. But that's OK. In
fact, there's no reason to believe this would make any difference to
performance. The point is to make the code more readable, and it certainly
achieves that.I think that when Bruce macro-ized this ten years ago or whenever it
was, he got a significant performance benefit from it; otherwise I
don't think he would have done it.
(You over-estimate me. ;-) )
What happened is that I was looking at call graph counts and
fastgetattr() was called a bazillion times, so I inlined it, and saw a
noticeably performance improvement, maybe 2% on an in-memory
SELECT-only workload. Same with a few other macros I created in those
early years.
Frankly, my hacks last a lot longer than I expected. (Did someone say
pg_upgrade. :-) )
--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com
+ Everyone has their own god. +
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Aug 12, 2015 at 10:40:53PM +0200, Andres Freund wrote:
You might argue that it's nothing we have touched frequently. And you're
right. But I think that's a mistake. We spend far too much time in the
various pieces of code dissembling tuples, and I think at some point
somebody really needs to spend time on this.
Yes, this will need to be addressed some day --- I have heard rumors
that we use more CPU than some proprietary relational database for the
same workload. Interestingly, we are not necessary slower, just consume
more CPU, causing us to max out the CPU sooner.
--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com
+ Everyone has their own god. +
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2015-08-27 11:31:44 -0400, Tom Lane wrote:
Needs a bit of copy-editing in places, but +1 overall.
Heres a slightly expanded version of this. I tried to do some of the
copy-editing, but I'm sure a look from a native speaker won't hurt.
Greetings,
Andres Freund
Attachments:
sources.difftext/x-diff; charset=us-asciiDownload
diff --git a/doc/src/sgml/sources.sgml b/doc/src/sgml/sources.sgml
index d6461ec..66a4629 100644
--- a/doc/src/sgml/sources.sgml
+++ b/doc/src/sgml/sources.sgml
@@ -851,4 +851,109 @@ BETTER: unrecognized node type: 42
</sect1>
+ <sect1 id="source-structure">
+ <title>Miscellaneous Coding Conventions</title>
+
+ <simplesect>
+ <title>C Standard</title>
+ <para>
+ Code in <productname>PostgreSQL</> should only rely on language
+ features available in the C89 standard. That means a conforming
+ C89 compiler has to be able to compile postgres, at least aside
+ from a few platform dependant pieces. Features from later
+ revision of the C standard or compiler specific features can be
+ used, if a fallback is provided.
+ </para>
+ <para>
+ For example <literal>static inline</> and
+ <literal>_StaticAssert()</literal> are currently used, even
+ though they are from newer revisions of the C standard. If not
+ available we respectively fall back to defining the functions
+ without inline, and to using a C89 compatible replacement that
+ performs the same checks, but emits rather cryptic messages.
+ </para>
+ </simplesect>
+
+ <simplesect>
+ <title>Function-Like Macros and Inline Functions</title>
+ <para>
+ Both, macros with arguments and <literal>static inline</>
+ functions, may be used. The latter are preferable if there are
+ multiple-evaluation hazards when written as a macro, as e.g. the
+ case with
+<programlisting>
+#define Max(x, y) ((x) > (y) ? (x) : (y))
+</programlisting>
+ or when the macro would be very long. In other cases it's only
+ possible to use macros, or at least easier. For example because
+ expressions of various types need to be passed to the macro.
+ </para>
+ <para>
+ When the definition an inline function references symbols
+ (i.e. variables, functions) that are only available as part of the
+ backend, the function may not be visible when included from frontend
+ code.
+<programlisting>
+#ifndef FRONTEND
+static inline MemoryContext
+MemoryContextSwitchTo(MemoryContext context)
+{
+ MemoryContext old = CurrentMemoryContext;
+
+ CurrentMemoryContext = context;
+ return old;
+}
+#endif /* FRONTEND */
+</programlisting>
+ In this example <literal>CurrentMemoryContext</>, which is only
+ available in the backend, is referenced and the function thus
+ hidden with a <literal>#ifndef FRONTEND</literal>. This rule
+ exists because some compilers emit references to symbols
+ contained in inline functions even if the function is not used.
+ </para>
+ </simplesect>
+
+ <simplesect>
+ <title>Writing Signal Handlers</title>
+ <para>
+ To be suitable to run inside a signal handler code has to be
+ written very carefully. The fundamental problem is that, unless
+ blocked, a signal handler can interrupt code at any time. If code
+ inside the signal handler uses the same state as code outside
+ chaos may ensue. As an example consider what happens if a signal
+ handler tries to acquire a lock that's already held in the
+ interrupted code.
+ </para>
+ <para>
+ Barring special arrangements code in signal handlers may only
+ call async-signal safe functions (as defined in posix) and access
+ variables of type <literal>volatile sig_atomic_t</literal>. A few
+ functions in postgres are also deemed signal safe, importantly
+ <literal>SetLatch()</literal>.
+ </para>
+ <para>
+ In most cases signal handlers should do nothing more than note
+ that a signal has arrived, and wake up code running outside of
+ the handler using a latch. An example of such a handler is the
+ following:
+<programlisting>
+static void
+handle_sighup(SIGNAL_ARGS)
+{
+ int save_errno = errno;
+
+ got_SIGHUP = true;
+ SetLatch(MyLatch);
+
+ errno = save_errno;
+}
+</programlisting>
+ <literal>errno</> is safed and restored because
+ <literal>SetLatch()</> might change it. If that were not done
+ interrupted code that's currently inspecting errno might see the wrong
+ value.
+ </para>
+ </simplesect>
+
+ </sect1>
</chapter>