Hi, Back in commit 4f658dc8 we gained src/port/fls.c. As anticipated by its commit message, we later finished up with something better in src/include/port/pg_bitutils.h. fls() ("find last set") is an off-by-one cousin of pg_leftmost_one_pos32(). I don't know why ffs() ("find first set", the rightmost variant) made it into POSIX while fls() did not, other than perhaps its more amusing name. fls() is present on *BSD, Macs and maybe more, but not everywhere, hence the configure test. Let's just do it with pg_bitutils.h instead, and drop some cruft? Open to better ideas on whether we need a new function, or there is some way to use the existing facilities directly without worrying about undefined behaviour for 0, etc.
Noticed while looking for configure stuff to cull. Mentioning separately because this isn't a simple no-longer-needed-crutch-for-prestandard-system case like the others in a nearby thread.
From 0260f65533bfdff024c5af6c0b14692484305b06 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] Remove replacement 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. --- configure | 13 ------ configure.ac | 1 - src/backend/access/hash/hashutil.c | 2 +- src/backend/optimizer/path/allpaths.c | 4 +- src/backend/optimizer/prep/prepunion.c | 2 +- src/backend/utils/mmgr/dsa.c | 3 +- src/include/pg_config.h.in | 3 -- src/include/port.h | 4 -- src/include/port/pg_bitutils.h | 15 ++++++ src/port/fls.c | 64 -------------------------- src/tools/msvc/Mkvcbuild.pm | 2 +- src/tools/msvc/Solution.pm | 1 - 12 files changed, 22 insertions(+), 92 deletions(-) delete mode 100644 src/port/fls.c diff --git a/configure b/configure index a4f4d321fb..4db38683e5 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 5bd29a4d2f..b826823e50 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..856462b641 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_fls(new_bucket) - 1)) - 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 358bb2aed6..6f19721751 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1491,7 +1491,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_fls(list_length(live_childrels))); parallel_workers = Min(parallel_workers, max_parallel_workers_per_gather); } @@ -1542,7 +1542,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_fls(list_length(live_childrels))); 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 f004fad1d9..3af7b55e7d 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -668,7 +668,7 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root, if (enable_parallel_append) { parallel_workers = Max(parallel_workers, - fls(list_length(partial_pathlist))); + pg_fls(list_length(partial_pathlist))); 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..80e92d80f3 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,7 @@ 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) +#define contiguous_pages_to_segment_bin(n) Min(pg_fls(n), 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/include/port/pg_bitutils.h b/src/include/port/pg_bitutils.h index 04e58cd1c4..209e5f68d0 100644 --- a/src/include/port/pg_bitutils.h +++ b/src/include/port/pg_bitutils.h @@ -247,6 +247,21 @@ pg_ceil_log2_64(uint64 num) return pg_leftmost_one_pos64(num - 1) + 1; } +/* + * Like pg_leftmost_one_pos32(), except that the least significant bit is + * called 1, not 0. This means that 0 can be accepted as an input, returning + * 0. This function is traditionally known as fls() on BSD-derived systems, + * but was not standardized. + */ +static inline int +pg_fls(int num) +{ + if (num == 0) + return 0; + else + return pg_leftmost_one_pos32(num) + 1; +} + /* * With MSVC on x86_64 builds, try using native popcnt instructions via the * __popcnt and __popcnt64 intrinsics. These don't work the same as GCC's 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 e4feda10fd..78adb9770a 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 getpeereid.c getrusage.c inet_aton.c + chklocale.c explicit_bzero.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 dirent.c dlopen.c getopt.c getopt_long.c link.c diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 1e125aef94..1d23573d66 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 => undef, - HAVE_FLS => undef, HAVE_FSEEKO => 1, HAVE_FUNCNAME__FUNC => undef, HAVE_FUNCNAME__FUNCTION => 1, -- 2.36.1