On Thu, Jul 21, 2022 at 1:34 AM Tom Lane <t...@sss.pgh.pa.us> wrote: > How is it sane to ask for a segment bin for zero pages? Seems like > something should have short-circuited such a case well before here.
It's intended. There are two ways you can arrive here with n == 0: * There's a special case in execParallel.c that creates a DSA segment "in-place" with initial size dsa_minimum_size(). That's because we don't know yet if we have any executor nodes that need a DSA segment (Parallel Hash, Parallel Bitmap Heap Scan), so we create one with the minimum amount of space other than the DSA control meta-data, so you get an in-place segment 0 with 0 usable pages. As soon as someone tries to allocate one byte, the first external DSM segment will be created. * A full segment can be re-binned into slot 0. On Thu, Jul 21, 2022 at 1:48 AM Tom Lane <t...@sss.pgh.pa.us> wrote: > Seems like passing a size_t to pg_leftmost_one_pos32 isn't great. > It was just as wrong before (if the caller-supplied argument is > indeed a size_t), but no time like the present to fix it. > > We could have pg_bitutils.h #define pg_leftmost_one_pos_size_t > as the appropriate one of pg_leftmost_one_pos32/64, perhaps. Yeah.
From e2b8448932ec7606c61dd847c3370ae9c31d23e9 Mon Sep 17 00:00:00 2001 From: Thomas Munro <thomas.mu...@gmail.com> Date: Thu, 21 Jul 2022 18:07:45 +1200 Subject: [PATCH v3 1/2] Extend size_t support in pg_bitutils.h. Use a more compact notation that allows us to add more size_t variants as required. This will be used by a later commit. Reviewed-by: Tom Lane <t...@sss.pgh.pa.us> Discussion: https://postgr.es/m/CA%2BhUKG%2B7dSX1XF8yFGmYk-%3D48dbjH2kmzZj16XvhbrWP-9BzRg%40mail.gmail.com --- src/include/port/pg_bitutils.h | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/include/port/pg_bitutils.h b/src/include/port/pg_bitutils.h index 04e58cd1c4..814e0b2dba 100644 --- a/src/include/port/pg_bitutils.h +++ b/src/include/port/pg_bitutils.h @@ -175,16 +175,6 @@ pg_nextpower2_64(uint64 num) return ((uint64) 1) << (pg_leftmost_one_pos64(num) + 1); } -/* - * pg_nextpower2_size_t - * Returns the next higher power of 2 above 'num', for a size_t input. - */ -#if SIZEOF_SIZE_T == 4 -#define pg_nextpower2_size_t(num) pg_nextpower2_32(num) -#else -#define pg_nextpower2_size_t(num) pg_nextpower2_64(num) -#endif - /* * pg_prevpower2_32 * Returns the next lower power of 2 below 'num', or 'num' if it's @@ -211,16 +201,6 @@ pg_prevpower2_64(uint64 num) return ((uint64) 1) << pg_leftmost_one_pos64(num); } -/* - * pg_prevpower2_size_t - * Returns the next lower power of 2 below 'num', for a size_t input. - */ -#if SIZEOF_SIZE_T == 4 -#define pg_prevpower2_size_t(num) pg_prevpower2_32(num) -#else -#define pg_prevpower2_size_t(num) pg_prevpower2_64(num) -#endif - /* * pg_ceil_log2_32 * Returns equivalent of ceil(log2(num)) @@ -299,4 +279,16 @@ pg_rotate_left32(uint32 word, int n) return (word << n) | (word >> (32 - n)); } +/* size_t variants of the above, as required */ + +#if SIZEOF_SIZE_T == 4 +#define pg_leftmost_one_pos_size_t pg_leftmost_one_pos32 +#define pg_nextpower2_size_t pg_nextpower2_32 +#define pg_prevpower2_size_t pg_prevpower2_32 +#else +#define pg_leftmost_one_pos_size_t pg_leftmost_one_pos64 +#define pg_nextpower2_size_t pg_nextpower2_64 +#define pg_prevpower2_size_t pg_prevpower2_64 +#endif + #endif /* PG_BITUTILS_H */ -- 2.36.1
From ad854c0b7fa88a12ec957f9b5bef9b0510e424ac Mon Sep 17 00:00:00 2001 From: Thomas Munro <thomas.mu...@gmail.com> Date: Tue, 19 Jul 2022 17:47:10 +1200 Subject: [PATCH v3 2/2] Remove fls function. Commit 4f658dc8 provided the traditional BSD fls() function so it could be used in several places. Later we added a bunch of similar sorts of things in pg_bitutils.h. Let's drop fls.c and the configure probe, and reuse the newer code. Reviewed-by: David Rowley <dgrowle...@gmail.com> Reviewed-by: Tom Lane <t...@sss.pgh.pa.us> Discussion: https://postgr.es/m/CA%2BhUKG%2B7dSX1XF8yFGmYk-%3D48dbjH2kmzZj16XvhbrWP-9BzRg%40mail.gmail.com --- configure | 13 ------ configure.ac | 1 - src/backend/access/hash/hashutil.c | 2 +- src/backend/optimizer/path/allpaths.c | 5 +- src/backend/optimizer/prep/prepunion.c | 2 +- src/backend/utils/mmgr/dsa.c | 14 +++++- src/include/pg_config.h.in | 3 -- src/include/port.h | 4 -- src/port/fls.c | 64 -------------------------- src/tools/msvc/Mkvcbuild.pm | 2 +- src/tools/msvc/Solution.pm | 1 - 11 files changed, 19 insertions(+), 92 deletions(-) delete mode 100644 src/port/fls.c diff --git a/configure b/configure index 59fa82b8d7..33a425562f 100755 --- a/configure +++ b/configure @@ -16771,19 +16771,6 @@ esac fi -ac_fn_c_check_func "$LINENO" "fls" "ac_cv_func_fls" -if test "x$ac_cv_func_fls" = xyes; then : - $as_echo "#define HAVE_FLS 1" >>confdefs.h - -else - case " $LIBOBJS " in - *" fls.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS fls.$ac_objext" - ;; -esac - -fi - ac_fn_c_check_func "$LINENO" "getopt" "ac_cv_func_getopt" if test "x$ac_cv_func_getopt" = xyes; then : $as_echo "#define HAVE_GETOPT 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index 612dabf698..5295cb5806 100644 --- a/configure.ac +++ b/configure.ac @@ -1911,7 +1911,6 @@ fi AC_REPLACE_FUNCS(m4_normalize([ dlopen explicit_bzero - fls getopt getpeereid getrusage diff --git a/src/backend/access/hash/hashutil.c b/src/backend/access/hash/hashutil.c index fe37bc47cb..32822dbb6b 100644 --- a/src/backend/access/hash/hashutil.c +++ b/src/backend/access/hash/hashutil.c @@ -436,7 +436,7 @@ _hash_get_oldblock_from_newbucket(Relation rel, Bucket new_bucket) * started. Masking the most significant bit of new bucket would give us * old bucket. */ - mask = (((uint32) 1) << (fls(new_bucket) - 1)) - 1; + mask = (((uint32) 1) << pg_leftmost_one_pos32(new_bucket)) - 1; old_bucket = new_bucket & mask; metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_READ, LH_META_PAGE); diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 028d9e1680..63f0f6b79c 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -47,6 +47,7 @@ #include "parser/parsetree.h" #include "partitioning/partbounds.h" #include "partitioning/partprune.h" +#include "port/pg_bitutils.h" #include "rewrite/rewriteManip.h" #include "utils/lsyscache.h" @@ -1491,7 +1492,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, if (enable_parallel_append) { parallel_workers = Max(parallel_workers, - fls(list_length(live_childrels))); + pg_leftmost_one_pos32(list_length(live_childrels)) + 1); parallel_workers = Min(parallel_workers, max_parallel_workers_per_gather); } @@ -1542,7 +1543,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, * the planned number of parallel workers. */ parallel_workers = Max(parallel_workers, - fls(list_length(live_childrels))); + pg_leftmost_one_pos32(list_length(live_childrels)) + 1); parallel_workers = Min(parallel_workers, max_parallel_workers_per_gather); Assert(parallel_workers > 0); diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index 2214920dea..043181b586 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -675,7 +675,7 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root, if (enable_parallel_append) { parallel_workers = Max(parallel_workers, - fls(list_length(partial_pathlist))); + pg_leftmost_one_pos32(list_length(partial_pathlist)) + 1); parallel_workers = Min(parallel_workers, max_parallel_workers_per_gather); } diff --git a/src/backend/utils/mmgr/dsa.c b/src/backend/utils/mmgr/dsa.c index b6cb8fa13d..82376fde2d 100644 --- a/src/backend/utils/mmgr/dsa.c +++ b/src/backend/utils/mmgr/dsa.c @@ -51,6 +51,7 @@ #include "postgres.h" #include "port/atomics.h" +#include "port/pg_bitutils.h" #include "storage/dsm.h" #include "storage/ipc.h" #include "storage/lwlock.h" @@ -137,7 +138,18 @@ typedef size_t dsa_segment_index; * free pages? There is no point in looking in segments in lower bins; they * definitely can't service a request for n free pages. */ -#define contiguous_pages_to_segment_bin(n) Min(fls(n), DSA_NUM_SEGMENT_BINS - 1) +static inline size_t +contiguous_pages_to_segment_bin(size_t n) +{ + size_t bin; + + if (n == 0) + bin = 0; + else + bin = pg_leftmost_one_pos_size_t(n) + 1; + + return Min(bin, DSA_NUM_SEGMENT_BINS - 1); +} /* Macros for access to locks. */ #define DSA_AREA_LOCK(area) (&area->control->lock) diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 529fb84a86..86d0b1941b 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -191,9 +191,6 @@ /* Define to 1 if you have the `fdatasync' function. */ #undef HAVE_FDATASYNC -/* Define to 1 if you have the `fls' function. */ -#undef HAVE_FLS - /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ #undef HAVE_FSEEKO diff --git a/src/include/port.h b/src/include/port.h index e647f62b77..d39b04141f 100644 --- a/src/include/port.h +++ b/src/include/port.h @@ -366,10 +366,6 @@ extern int gettimeofday(struct timeval *tp, struct timezone *tzp); #define pgoff_t off_t #endif -#ifndef HAVE_FLS -extern int fls(int mask); -#endif - #ifndef HAVE_GETPEEREID /* On Windows, Perl might have incompatible definitions of uid_t and gid_t. */ #ifndef PLPERL_HAVE_UID_GID diff --git a/src/port/fls.c b/src/port/fls.c deleted file mode 100644 index 19b4221826..0000000000 --- a/src/port/fls.c +++ /dev/null @@ -1,64 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fls.c - * finds the last (most significant) bit that is set - * - * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group - * - * - * IDENTIFICATION - * src/port/fls.c - * - * This file was taken from FreeBSD to provide an implementation of fls() - * for platforms that lack it. Note that the operating system's version may - * be substantially more efficient than ours, since some platforms have an - * assembly instruction that does exactly this. - * - * The FreeBSD copyright terms follow. - */ - -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "c.h" - -/* - * Find Last Set bit - */ -int -fls(int mask) -{ - int bit; - - if (mask == 0) - return (0); - for (bit = 1; mask != 1; bit++) - mask = (unsigned int) mask >> 1; - return (bit); -} diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm index cc7a908d10..c935f776e5 100644 --- a/src/tools/msvc/Mkvcbuild.pm +++ b/src/tools/msvc/Mkvcbuild.pm @@ -99,7 +99,7 @@ sub mkvcbuild $solution = CreateSolution($vsVersion, $config); our @pgportfiles = qw( - chklocale.c explicit_bzero.c fls.c fdatasync.c + chklocale.c explicit_bzero.c fdatasync.c getpeereid.c getrusage.c inet_aton.c getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 3ddcd024a7..23296527ae 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -258,7 +258,6 @@ sub GenerateFiles HAVE_EXECINFO_H => undef, HAVE_EXPLICIT_BZERO => undef, HAVE_FDATASYNC => 1, - HAVE_FLS => undef, HAVE_FSEEKO => 1, HAVE_FUNCNAME__FUNC => undef, HAVE_FUNCNAME__FUNCTION => 1, -- 2.36.1