diff options
Diffstat (limited to '')
33 files changed, 999 insertions, 105 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 3960a06..52c1861 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -3,10 +3,16 @@ env: ARCH: amd64 task: - freebsd_instance: - matrix: - image: freebsd-12-0-release-amd64 - image: freebsd-11-2-release-amd64 + matrix: + - name: freebsd12-amd64 + freebsd_instance: + image_family: freebsd-12-3-snap + - name: freebsd13-amd64 + freebsd_instance: + image_family: freebsd-13-1-snap + - name: freebsd14-amd64 + freebsd_instance: + image_family: freebsd-14-0-snap script: - cc --version - export CFLAGS="-DITERATE=400 -DPAIRS_S=100 -DITERATIONS=24" diff --git a/.github/workflows/codesee-arch-diagram.yml b/.github/workflows/codesee-arch-diagram.yml new file mode 100644 index 0000000..5b4e581 --- /dev/null +++ b/.github/workflows/codesee-arch-diagram.yml @@ -0,0 +1,81 @@ +on: + push: + branches: + - master + pull_request_target: + types: [opened, synchronize, reopened] + +name: CodeSee Map + +jobs: + test_map_action: + runs-on: ubuntu-latest + continue-on-error: true + name: Run CodeSee Map Analysis + steps: + - name: checkout + id: checkout + uses: actions/checkout@v2 + with: + repository: ${{ github.event.pull_request.head.repo.full_name }} + ref: ${{ github.event.pull_request.head.ref }} + fetch-depth: 0 + + # codesee-detect-languages has an output with id languages. + - name: Detect Languages + id: detect-languages + uses: Codesee-io/codesee-detect-languages-action@latest + + - name: Configure JDK 16 + uses: actions/setup-java@v2 + if: ${{ fromJSON(steps.detect-languages.outputs.languages).java }} + with: + java-version: '16' + distribution: 'zulu' + + # CodeSee Maps Go support uses a static binary so there's no setup step required. + + - name: Configure Node.js 14 + uses: actions/setup-node@v2 + if: ${{ fromJSON(steps.detect-languages.outputs.languages).javascript }} + with: + node-version: '14' + + - name: Configure Python 3.x + uses: actions/setup-python@v2 + if: ${{ fromJSON(steps.detect-languages.outputs.languages).python }} + with: + python-version: '3.x' + architecture: 'x64' + + - name: Configure Ruby '3.x' + uses: ruby/setup-ruby@v1 + if: ${{ fromJSON(steps.detect-languages.outputs.languages).ruby }} + with: + ruby-version: '3.0' + + # CodeSee Maps Rust support uses a static binary so there's no setup step required. + + - name: Generate Map + id: generate-map + uses: Codesee-io/codesee-map-action@latest + with: + step: map + github_ref: ${{ github.ref }} + languages: ${{ steps.detect-languages.outputs.languages }} + + - name: Upload Map + id: upload-map + uses: Codesee-io/codesee-map-action@latest + with: + step: mapUpload + api_token: ${{ secrets.CODESEE_ARCH_DIAG_API_TOKEN }} + github_ref: ${{ github.ref }} + + - name: Insights + id: insights + uses: Codesee-io/codesee-map-action@latest + with: + step: insights + api_token: ${{ secrets.CODESEE_ARCH_DIAG_API_TOKEN }} + github_ref: ${{ github.ref }} diff --git a/Makefile.in b/Makefile.in index 6f17a12..86b62fe 100644 --- a/Makefile.in +++ b/Makefile.in @@ -13,7 +13,7 @@ LDNAME=@LDNAME@ LDNAME_VERSION=@LDNAME_VERSION@ LDNAME_MAJOR=@LDNAME_MAJOR@ -all: doc +all: @EXTRA_BUILD@ $(MAKE) -C src all || exit @echo @echo @@ -34,15 +34,15 @@ check: regressions install-headers: mkdir -p $(DESTDIR)/$(HEADERS) || exit - cp $(SRC_DIR)/include/*.h $(DESTDIR)/$(HEADERS) || exit + cp -p $(SRC_DIR)/include/*.h $(DESTDIR)/$(HEADERS) || exit chmod 644 $(DESTDIR)/$(HEADERS)/ck_*.h || exit mkdir -p $(DESTDIR)/$(HEADERS)/gcc || exit cp -r $(SRC_DIR)/include/gcc/* $(DESTDIR)/$(HEADERS)/gcc || exit - cp include/ck_md.h $(DESTDIR)/$(HEADERS)/ck_md.h || exit + cp -p include/ck_md.h $(DESTDIR)/$(HEADERS)/ck_md.h || exit chmod 755 $(DESTDIR)/$(HEADERS)/gcc chmod 644 $(DESTDIR)/$(HEADERS)/gcc/ck_*.h $(DESTDIR)/$(HEADERS)/gcc/*/ck_*.h || exit mkdir -p $(DESTDIR)/$(HEADERS)/spinlock || exit - cp -r $(SRC_DIR)/include/spinlock/* $(DESTDIR)/$(HEADERS)/spinlock || exit + cp -pr $(SRC_DIR)/include/spinlock/* $(DESTDIR)/$(HEADERS)/spinlock || exit chmod 755 $(DESTDIR)/$(HEADERS)/spinlock chmod 644 $(DESTDIR)/$(HEADERS)/spinlock/*.h || exit @@ -51,7 +51,7 @@ install-so: cp src/libck.so $(DESTDIR)/$(LIBRARY)/$(LDNAME_VERSION) ln -sf $(LDNAME_VERSION) $(DESTDIR)/$(LIBRARY)/$(LDNAME) ln -sf $(LDNAME_VERSION) $(DESTDIR)/$(LIBRARY)/$(LDNAME_MAJOR) - chmod 744 $(DESTDIR)/$(LIBRARY)/$(LDNAME_VERSION) \ + chmod 755 $(DESTDIR)/$(LIBRARY)/$(LDNAME_VERSION) \ $(DESTDIR)/$(LIBRARY)/$(LDNAME) \ $(DESTDIR)/$(LIBRARY)/$(LDNAME_MAJOR) @@ -65,7 +65,7 @@ install: all install-headers @INSTALL_LIBS@ mkdir -p $(DESTDIR)/$(LIBRARY) || exit mkdir -p $(DESTDIR)/$(PKGCONFIG_DATA) || exit chmod 755 $(DESTDIR)/$(PKGCONFIG_DATA) - cp build/ck.pc $(DESTDIR)/$(PKGCONFIG_DATA)/ck.pc || exit + cp -p build/ck.pc $(DESTDIR)/$(PKGCONFIG_DATA)/ck.pc || exit @echo @echo @echo ---[ Concurrency Kit has installed successfully. @@ -39,6 +39,7 @@ Concurrency Kit has specialized assembly for the following architectures: * `arm` * `ppc` * `ppc64` + * `riscv64` * `s390x` * `sparcv9+` * `x86` diff --git a/build/ck.build.riscv32 b/build/ck.build.riscv32 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/build/ck.build.riscv32 diff --git a/build/ck.build.riscv64 b/build/ck.build.riscv64 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/build/ck.build.riscv64 diff --git a/build/ck.build.x86 b/build/ck.build.x86 index 6e12783..4d07fa4 100644 --- a/build/ck.build.x86 +++ b/build/ck.build.x86 @@ -1,2 +1,2 @@ -CFLAGS+=-m32 -D__x86__ -msse -msse2 +CFLAGS+=-m32 -D__x86__ LDFLAGS+=-m32 @@ -32,15 +32,16 @@ EXIT_SUCCESS=0 EXIT_FAILURE=1 WANT_PIC=yes -P_PWD=`pwd` +BUILD_DIR=`pwd` MAINTAINER='sbahra@repnop.org' -VERSION=${VERSION:-'0.7.1'} +VERSION=${VERSION:-'0.7.2'} VERSION_MAJOR='0' BUILD="$PWD/build/ck.build" PREFIX=${PREFIX:-"/usr/local"} LDNAME="libck.so" LDNAME_VERSION="libck.so.$VERSION" LDNAME_MAJOR="libck.so.$VERSION_MAJOR" +EXTRA_BUILD='doc' OPTION_CHECKING=1 @@ -119,6 +120,7 @@ generate() -e "s#@GZIP_SUFFIX@#$GZIP_SUFFIX#g" \ -e "s#@POINTER_PACK_ENABLE@#$POINTER_PACK_ENABLE#g" \ -e "s#@DISABLE_DOUBLE@#$DISABLE_DOUBLE#g" \ + -e "s#@DISABLE_SHARED@#$DISABLE_SHARED#g" \ -e "s#@DISABLE_STATIC@#$DISABLE_STATIC#g" \ -e "s#@SSE_DISABLE@#$SSE_DISABLE#g" \ -e "s#@PPC32_LWSYNC_ENABLE@#$PPC32_LWSYNC_ENABLE#g" \ @@ -127,13 +129,14 @@ generate() -e "s#@VMA_BITS@#$VMA_BITS_R#g" \ -e "s#@VMA_BITS_VALUE@#$VMA_BITS_VALUE_R#g" \ -e "s#@MM@#$MM#g" \ - -e "s#@BUILD_DIR@#$P_PWD#g" \ - -e "s#@SRC_DIR@#$BUILD_DIR#g" \ + -e "s#@BUILD_DIR@#$BUILD_DIR#g" \ + -e "s#@SRC_DIR@#$SRC_DIR#g" \ -e "s#@LDNAME@#$LDNAME#g" \ -e "s#@LDNAME_MAJOR@#$LDNAME_MAJOR#g" \ -e "s#@LDNAME_VERSION@#$LDNAME_VERSION#g" \ -e "s#@PC_CFLAGS@#$PC_CFLAGS#g" \ -e "s#@GIT_SHA@#$GIT_SHA#g" \ + -e "s#@EXTRA_BUILD@#$EXTRA_BUILD#g" \ $1 > $2 } @@ -143,8 +146,8 @@ generate_stdout() echo echo " VERSION = $VERSION" echo " GIT_SHA = $GIT_SHA" - echo " BUILD_DIR = $P_PWD" - echo " SRC_DIR = $BUILD_DIR" + echo " BUILD_DIR = $BUILD_DIR" + echo " SRC_DIR = $SRC_DIR" echo " SYSTEM = $SYSTEM" echo " PROFILE = $PROFILE" echo " AR = $AR" @@ -157,7 +160,9 @@ generate_stdout() echo " LDNAME_VERSION = $LDNAME_VERSION" echo " LDNAME_MAJOR = $LDNAME_MAJOR" echo " LDFLAGS = $LDFLAGS" - echo " STATIC_LIB = $DISABLE_STATIC" + echo " SHARED_LIB = `expr $DISABLE_SHARED = 0`" + echo " STATIC_LIB = `expr $DISABLE_STATIC = 0`" + echo " EXTRA_BUILD = $EXTRA_BUILD" echo " GZIP = $GZIP" echo " CORES = $CORES" echo " POINTER_PACK = $POINTER_PACK_ENABLE" @@ -175,14 +180,14 @@ generate_stdout() for option; do case "$option" in - *=?*) + --*=?*) optname=`echo $option|cut -c 3-` value=`expr "$optname" : '[^=]*=\(.*\)'` ;; - *=) + --*=) value= ;; - *) + --*) value=yes ;; esac @@ -296,6 +301,9 @@ for option; do --disable-double) DISABLE_DOUBLE="CK_PR_DISABLE_DOUBLE" ;; + --disable-shared) + DISABLE_SHARED=1 + ;; --disable-static) DISABLE_STATIC=1 ;; @@ -305,7 +313,7 @@ for option; do --build=*|--host=*|--target=*|--exec-prefix=*|--bindir=*|--sbindir=*|\ --sysconfdir=*|--datadir=*|--libexecdir=*|--localstatedir=*|\ --enable-static|\ - --sharedstatedir=*|--infodir=*|--enable-shared|--disable-shared|\ + --sharedstatedir=*|--infodir=*|--enable-shared|\ --cache-file=*|--srcdir=*) # ignore for compat with regular configure ;; @@ -317,8 +325,8 @@ for option; do fi ;; *=*) - optname=`echo $option|cut -c 3-` - NAME=`expr "$optname" : '\([^=]*\)='` + value=`echo $option|cut -d '=' -f 2-` + NAME=`expr "$option" : '\([^=]*\)='` eval "$NAME='$value'" export $NAME ;; @@ -336,6 +344,7 @@ MANDIR=${MANDIR:-"${PREFIX}/share/man"} GZIP=${GZIP-"gzip -c"} POINTER_PACK_ENABLE=${POINTER_PACK_ENABLE:-"CK_MD_POINTER_PACK_DISABLE"} DISABLE_DOUBLE=${DISABLE_DOUBLE:-"CK_PR_ENABLE_DOUBLE"} +DISABLE_SHARED=${DISABLE_SHARED:-"0"} DISABLE_STATIC=${DISABLE_STATIC:-"0"} PPC32_LWSYNC_ENABLE=${PPC32_LWSYNC_ENABLE:-"CK_MD_PPC32_LWSYNC_DISABLE"} RTM_ENABLE=${RTM_ENABLE_SET:-"CK_MD_RTM_DISABLE"} @@ -424,6 +433,9 @@ case $PLATFORM in LDFLAGS="-m64 $LDFLAGS" ;; i386|i486|i586|i686|i586_i686|pentium*|athlon*|k5|k6|k6_2|k6_3) + if test "${SSE_DISABLE}" = "CK_MD_SSE_ENABLE"; then + CFLAGS="$CFLAGS -msse -msse2" + fi LSE_ENABLE="CK_MD_LSE_DISABLE" MM="${MM:-"CK_MD_TSO"}" case $SYSTEM in @@ -523,6 +535,18 @@ case $PLATFORM in PLATFORM=aarch64 ENVIRONMENT=64 ;; + "riscv32"|"riscv") + RTM_ENABLE="CK_MD_RTM_DISABLE" + MM="${MM:-"CK_MD_RMO"}" + PLATFORM=riscv32 + ENVIRONMENT=32 + ;; + "riscv64") + RTM_ENABLE="CK_MD_RTM_DISABLE" + MM="${MM:-"CK_MD_RMO"}" + PLATFORM=riscv64 + ENVIRONMENT=64 + ;; "s390x") RTM_ENABLE="CK_MD_RTM_DISABLE" LSE_ENABLE="CK_MD_LSE_DISABLE" @@ -551,8 +575,8 @@ else fi if test "$USE_CC_BUILTINS"; then - CFLAGS="$CFLAGS -DCK_CC_BUILTINS" - PC_CFLAGS="-DCK_CC_BULITINS" + CFLAGS="$CFLAGS -DCK_USE_CC_BUILTINS=1" + PC_CFLAGS="-DCK_USE_CC_BUILTINS=1" fi # `which` on Solaris sucks @@ -583,13 +607,13 @@ fi if test -z "$DIRNAME"; then echo "not found (out of source build unsupported)" else - printf "Determining build directory......" + printf "Determining source directory......" - BUILD_DIR=`$DIRNAME $0` + SRC_DIR=`$DIRNAME $0` cd `$DIRNAME $0` - BUILD_DIR=`pwd` + SRC_DIR=`pwd` - echo "success [$BUILD_DIR]" + echo "success [$SRC_DIR]" fi if test -n "$GZIP"; then @@ -716,9 +740,15 @@ elif test "$COMPILER" = "gcc" || test "$COMPILER" = "clang" || test "$COMPILER" LDFLAGS="$LDFLAGS -shared -fPIC" CFLAGS="$CFLAGS -fPIC" - if [ "$DISABLE_STATIC" -eq 1 ]; then + if [ "$DISABLE_SHARED" -eq 1 ] && [ "$DISABLE_STATIC" -eq 1 ]; then + echo "Error: You have choosen to disable the shared lib, yet you also disabled the static lib." 1>&2 + exit $EXIT_FAILURE + elif [ "$DISABLE_STATIC" -eq 1 ]; then ALL_LIBS="libck.so" INSTALL_LIBS="install-so" + elif [ "$DISABLE_SHARED" -eq 1 ]; then + ALL_LIBS="libck.a" + INSTALL_LIBS="install-lib" else ALL_LIBS="libck.so libck.a" INSTALL_LIBS="install-so install-lib" @@ -735,12 +765,18 @@ elif test "$COMPILER" = "gcc" || test "$COMPILER" = "clang" || test "$COMPILER" fi fi - CFLAGS="-D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -std=gnu99 -pedantic -Wall -W -Wundef -Wendif-labels -Wshadow -Wpointer-arith -Wcast-align -Wcast-qual -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wdisabled-optimization -fstrict-aliasing -O2 -pipe -Wno-parentheses $CFLAGS" + CFLAGS="-D_BSD_SOURCE -D_DEFAULT_SOURCE -std=gnu99 -pedantic -Wall -W -Wundef -Wendif-labels -Wshadow -Wpointer-arith -Wcast-align -Wcast-qual -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wdisabled-optimization -fstrict-aliasing -O2 -pipe -Wno-parentheses $CFLAGS" PTHREAD_CFLAGS="-pthread" if test "$COMPILER" = "mingw64"; then ENVIRONMENT=64 PLATFORM=x86_64 fi + if test "$SYSTEM" = "netbsd"; then + CFLAGS="$CFLAGS -D_NETBSD_SOURCE" + fi + if test "$SYSTEM" != "dragonflybsd"; then + CFLAGS="$CFLAGS -D_XOPEN_SOURCE=600" + fi else assert "" "unknown compiler" fi @@ -846,31 +882,31 @@ PROFILE="${PROFILE:-$PLATFORM}" PLATFORM="__${PLATFORM}__" printf "Generating header files.........." -generate include/ck_md.h.in include/ck_md.h -generate include/freebsd/ck_md.h.in include/freebsd/ck_md.h +mkdir -p $BUILD_DIR/include +mkdir -p $BUILD_DIR/include/freebsd +generate include/ck_md.h.in $BUILD_DIR/include/ck_md.h +generate include/freebsd/ck_md.h.in $BUILD_DIR/include/freebsd/ck_md.h echo "success" printf "Generating build files..........." -mkdir -p $P_PWD/doc -mkdir -p $P_PWD/build -mkdir -p $P_PWD/include -mkdir -p $P_PWD/src +mkdir -p $BUILD_DIR/doc +mkdir -p $BUILD_DIR/build +mkdir -p $BUILD_DIR/src -if test "$P_PWD" '!=' "$BUILD_DIR"; then - mkdir -p $P_PWD/regressions - cp $BUILD_DIR/regressions/Makefile.unsupported $P_PWD/regressions/Makefile &> /dev/null - cp $BUILD_DIR/build/ck.build.$PROFILE $P_PWD/build/ck.build.$PROFILE &> /dev/null - cp $BUILD_DIR/include/ck_md.h $P_PWD/include/ck_md.h &> /dev/null +if test "$BUILD_DIR" '!=' "$SRC_DIR"; then + mkdir -p $BUILD_DIR/regressions + cp $SRC_DIR/regressions/Makefile.unsupported $BUILD_DIR/regressions/Makefile &> /dev/null + cp $SRC_DIR/build/ck.build.$PROFILE $BUILD_DIR/build/ck.build.$PROFILE &> /dev/null fi -generate src/Makefile.in $P_PWD/src/Makefile -generate doc/Makefile.in $P_PWD/doc/Makefile -generate build/ck.build.in $P_PWD/build/ck.build -generate build/regressions.build.in $P_PWD/build/regressions.build -generate build/ck.pc.in $P_PWD/build/ck.pc -generate build/ck.spec.in $P_PWD/build/ck.spec -generate Makefile.in $P_PWD/Makefile +generate src/Makefile.in $BUILD_DIR/src/Makefile +generate doc/Makefile.in $BUILD_DIR/doc/Makefile +generate build/ck.build.in $BUILD_DIR/build/ck.build +generate build/regressions.build.in $BUILD_DIR/build/regressions.build +generate build/ck.pc.in $BUILD_DIR/build/ck.pc +generate build/ck.spec.in $BUILD_DIR/build/ck.spec +generate Makefile.in $BUILD_DIR/Makefile touch src/*.c echo "success" generate_stdout diff --git a/doc/Makefile.in b/doc/Makefile.in index cbad704..73c0c75 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -206,7 +206,7 @@ refcheck: install: mkdir -p $(DESTDIR)/$(MANDIR)/man3 || exit - cp *$(GZIP_SUFFIX) $(DESTDIR)/$(MANDIR)/man3 || exit + cp -p *$(GZIP_SUFFIX) $(DESTDIR)/$(MANDIR)/man3 || exit uninstall: for target in $(OBJECTS); do \ diff --git a/doc/ck_epoch_barrier b/doc/ck_epoch_barrier index a586145..2343800 100644 --- a/doc/ck_epoch_barrier +++ b/doc/ck_epoch_barrier @@ -68,7 +68,7 @@ function(void) ck_stack_entry_t *s; record = malloc(sizeof *record); - ck_epoch_register(&epoch, record); + ck_epoch_register(&epoch, record, NULL); /* * We are using an epoch section here to guarantee no diff --git a/doc/ck_epoch_call b/doc/ck_epoch_call index 7390642..fb6302d 100644 --- a/doc/ck_epoch_call +++ b/doc/ck_epoch_call @@ -89,7 +89,7 @@ function(void) struct object *n; record = malloc(sizeof *record); - ck_epoch_register(&epoch, record); + ck_epoch_register(&epoch, record, NULL); n = malloc(sizeof *n); if (n == NULL) diff --git a/doc/ck_epoch_init b/doc/ck_epoch_init index 51a3e2a..c7dee9f 100644 --- a/doc/ck_epoch_init +++ b/doc/ck_epoch_init @@ -51,7 +51,7 @@ The behavior of is undefined if .Fa epoch is not a pointer to a -.Tn ck_epoch_t +.Vt ck_epoch_t object. .El .Sh SEE ALSO diff --git a/doc/ck_epoch_recycle b/doc/ck_epoch_recycle index 530079c..cfaa9f3 100644 --- a/doc/ck_epoch_recycle +++ b/doc/ck_epoch_recycle @@ -64,7 +64,7 @@ function(void) if (record == NULL) return; - ck_epoch_register(&epoch, record); + ck_epoch_register(&epoch, record, NULL); } /* diff --git a/doc/ck_epoch_synchronize b/doc/ck_epoch_synchronize index 6e5f73d..7b4bf74 100644 --- a/doc/ck_epoch_synchronize +++ b/doc/ck_epoch_synchronize @@ -73,7 +73,7 @@ function(void) ck_stack_entry_t *s; record = malloc(sizeof *record); - ck_epoch_register(&epoch, record); + ck_epoch_register(&epoch, record, NULL); /* * We are using an epoch section here to guarantee no diff --git a/doc/ck_hs_init b/doc/ck_hs_init index cfcbf63..9bff896 100644 --- a/doc/ck_hs_init +++ b/doc/ck_hs_init @@ -143,7 +143,7 @@ The behavior of is undefined if .Fa hs is not a pointer to a -.Tn ck_hs_t +.Vt ck_hs_t object. .El .Sh SEE ALSO diff --git a/doc/ck_ht_init b/doc/ck_ht_init index 757a39a..5382c03 100644 --- a/doc/ck_ht_init +++ b/doc/ck_ht_init @@ -68,7 +68,7 @@ NULL or (void *)UINTPTR_MAX will result in undefined behavior. .It CK_HT_MODE_DIRECT The hash table is meant to store key-value pointers where the key is of fixed width field compatible with the -.Tn uintptr_t +.Vt uintptr_t type. The key will be directly compared with other keys for equality. Entries of this hash table are expected to be interacted with using the @@ -155,7 +155,7 @@ The behavior of is undefined if .Fa ht is not a pointer to a -.Tn ck_ht_t +.Vt ck_ht_t object. .El .Sh SEE ALSO diff --git a/doc/ck_pr_fence_atomic_store b/doc/ck_pr_fence_atomic_store index fd02122..9cd8dc5 100644 --- a/doc/ck_pr_fence_atomic_store +++ b/doc/ck_pr_fence_atomic_store @@ -42,7 +42,7 @@ The .Fn ck_pr_fence_atomic_store function enforces the ordering of any atomic read-modify-write operations relative to -any load operations following the function invocation. This function +any store operations following the function invocation. This function always serve as an implicit compiler barrier. On architectures implementing CK_MD_TSO, this operation only serves as a compiler barrier and no fences diff --git a/doc/ck_queue b/doc/ck_queue index a27ec15..df0276a 100644 --- a/doc/ck_queue +++ b/doc/ck_queue @@ -31,6 +31,7 @@ .Nm CK_LIST_ENTRY , .Nm CK_LIST_FIRST , .Nm CK_LIST_FOREACH , +.Nm CK_LIST_FOREACH_FROM , .Nm CK_LIST_FOREACH_SAFE , .Nm CK_LIST_HEAD , .Nm CK_LIST_HEAD_INITIALIZER , @@ -46,6 +47,7 @@ .Nm CK_SLIST_ENTRY , .Nm CK_SLIST_FIRST , .Nm CK_SLIST_FOREACH , +.Nm CK_SLIST_FOREACH_FROM , .Nm CK_SLIST_FOREACH_PREVPTR , .Nm CK_SLIST_FOREACH_SAFE , .Nm CK_SLIST_HEAD , @@ -64,6 +66,7 @@ .Nm CK_STAILQ_ENTRY , .Nm CK_STAILQ_FIRST , .Nm CK_STAILQ_FOREACH , +.Nm CK_STAILQ_FOREACH_FROM , .Nm CK_STAILQ_FOREACH_SAFE , .Nm CK_STAILQ_HEAD , .Nm CK_STAILQ_HEAD_INITIALIZER , @@ -86,6 +89,7 @@ Concurrency Kit (libck, \-lck) .Fn CK_LIST_ENTRY .Fn CK_LIST_FIRST .Fn CK_LIST_FOREACH +.Fn CK_LIST_FOREACH_FROM .Fn CK_LIST_FOREACH_SAFE .Fn CK_LIST_HEAD .Fn CK_LIST_HEAD_INITIALIZER @@ -101,6 +105,7 @@ Concurrency Kit (libck, \-lck) .Fn CK_SLIST_ENTRY .Fn CK_SLIST_FIRST .Fn CK_SLIST_FOREACH +.Fn CK_SLIST_FOREACH_FROM .Fn CK_SLIST_FOREACH_PREVPTR .Fn CK_SLIST_FOREACH_SAFE .Fn CK_SLIST_HEAD @@ -119,6 +124,7 @@ Concurrency Kit (libck, \-lck) .Fn CK_STAILQ_ENTRY .Fn CK_STAILQ_FIRST .Fn CK_STAILQ_FOREACH +.Fn CK_STAILQ_FOREACH_FROM .Fn CK_STAILQ_FOREACH_SAFE .Fn CK_STAILQ_HEAD .Fn CK_STAILQ_HEAD_INITIALIZER diff --git a/doc/ck_rhs_init b/doc/ck_rhs_init index 17c5097..b8316d3 100644 --- a/doc/ck_rhs_init +++ b/doc/ck_rhs_init @@ -140,7 +140,7 @@ The behavior of is undefined if .Fa hs is not a pointer to a -.Tn ck_rhs_t +.Vt ck_rhs_t object. .El .Sh SEE ALSO diff --git a/include/ck_pr.h b/include/ck_pr.h index 8ebf855..cd2a180 100644 --- a/include/ck_pr.h +++ b/include/ck_pr.h @@ -64,6 +64,8 @@ #include "gcc/arm/ck_pr.h" #elif defined(__aarch64__) #include "gcc/aarch64/ck_pr.h" +#elif defined(__riscv) && __riscv_xlen == 64 +#include "gcc/riscv64/ck_pr.h" #elif !defined(__GNUC__) #error Your platform is unsupported #endif diff --git a/include/ck_queue.h b/include/ck_queue.h index fd38d8a..3472b0e 100644 --- a/include/ck_queue.h +++ b/include/ck_queue.h @@ -153,6 +153,11 @@ struct { \ (var); \ (var) = CK_SLIST_NEXT((var), field)) +#define CK_SLIST_FOREACH_FROM(var, head, field) \ + for ((var) = ((var) != NULL ? (var) : CK_SLIST_FIRST((head))); \ + (var); \ + (var) = CK_SLIST_NEXT((var), field)) + #define CK_SLIST_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = CK_SLIST_FIRST(head); \ (var) && ((tvar) = CK_SLIST_NEXT(var, field), 1); \ @@ -262,6 +267,11 @@ struct { \ (var); \ (var) = CK_STAILQ_NEXT((var), field)) +#define CK_STAILQ_FOREACH_FROM(var, head, field) \ + for ((var) = ((var) != NULL ? (var) : CK_STAILQ_FIRST((head))); \ + (var); \ + (var) = CK_STAILQ_NEXT((var), field)) + #define CK_STAILQ_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = CK_STAILQ_FIRST((head)); \ (var) && ((tvar) = \ @@ -374,6 +384,11 @@ struct { \ (var); \ (var) = CK_LIST_NEXT((var), field)) +#define CK_LIST_FOREACH_FROM(var, head, field) \ + for ((var) = ((var) != NULL ? (var) : CK_LIST_FIRST((head))); \ + (var); \ + (var) = CK_LIST_NEXT((var), field)) + #define CK_LIST_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = CK_LIST_FIRST((head)); \ (var) && ((tvar) = CK_LIST_NEXT((var), field), 1); \ diff --git a/include/ck_ring.h b/include/ck_ring.h index 9f6754e..3a52276 100644 --- a/include/ck_ring.h +++ b/include/ck_ring.h @@ -282,7 +282,7 @@ _ck_ring_enqueue_reserve_mp(struct ck_ring *ring, if (size != NULL) *size = (producer - consumer) & mask; - return false; + return NULL; } producer = new_producer; diff --git a/include/gcc/aarch64/ck_pr.h b/include/gcc/aarch64/ck_pr.h index 0a47307..3d269a5 100644 --- a/include/gcc/aarch64/ck_pr.h +++ b/include/gcc/aarch64/ck_pr.h @@ -137,8 +137,8 @@ CK_PR_LOAD_S_64(double, double, "ldr") CK_CC_INLINE static void \ ck_pr_md_store_##S(M *target, T v) \ { \ - __asm__ __volatile__(I " %w1, [%0]" \ - : \ + __asm__ __volatile__(I " %w2, [%1]" \ + : "=m" (*(T *)target) \ : "r" (target), \ "r" (v) \ : "memory"); \ @@ -148,8 +148,8 @@ CK_PR_LOAD_S_64(double, double, "ldr") CK_CC_INLINE static void \ ck_pr_md_store_##S(M *target, T v) \ { \ - __asm__ __volatile__(I " %1, [%0]" \ - : \ + __asm__ __volatile__(I " %2, [%1]" \ + : "=m" (*(T *)target) \ : "r" (target), \ "r" (v) \ : "memory"); \ diff --git a/include/gcc/arm/ck_f_pr.h b/include/gcc/arm/ck_f_pr.h index c508f85..95770e0 100644 --- a/include/gcc/arm/ck_f_pr.h +++ b/include/gcc/arm/ck_f_pr.h @@ -20,7 +20,7 @@ #define CK_F_PR_CAS_16_VALUE #define CK_F_PR_CAS_32 #define CK_F_PR_CAS_32_VALUE -#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7VE__) #define CK_F_PR_CAS_64 #define CK_F_PR_CAS_64_VALUE #define CK_F_PR_CAS_DOUBLE @@ -33,7 +33,7 @@ #define CK_F_PR_CAS_INT #define CK_F_PR_CAS_INT_VALUE #define CK_F_PR_CAS_PTR -#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7VE__) #define CK_F_PR_CAS_PTR_2 #define CK_F_PR_CAS_PTR_2_VALUE #endif @@ -97,7 +97,7 @@ #define CK_F_PR_INC_UINT #define CK_F_PR_LOAD_16 #define CK_F_PR_LOAD_32 -#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7VE__) #define CK_F_PR_LOAD_64 #define CK_F_PR_LOAD_DOUBLE #endif @@ -134,7 +134,7 @@ #define CK_F_PR_STALL #define CK_F_PR_STORE_16 #define CK_F_PR_STORE_32 -#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7VE__) #define CK_F_PR_STORE_64 #define CK_F_PR_STORE_DOUBLE #endif diff --git a/include/gcc/arm/ck_pr.h b/include/gcc/arm/ck_pr.h index 841ca21..b69d6c4 100644 --- a/include/gcc/arm/ck_pr.h +++ b/include/gcc/arm/ck_pr.h @@ -54,7 +54,7 @@ ck_pr_stall(void) return; } -#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7VE__) #define CK_ISB __asm __volatile("isb" : : "r" (0) : "memory") #define CK_DMB __asm __volatile("dmb" : : "r" (0) : "memory") #define CK_DSB __asm __volatile("dsb" : : "r" (0) : "memory") @@ -132,7 +132,7 @@ CK_PR_LOAD_S(char, char, "ldrb") #undef CK_PR_LOAD_S #undef CK_PR_LOAD -#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7VE__) #define CK_PR_DOUBLE_LOAD(T, N) \ CK_CC_INLINE static T \ @@ -181,7 +181,7 @@ CK_PR_STORE_S(char, char, "strb") #undef CK_PR_STORE_S #undef CK_PR_STORE -#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7VE__) #define CK_PR_DOUBLE_STORE(T, N) \ CK_CC_INLINE static void \ diff --git a/include/gcc/riscv64/ck_f_pr.h b/include/gcc/riscv64/ck_f_pr.h new file mode 100644 index 0000000..72b8373 --- /dev/null +++ b/include/gcc/riscv64/ck_f_pr.h @@ -0,0 +1,134 @@ +/* DO NOT EDIT. This is auto-generated from feature.sh */ +#define CK_F_PR_ADD_32 +#define CK_F_PR_ADD_64 +#define CK_F_PR_ADD_INT +#define CK_F_PR_ADD_PTR +#define CK_F_PR_ADD_UINT +#define CK_F_PR_AND_32 +#define CK_F_PR_AND_64 +#define CK_F_PR_AND_INT +#define CK_F_PR_AND_PTR +#define CK_F_PR_AND_UINT +#define CK_F_PR_BTC_32 +#define CK_F_PR_BTC_64 +#define CK_F_PR_BTC_INT +#define CK_F_PR_BTC_PTR +#define CK_F_PR_BTC_UINT +#define CK_F_PR_BTR_32 +#define CK_F_PR_BTR_64 +#define CK_F_PR_BTR_INT +#define CK_F_PR_BTR_PTR +#define CK_F_PR_BTR_UINT +#define CK_F_PR_BTS_32 +#define CK_F_PR_BTS_64 +#define CK_F_PR_BTS_INT +#define CK_F_PR_BTS_PTR +#define CK_F_PR_BTS_UINT +#define CK_F_PR_CAS_32 +#define CK_F_PR_CAS_32_VALUE +#define CK_F_PR_CAS_64 +#define CK_F_PR_CAS_64_VALUE +#define CK_F_PR_CAS_DOUBLE +#define CK_F_PR_CAS_DOUBLE_VALUE +#define CK_F_PR_CAS_INT +#define CK_F_PR_CAS_INT_VALUE +#define CK_F_PR_CAS_PTR +#define CK_F_PR_CAS_PTR_VALUE +#define CK_F_PR_CAS_UINT +#define CK_F_PR_CAS_UINT_VALUE +#define CK_F_PR_DEC_32 +#define CK_F_PR_DEC_32_ZERO +#define CK_F_PR_DEC_64 +#define CK_F_PR_DEC_64_ZERO +#define CK_F_PR_DEC_INT +#define CK_F_PR_DEC_INT_ZERO +#define CK_F_PR_DEC_PTR +#define CK_F_PR_DEC_PTR_ZERO +#define CK_F_PR_DEC_UINT +#define CK_F_PR_DEC_UINT_ZERO +#define CK_F_PR_FAA_32 +#define CK_F_PR_FAA_64 +#define CK_F_PR_FAA_INT +#define CK_F_PR_FAA_PTR +#define CK_F_PR_FAA_UINT +#define CK_F_PR_FAS_32 +#define CK_F_PR_FAS_64 +#define CK_F_PR_FAS_INT +#define CK_F_PR_FAS_PTR +#define CK_F_PR_FAS_UINT +#define CK_F_PR_FENCE_STRICT_ACQREL +#define CK_F_PR_FENCE_STRICT_ACQUIRE +#define CK_F_PR_FENCE_STRICT_ATOMIC +#define CK_F_PR_FENCE_STRICT_ATOMIC_LOAD +#define CK_F_PR_FENCE_STRICT_ATOMIC_STORE +#define CK_F_PR_FENCE_STRICT_LOAD +#define CK_F_PR_FENCE_STRICT_LOAD_ATOMIC +#define CK_F_PR_FENCE_STRICT_LOAD_STORE +#define CK_F_PR_FENCE_STRICT_LOCK +#define CK_F_PR_FENCE_STRICT_MEMORY +#define CK_F_PR_FENCE_STRICT_RELEASE +#define CK_F_PR_FENCE_STRICT_STORE +#define CK_F_PR_FENCE_STRICT_STORE_ATOMIC +#define CK_F_PR_FENCE_STRICT_STORE_LOAD +#define CK_F_PR_FENCE_STRICT_UNLOCK +#define CK_F_PR_INC_32 +#define CK_F_PR_INC_32_ZERO +#define CK_F_PR_INC_64 +#define CK_F_PR_INC_64_ZERO +#define CK_F_PR_INC_INT +#define CK_F_PR_INC_INT_ZERO +#define CK_F_PR_INC_PTR +#define CK_F_PR_INC_PTR_ZERO +#define CK_F_PR_INC_UINT +#define CK_F_PR_INC_UINT_ZERO +#define CK_F_PR_LOAD_16 +#define CK_F_PR_LOAD_32 +#define CK_F_PR_LOAD_64 +#define CK_F_PR_LOAD_8 +#define CK_F_PR_LOAD_CHAR +#define CK_F_PR_LOAD_DOUBLE +#define CK_F_PR_LOAD_INT +#define CK_F_PR_LOAD_PTR +#define CK_F_PR_LOAD_SHORT +#define CK_F_PR_LOAD_UINT +#define CK_F_PR_NEG_32 +#define CK_F_PR_NEG_32_ZERO +#define CK_F_PR_NEG_64 +#define CK_F_PR_NEG_64_ZERO +#define CK_F_PR_NEG_INT +#define CK_F_PR_NEG_INT_ZERO +#define CK_F_PR_NEG_PTR +#define CK_F_PR_NEG_PTR_ZERO +#define CK_F_PR_NEG_UINT +#define CK_F_PR_NEG_UINT_ZERO +#define CK_F_PR_NOT_32 +#define CK_F_PR_NOT_64 +#define CK_F_PR_NOT_INT +#define CK_F_PR_NOT_PTR +#define CK_F_PR_NOT_UINT +#define CK_F_PR_OR_32 +#define CK_F_PR_OR_64 +#define CK_F_PR_OR_INT +#define CK_F_PR_OR_PTR +#define CK_F_PR_OR_UINT +#define CK_F_PR_STALL +#define CK_F_PR_STORE_16 +#define CK_F_PR_STORE_32 +#define CK_F_PR_STORE_64 +#define CK_F_PR_STORE_8 +#define CK_F_PR_STORE_CHAR +#define CK_F_PR_STORE_DOUBLE +#define CK_F_PR_STORE_INT +#define CK_F_PR_STORE_PTR +#define CK_F_PR_STORE_SHORT +#define CK_F_PR_STORE_UINT +#define CK_F_PR_SUB_32 +#define CK_F_PR_SUB_64 +#define CK_F_PR_SUB_INT +#define CK_F_PR_SUB_PTR +#define CK_F_PR_SUB_UINT +#define CK_F_PR_XOR_32 +#define CK_F_PR_XOR_64 +#define CK_F_PR_XOR_INT +#define CK_F_PR_XOR_PTR +#define CK_F_PR_XOR_UINT diff --git a/include/gcc/riscv64/ck_pr.h b/include/gcc/riscv64/ck_pr.h new file mode 100644 index 0000000..9193ee8 --- /dev/null +++ b/include/gcc/riscv64/ck_pr.h @@ -0,0 +1,548 @@ +/* + * Copyright 2009-2016 Samy Al Bahra. + * Copyright 2013-2016 Olivier Houchard. + * All rights reserved. + * Copyright 2022 The FreeBSD Foundation. + * + * Portions of this software were developed by Mitchell Horne + * under sponsorship from the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef CK_PR_RISCV64_H +#define CK_PR_RISCV64_H + +#ifndef CK_PR_H +#error Do not include this file directly, use ck_pr.h +#endif + +#include <ck_cc.h> +#include <ck_md.h> + +#if !defined(__riscv_xlen) || __riscv_xlen != 64 +#error "only for riscv64!" +#endif + +/* + * The following represent supported atomic operations. + * These operations may be emulated. + */ +#include "ck_f_pr.h" + +/* + * Minimum interface requirement met. + */ +#define CK_F_PR + +CK_CC_INLINE static void +ck_pr_stall(void) +{ + + __asm__ __volatile__("" ::: "memory"); + return; +} + +/* + * The FENCE instruction is defined in terms of predecessor and successor bits. + * This allows for greater granularity in specifying whether reads (loads) or + * writes (stores) may pass over either side of the fence. + * + * e.g. "fence r,rw" creates a barrier with acquire semantics. + * + * Note that atomic memory operations (AMOs) are defined by the RISC-V spec to + * act as both a load and store memory operation (read-modify-write, in other + * words). Thus, any of r, w, or rw will enforce ordering on an AMO. + */ +#define CK_FENCE(p, s) __asm __volatile("fence " #p "," #s ::: "memory"); +#define CK_FENCE_RW_RW CK_FENCE(rw,rw) + +#define CK_PR_FENCE(T, I) \ + CK_CC_INLINE static void \ + ck_pr_fence_strict_##T(void) \ + { \ + I; \ + } + +CK_PR_FENCE(atomic, CK_FENCE_RW_RW) +CK_PR_FENCE(atomic_store, CK_FENCE(rw,w)) +CK_PR_FENCE(atomic_load, CK_FENCE(rw,r)) +CK_PR_FENCE(store_atomic, CK_FENCE(w,rw)) +CK_PR_FENCE(load_atomic, CK_FENCE(r,rw)) +CK_PR_FENCE(store, CK_FENCE(w,w)) +CK_PR_FENCE(store_load, CK_FENCE(w,r)) +CK_PR_FENCE(load, CK_FENCE(r,r)) +CK_PR_FENCE(load_store, CK_FENCE(r,w)) +CK_PR_FENCE(memory, CK_FENCE_RW_RW) +CK_PR_FENCE(acquire, CK_FENCE(r,rw)) +CK_PR_FENCE(release, CK_FENCE(rw,w)) +CK_PR_FENCE(acqrel, CK_FENCE_RW_RW) +CK_PR_FENCE(lock, CK_FENCE_RW_RW) +CK_PR_FENCE(unlock, CK_FENCE_RW_RW) + +#undef CK_PR_FENCE + +#undef CK_FENCE_RW_RW +#undef CK_FENCE + +/* + * ck_pr_load(3) + */ +#define CK_PR_LOAD(S, M, T, I) \ + CK_CC_INLINE static T \ + ck_pr_md_load_##S(const M *target) \ + { \ + long r = 0; \ + __asm__ __volatile__(I " %0, 0(%1)\n" \ + : "=r" (r) \ + : "r" (target) \ + : "memory"); \ + return ((T)r); \ + } +#define CK_PR_LOAD_S(S, T, I) CK_PR_LOAD(S, T, T, I) + +CK_PR_LOAD(ptr, void, void *, "ld") +CK_PR_LOAD_S(64, uint64_t, "ld") +CK_PR_LOAD_S(32, uint32_t, "lwu") +CK_PR_LOAD_S(16, uint16_t, "lhu") +CK_PR_LOAD_S(8, uint8_t, "lbu") +CK_PR_LOAD_S(uint, unsigned int, "lwu") +CK_PR_LOAD_S(int, int, "lw") +CK_PR_LOAD_S(short, short, "lh") +CK_PR_LOAD_S(char, char, "lb") +#ifndef CK_PR_DISABLE_DOUBLE +CK_PR_LOAD_S(double, double, "ld") +#endif + +#undef CK_PR_LOAD_S +#undef CK_PR_LOAD + +/* + * ck_pr_store(3) + */ +#define CK_PR_STORE(S, M, T, I) \ + CK_CC_INLINE static void \ + ck_pr_md_store_##S(M *target, T val) \ + { \ + __asm__ __volatile__(I " %1, 0(%0)" \ + : \ + : "r" (target), \ + "r" (val) \ + : "memory"); \ + } +#define CK_PR_STORE_S(S, T, I) CK_PR_STORE(S, T, T, I) + +CK_PR_STORE(ptr, void, const void *, "sd") +CK_PR_STORE_S(64, uint64_t, "sd") +CK_PR_STORE_S(32, uint32_t, "sw") +CK_PR_STORE_S(16, uint16_t, "sh") +CK_PR_STORE_S(8, uint8_t, "sb") +CK_PR_STORE_S(uint, unsigned int, "sw") +CK_PR_STORE_S(int, int, "sw") +CK_PR_STORE_S(short, short, "sh") +CK_PR_STORE_S(char, char, "sb") +#ifndef CK_PR_DISABLE_DOUBLE +CK_PR_STORE_S(double, double, "sd") +#endif + +#undef CK_PR_STORE_S +#undef CK_PR_STORE + +/* + * ck_pr_cas(3) + * + * NB: 'S' is to cast compare to a signed 32-bit integer, so the value will be + * sign-extended when passed to inline asm. GCC does this sign extension + * implicitly, while clang does not. It is necessary because lr.w sign-extends + * the value read from memory, so compare must match that to avoid looping + * unconditionally. + */ +#define CK_PR_CAS(N, M, T, C, S, W) \ + CK_CC_INLINE static bool \ + ck_pr_cas_##N##_value(M *target, T compare, T set, M *value) \ + { \ + T previous; \ + int tmp; \ + __asm__ __volatile__("1:" \ + "li %[tmp], 1\n" \ + "lr." W " %[p], %[t]\n" \ + "bne %[p], %[c], 2f\n" \ + "sc." W " %[tmp], %[s], %[t]\n" \ + "bnez %[tmp], 1b\n" \ + "2:" \ + : [p]"=&r" (previous), \ + [tmp]"=&r" (tmp), \ + [t]"+A" (*(C *)target) \ + : [s]"r" (set), \ + [c]"r" ((long)(S)compare) \ + : "memory"); \ + *(T *)value = previous; \ + return (tmp == 0); \ + } \ + CK_CC_INLINE static bool \ + ck_pr_cas_##N(M *target, T compare, T set) \ + { \ + T previous; \ + int tmp; \ + __asm__ __volatile__("1:" \ + "li %[tmp], 1\n" \ + "lr." W " %[p], %[t]\n" \ + "bne %[p], %[c], 2f\n" \ + "sc." W " %[tmp], %[s], %[t]\n" \ + "bnez %[tmp], 1b\n" \ + "2:" \ + : [p]"=&r" (previous), \ + [tmp]"=&r" (tmp), \ + [t]"+A" (*(C *)target) \ + : [s]"r" (set), \ + [c]"r" ((long)(S)compare) \ + : "memory"); \ + return (tmp == 0); \ + } +#define CK_PR_CAS_S(N, T, W) CK_PR_CAS(N, T, T, T, T, W) +#define CK_PR_CAS_32_S(N, T, W) CK_PR_CAS(N, T, T, T, int32_t, W) + +CK_PR_CAS(ptr, void, void *, uint64_t, uint64_t, "d") +CK_PR_CAS_S(64, uint64_t, "d") +CK_PR_CAS_32_S(32, uint32_t, "w") +CK_PR_CAS_32_S(uint, unsigned int, "w") +CK_PR_CAS_32_S(int, int, "w") +#ifndef CK_PR_DISABLE_DOUBLE +CK_PR_CAS_S(double, double, "d") +#endif + +#undef CK_PR_CAS_S +#undef CK_PR_CAS + +/* + * ck_pr_faa(3) + */ +#define CK_PR_FAA(N, M, T, C, W) \ + CK_CC_INLINE static T \ + ck_pr_faa_##N(M *target, T delta) \ + { \ + T previous; \ + __asm__ __volatile__("amoadd." W " %0, %2, %1\n" \ + : "=&r" (previous), \ + "+A" (*(C *)target) \ + : "r" (delta) \ + : "memory"); \ + return (previous); \ + } +#define CK_PR_FAA_S(N, T, W) CK_PR_FAA(N, T, T, T, W) + +CK_PR_FAA(ptr, void, void *, uint64_t, "d") +CK_PR_FAA_S(64, uint64_t, "d") +CK_PR_FAA_S(32, uint32_t, "w") +CK_PR_FAA_S(uint, unsigned int, "w") +CK_PR_FAA_S(int, int, "w") + +#undef CK_PR_FAA_S +#undef CK_PR_FAA + +/* + * ck_pr_fas(3) + */ +#define CK_PR_FAS(N, M, T, C, W) \ + CK_CC_INLINE static T \ + ck_pr_fas_##N(M *target, T val) \ + { \ + T previous; \ + __asm__ __volatile__("amoswap." W " %0, %2, %1\n" \ + : "=&r" (previous), \ + "+A" (*(C *)target) \ + : "r" (val) \ + : "memory"); \ + return (previous); \ + } +#define CK_PR_FAS_S(N, T, W) CK_PR_FAS(N, T, T, T, W) + +CK_PR_FAS(ptr, void, void *, uint64_t, "d") +CK_PR_FAS_S(64, uint64_t, "d") +CK_PR_FAS_S(32, uint32_t, "w") +CK_PR_FAS_S(int, int, "w") +CK_PR_FAS_S(uint, unsigned int, "w") + +#undef CK_PR_FAS_S +#undef CK_PR_FAS + +/* + * ck_pr_add(3) + */ +#define CK_PR_ADD(N, M, T, C, W) \ + CK_CC_INLINE static void \ + ck_pr_add_##N(M *target, T val) \ + { \ + __asm__ __volatile__("amoadd." W " zero, %1, %0\n" \ + : "+A" (*(C *)target) \ + : "r" (val) \ + : "memory"); \ + } \ + CK_CC_INLINE static bool \ + ck_pr_add_##N##_is_zero(M *target, T val) \ + { \ + T previous; \ + __asm__ __volatile__("amoadd." W " %0, %2, %1\n" \ + : "=&r" (previous), \ + "+A" (*(C *)target) \ + : "r" (val) \ + : "memory"); \ + return (((C)previous + (C)val) == 0); \ + } +#define CK_PR_ADD_S(N, T, W) CK_PR_ADD(N, T, T, T, W) + +CK_PR_ADD(ptr, void, void *, uint64_t, "d") +CK_PR_ADD_S(64, uint64_t, "d") +CK_PR_ADD_S(32, uint32_t, "w") +CK_PR_ADD_S(uint, unsigned int, "w") +CK_PR_ADD_S(int, int, "w") + +#undef CK_PR_ADD_S +#undef CK_PR_ADD + +/* + * ck_pr_inc(3) + * + * Implemented in terms of ck_pr_add(3); RISC-V has no atomic inc or dec + * instructions. + */ +#define CK_PR_INC(N, M, T, W) \ + CK_CC_INLINE static void \ + ck_pr_inc_##N(M *target) \ + { \ + ck_pr_add_##N(target, (T)1); \ + } \ + CK_CC_INLINE static bool \ + ck_pr_inc_##N##_is_zero(M *target) \ + { \ + return (ck_pr_add_##N##_is_zero(target, (T)1)); \ + } +#define CK_PR_INC_S(N, T, W) CK_PR_INC(N, T, T, W) + +CK_PR_INC(ptr, void, void *, "d") +CK_PR_INC_S(64, uint64_t, "d") +CK_PR_INC_S(32, uint32_t, "w") +CK_PR_INC_S(uint, unsigned int, "w") +CK_PR_INC_S(int, int, "w") + +#undef CK_PR_INC_S +#undef CK_PR_INC + +/* + * ck_pr_sub(3) + */ +#define CK_PR_SUB(N, M, T, C, W) \ + CK_CC_INLINE static void \ + ck_pr_sub_##N(M *target, T val) \ + { \ + __asm__ __volatile__("amoadd." W " zero, %1, %0\n" \ + : "+A" (*(C *)target) \ + : "r" (-(C)val) \ + : "memory"); \ + } \ + CK_CC_INLINE static bool \ + ck_pr_sub_##N##_is_zero(M *target, T val) \ + { \ + T previous; \ + __asm__ __volatile__("amoadd." W " %0, %2, %1\n" \ + : "=&r" (previous), \ + "+A" (*(C *)target) \ + : "r" (-(C)val) \ + : "memory"); \ + return (((C)previous - (C)val) == 0); \ + } +#define CK_PR_SUB_S(N, T, W) CK_PR_SUB(N, T, T, T, W) + +CK_PR_SUB(ptr, void, void *, uint64_t, "d") +CK_PR_SUB_S(64, uint64_t, "d") +CK_PR_SUB_S(32, uint32_t, "w") +CK_PR_SUB_S(uint, unsigned int, "w") +CK_PR_SUB_S(int, int, "w") + +#undef CK_PR_SUB_S +#undef CK_PR_SUB + +/* + * ck_pr_dec(3) + */ +#define CK_PR_DEC(N, M, T, W) \ + CK_CC_INLINE static void \ + ck_pr_dec_##N(M *target) \ + { \ + ck_pr_sub_##N(target, (T)1); \ + } \ + CK_CC_INLINE static bool \ + ck_pr_dec_##N##_is_zero(M *target) \ + { \ + return (ck_pr_sub_##N##_is_zero(target, (T)1)); \ + } +#define CK_PR_DEC_S(N, T, W) CK_PR_DEC(N, T, T, W) + +CK_PR_DEC(ptr, void, void *, "d") +CK_PR_DEC_S(64, uint64_t, "d") +CK_PR_DEC_S(32, uint32_t, "w") +CK_PR_DEC_S(uint, unsigned int, "w") +CK_PR_DEC_S(int, int, "w") + +#undef CK_PR_DEC_S +#undef CK_PR_DEC + +/* + * ck_pr_neg(3) + */ +#define CK_PR_NEG(N, M, T, C, W) \ + CK_CC_INLINE static void \ + ck_pr_neg_##N(M *target) \ + { \ + __asm__ __volatile__("1:" \ + "lr." W " t0, %0\n" \ + "sub t0, zero, t0\n" \ + "sc." W " t1, t0, %0\n" \ + "bnez t1, 1b\n" \ + : "+A" (*(C *)target) \ + : \ + : "t0", "t1", "memory"); \ + } +#define CK_PR_NEG_S(N, T, W) CK_PR_NEG(N, T, T, T, W) + +CK_PR_NEG(ptr, void, void *, uint64_t, "d") +CK_PR_NEG_S(64, uint64_t, "d") +CK_PR_NEG_S(32, uint32_t, "w") +CK_PR_NEG_S(uint, unsigned int, "w") +CK_PR_NEG_S(int, int, "w") + +#undef CK_PR_NEG_S +#undef CK_PR_NEG + +/* + * ck_pr_not(3) + */ +#define CK_PR_NOT(N, M, T, C, W) \ + CK_CC_INLINE static void \ + ck_pr_not_##N(M *target) \ + { \ + __asm__ __volatile__("1:" \ + "lr." W " t0, %0\n" \ + "not t0, t0\n" \ + "sc." W " t1, t0, %0\n" \ + "bnez t1, 1b\n" \ + : "+A" (*(C *)target) \ + : \ + : "t0", "t1", "memory"); \ + } +#define CK_PR_NOT_S(N, T, W) CK_PR_NOT(N, T, T, T, W) + +CK_PR_NOT(ptr, void, void *, uint64_t, "d") +CK_PR_NOT_S(64, uint64_t, "d") +CK_PR_NOT_S(32, uint32_t, "w") +CK_PR_NOT_S(uint, unsigned int, "w") +CK_PR_NOT_S(int, int, "w") + +#undef CK_PR_NOT_S +#undef CK_PR_NOT + +/* + * ck_pr_and(3), ck_pr_or(3), and ck_pr_xor(3) + */ +#define CK_PR_BINARY(O, N, M, T, C, I, W) \ + CK_CC_INLINE static void \ + ck_pr_##O##_##N(M *target, T delta) \ + { \ + __asm__ __volatile__(I "." W " zero, %1, %0\n" \ + : "+A" (*(C *)target) \ + : "r" (delta) \ + : "memory"); \ + } + +CK_PR_BINARY(and, ptr, void, void *, uint64_t, "amoand", "d") +CK_PR_BINARY(or, ptr, void, void *, uint64_t, "amoor", "d") +CK_PR_BINARY(xor, ptr, void, void *, uint64_t, "amoxor", "d") + +#define CK_PR_BINARY_S(S, T, W) \ + CK_PR_BINARY(and, S, T, T, T, "amoand", W) \ + CK_PR_BINARY(or, S, T, T, T, "amoor", W) \ + CK_PR_BINARY(xor, S, T, T, T, "amoxor", W) \ + +CK_PR_BINARY_S(64, uint64_t, "d") +CK_PR_BINARY_S(32, uint32_t, "w") +CK_PR_BINARY_S(uint, unsigned int, "w") +CK_PR_BINARY_S(int, int, "w") + +#undef CK_PR_BINARY_S +#undef CK_PR_BINARY + +/* + * ck_pr_btc(3), ck_pr_btr(3), and ck_pr_bts(3) + */ +#define CK_PR_BTX(K, S, I, W, M, C, O) \ + CK_CC_INLINE static bool \ + ck_pr_##K##_##S(M *target, unsigned int idx) \ + { \ + C ret; \ + C mask = (C)0x1 << idx; \ + __asm__ __volatile__(I "." W " %1, %2, %0\n" \ + : "+A" (*(C *)target), \ + "=r" (ret) \ + : "r" (O(mask)) \ + : "memory", "cc"); \ + return ((ret & mask) != 0); \ + } + +#define CK_PR_BTC(S, W, M, C) CK_PR_BTX(btc, S, "amoxor", W, M, C, 0+) +#define CK_PR_BTC_S(S, W, T) CK_PR_BTC(S, W, T, T) + +CK_PR_BTC(ptr, "d", void, uint64_t) +CK_PR_BTC_S(64, "d", uint64_t) +CK_PR_BTC_S(32, "w", uint32_t) +CK_PR_BTC_S(uint, "w", unsigned int) +CK_PR_BTC_S(int, "w", int) + +#undef CK_PR_BTC_S +#undef CK_PR_BTC + +#define CK_PR_BTR(S, W, M, C) CK_PR_BTX(btr, S, "amoand", W, M, C, ~) +#define CK_PR_BTR_S(S, W, T) CK_PR_BTR(S, W, T, T) + +CK_PR_BTR(ptr, "d", void, uint64_t) +CK_PR_BTR_S(64, "d", uint64_t) +CK_PR_BTR_S(32, "w", uint32_t) +CK_PR_BTR_S(uint, "w", unsigned int) +CK_PR_BTR_S(int, "w", int) + +#undef CK_PR_BTR_S +#undef CK_PR_BTR + +#define CK_PR_BTS(S, W, M, C) CK_PR_BTX(bts, S, "amoor", W, M, C, 0+) +#define CK_PR_BTS_S(S, W, T) CK_PR_BTS(S, W, T, T) + +CK_PR_BTS(ptr, "d", void, uint64_t) +CK_PR_BTS_S(64, "d", uint64_t) +CK_PR_BTS_S(32, "w", uint32_t) +CK_PR_BTS_S(uint, "w", unsigned int) +CK_PR_BTS_S(int, "w", int) + +#undef CK_PR_BTS_S +#undef CK_PR_BTS + +#undef CK_PR_BTX + +#endif /* CK_PR_RISCV64_H */ diff --git a/include/gcc/x86/ck_pr.h b/include/gcc/x86/ck_pr.h index 5194dee..12291c8 100644 --- a/include/gcc/x86/ck_pr.h +++ b/include/gcc/x86/ck_pr.h @@ -120,7 +120,7 @@ CK_PR_FENCE(unlock, CK_MD_X86_MFENCE) return v; \ } -CK_PR_FAS(ptr, void, void *, char, "xchgl") +CK_PR_FAS(ptr, void, void *, uint32_t, "xchgl") #define CK_PR_FAS_S(S, T, I) CK_PR_FAS(S, T, T, T, I) @@ -146,7 +146,7 @@ CK_PR_FAS_S(8, uint8_t, "xchgb") return (r); \ } -CK_PR_LOAD(ptr, void, void *, char, "movl") +CK_PR_LOAD(ptr, void, void *, uint32_t, "movl") #define CK_PR_LOAD_S(S, T, I) CK_PR_LOAD(S, T, T, T, I) @@ -171,7 +171,7 @@ CK_PR_LOAD_S(8, uint8_t, "movb") return; \ } -CK_PR_STORE(ptr, void, const void *, char, "movl") +CK_PR_STORE(ptr, void, const void *, uint32_t, "movl") #define CK_PR_STORE_S(S, T, I) CK_PR_STORE(S, T, T, T, I) @@ -200,7 +200,7 @@ CK_PR_STORE_S(8, uint8_t, "movb") return (d); \ } -CK_PR_FAA(ptr, void, uintptr_t, char, "xaddl") +CK_PR_FAA(ptr, void, uintptr_t, uint32_t, "xaddl") #define CK_PR_FAA_S(S, T, I) CK_PR_FAA(S, T, T, T, I) @@ -248,7 +248,7 @@ CK_PR_FAA_S(8, uint8_t, "xaddb") #define CK_PR_UNARY_S(K, S, T, I) CK_PR_UNARY(K, S, T, T, I) #define CK_PR_GENERATE(K) \ - CK_PR_UNARY(K, ptr, void, char, #K "l") \ + CK_PR_UNARY(K, ptr, void, uint32_t, #K "l") \ CK_PR_UNARY_S(K, char, char, #K "b") \ CK_PR_UNARY_S(K, int, int, #K "l") \ CK_PR_UNARY_S(K, uint, unsigned int, #K "l") \ @@ -288,7 +288,7 @@ CK_PR_GENERATE(not) #define CK_PR_BINARY_S(K, S, T, I) CK_PR_BINARY(K, S, T, T, T, I) #define CK_PR_GENERATE(K) \ - CK_PR_BINARY(K, ptr, void, uintptr_t, char, #K "l") \ + CK_PR_BINARY(K, ptr, void, uintptr_t, uint32_t, #K "l") \ CK_PR_BINARY_S(K, char, char, #K "b") \ CK_PR_BINARY_S(K, int, int, #K "l") \ CK_PR_BINARY_S(K, uint, unsigned int, #K "l") \ @@ -369,7 +369,7 @@ CK_PR_GENERATE(xor) } #endif -CK_PR_CAS(ptr, void, void *, char, "cmpxchgl") +CK_PR_CAS(ptr, void, void *, uint32_t, "cmpxchgl") #define CK_PR_CAS_S(S, T, I) CK_PR_CAS(S, T, T, T, I) @@ -401,11 +401,11 @@ CK_PR_CAS_S(8, uint8_t, "cmpxchgb") #define CK_PR_BT_S(K, S, T, I) CK_PR_BT(K, S, T, T, T, I) -#define CK_PR_GENERATE(K) \ - CK_PR_BT(K, ptr, void, uint32_t, char, #K "l %2, %0") \ - CK_PR_BT_S(K, uint, unsigned int, #K "l %2, %0") \ - CK_PR_BT_S(K, int, int, #K "l %2, %0") \ - CK_PR_BT_S(K, 32, uint32_t, #K "l %2, %0") \ +#define CK_PR_GENERATE(K) \ + CK_PR_BT(K, ptr, void, uint32_t, uint32_t, #K "l %2, %0") \ + CK_PR_BT_S(K, uint, unsigned int, #K "l %2, %0") \ + CK_PR_BT_S(K, int, int, #K "l %2, %0") \ + CK_PR_BT_S(K, 32, uint32_t, #K "l %2, %0") \ CK_PR_BT_S(K, 16, uint16_t, #K "w %w2, %0") CK_PR_GENERATE(btc) diff --git a/include/gcc/x86_64/ck_pr.h b/include/gcc/x86_64/ck_pr.h index 4222729..b737c3a 100644 --- a/include/gcc/x86_64/ck_pr.h +++ b/include/gcc/x86_64/ck_pr.h @@ -149,7 +149,7 @@ ck_pr_rfo(const void *m) return v; \ } -CK_PR_FAS(ptr, void, void *, char, "xchgq") +CK_PR_FAS(ptr, void, void *, uint64_t, "xchgq") #define CK_PR_FAS_S(S, T, I) CK_PR_FAS(S, T, T, T, I) @@ -182,7 +182,7 @@ CK_PR_FAS_S(8, uint8_t, "xchgb") return (r); \ } -CK_PR_LOAD(ptr, void, void *, char, "movq") +CK_PR_LOAD(ptr, void, void *, uint64_t, "movq") #define CK_PR_LOAD_S(S, T, I) CK_PR_LOAD(S, T, T, T, I) @@ -223,7 +223,7 @@ ck_pr_load_ptr_2(const void *t, void *v) #define CK_PR_LOAD_2(S, W, T) \ CK_CC_INLINE static void \ - ck_pr_md_load_##S##_##W(const T t[2], T v[2]) \ + ck_pr_md_load_##S##_##W(const T t[W], T v[W]) \ { \ ck_pr_load_64_2((const uint64_t *)(const void *)t, \ (uint64_t *)(void *)v); \ @@ -264,7 +264,7 @@ CK_PR_LOAD_2(8, 16, uint8_t) return; \ } -CK_PR_STORE_IMM(ptr, void, const void *, char, "movq", CK_CC_IMM_U32) +CK_PR_STORE_IMM(ptr, void, const void *, uint64_t, "movq", CK_CC_IMM_U32) #ifndef CK_PR_DISABLE_DOUBLE CK_PR_STORE(double, double, double, double, "movq") #endif @@ -298,7 +298,7 @@ CK_PR_STORE_S(8, uint8_t, "movb", CK_CC_IMM_U32) return (d); \ } -CK_PR_FAA(ptr, void, uintptr_t, char, "xaddq") +CK_PR_FAA(ptr, void, uintptr_t, uint64_t, "xaddq") #define CK_PR_FAA_S(S, T, I) CK_PR_FAA(S, T, T, T, I) @@ -347,7 +347,7 @@ CK_PR_FAA_S(8, uint8_t, "xaddb") #define CK_PR_UNARY_S(K, S, T, I) CK_PR_UNARY(K, S, T, T, I) #define CK_PR_GENERATE(K) \ - CK_PR_UNARY(K, ptr, void, char, #K "q") \ + CK_PR_UNARY(K, ptr, void, uint64_t, #K "q") \ CK_PR_UNARY_S(K, char, char, #K "b") \ CK_PR_UNARY_S(K, int, int, #K "l") \ CK_PR_UNARY_S(K, uint, unsigned int, #K "l") \ @@ -388,7 +388,7 @@ CK_PR_GENERATE(not) #define CK_PR_BINARY_S(K, S, T, I, O) CK_PR_BINARY(K, S, T, T, T, I, O) #define CK_PR_GENERATE(K) \ - CK_PR_BINARY(K, ptr, void, uintptr_t, char, #K "q", CK_CC_IMM_U32) \ + CK_PR_BINARY(K, ptr, void, uintptr_t, uint64_t, #K "q", CK_CC_IMM_U32) \ CK_PR_BINARY_S(K, char, char, #K "b", CK_CC_IMM_S32) \ CK_PR_BINARY_S(K, int, int, #K "l", CK_CC_IMM_S32) \ CK_PR_BINARY_S(K, uint, unsigned int, #K "l", CK_CC_IMM_U32) \ @@ -470,7 +470,7 @@ CK_PR_GENERATE(xor) } #endif -CK_PR_CAS(ptr, void, void *, char, "cmpxchgq") +CK_PR_CAS(ptr, void, void *, uint64_t, "cmpxchgq") #define CK_PR_CAS_S(S, T, I) CK_PR_CAS(S, T, T, T, I) @@ -594,12 +594,12 @@ CK_PR_CAS_V(8, 16, uint8_t) #define CK_PR_BT_S(K, S, T, I) CK_PR_BT(K, S, T, T, T, I) -#define CK_PR_GENERATE(K) \ - CK_PR_BT(K, ptr, void, uint64_t, char, #K "q %2, %0") \ - CK_PR_BT_S(K, uint, unsigned int, #K "l %2, %0") \ - CK_PR_BT_S(K, int, int, #K "l %2, %0") \ - CK_PR_BT_S(K, 64, uint64_t, #K "q %2, %0") \ - CK_PR_BT_S(K, 32, uint32_t, #K "l %2, %0") \ +#define CK_PR_GENERATE(K) \ + CK_PR_BT(K, ptr, void, uint64_t, uint64_t, #K "q %2, %0") \ + CK_PR_BT_S(K, uint, unsigned int, #K "l %2, %0") \ + CK_PR_BT_S(K, int, int, #K "l %2, %0") \ + CK_PR_BT_S(K, 64, uint64_t, #K "q %2, %0") \ + CK_PR_BT_S(K, 32, uint32_t, #K "l %2, %0") \ CK_PR_BT_S(K, 16, uint16_t, #K "w %w2, %0") CK_PR_GENERATE(btc) diff --git a/regressions/Makefile b/regressions/Makefile index c74b4fa..1dbf988 100644 --- a/regressions/Makefile +++ b/regressions/Makefile @@ -18,7 +18,6 @@ DIR=array \ queue \ ring \ rwlock \ - swlock \ sequence \ spinlock \ stack \ diff --git a/regressions/ck_sequence/validate/ck_sequence.c b/regressions/ck_sequence/validate/ck_sequence.c index 47de852..5c85d44 100644 --- a/regressions/ck_sequence/validate/ck_sequence.c +++ b/regressions/ck_sequence/validate/ck_sequence.c @@ -124,7 +124,7 @@ main(int argc, char *argv[]) n_threads = atoi(argv[1]) - 1; if (n_threads <= 0) { - ck_error("ERROR: Number of threads must be greater than 0\n"); + return 0; /* nothing to do */ } threads = malloc(sizeof(pthread_t) * n_threads); diff --git a/regressions/common.h b/regressions/common.h index 9cdc690..4d3d782 100644 --- a/regressions/common.h +++ b/regressions/common.h @@ -34,16 +34,24 @@ #include <stdlib.h> #include <sys/time.h> -#ifdef __linux__ +#if defined(__linux__) || defined(__DragonFly__) #include <sched.h> #include <sys/types.h> #include <sys/syscall.h> +#if defined(__DragonFly__) +#include <sys/sched.h> +#include <pthread_np.h> +#endif #elif defined(__MACH__) +#include <errno.h> #include <mach/mach.h> #include <mach/thread_policy.h> #elif defined(__FreeBSD__) #include <sys/param.h> #include <sys/cpuset.h> +#elif defined(__NetBSD__) +#include <pthread.h> +#include <sched.h> #endif #if defined(_WIN32) @@ -266,11 +274,15 @@ struct affinity { #define AFFINITY_INITIALIZER {0, 0} -#ifdef __linux__ +#if defined(__linux__) || defined(__DragonFly__) static pid_t common_gettid(void) { +#if defined(__linux__) return syscall(__NR_gettid); +#else + return pthread_getthreadid_np(); +#endif } CK_CC_UNUSED static int @@ -309,13 +321,19 @@ aff_iterate(struct affinity *acb) { thread_affinity_policy_data_t policy; unsigned int c; + int err; c = ck_pr_faa_uint(&acb->request, acb->delta) % CORES; policy.affinity_tag = c; - return thread_policy_set(mach_thread_self(), + err = thread_policy_set(mach_thread_self(), THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, THREAD_AFFINITY_POLICY_COUNT); + if (err == KERN_NOT_SUPPORTED) + return 0; + if (err != 0) + errno = EINVAL; + return err; } CK_CC_UNUSED static int @@ -355,6 +373,39 @@ aff_iterate_core(struct affinity *acb CK_CC_UNUSED, unsigned int *core) return (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(mask), &mask)); } +#elif defined(__NetBSD__) +CK_CC_UNUSED static int +aff_iterate(struct affinity *acb CK_CC_UNUSED) +{ + unsigned int c; + cpuset_t *mask; + + c = ck_pr_faa_uint(&acb->request, acb->delta) % CORES; + mask = cpuset_create(); + if (!mask) + return -1; + cpuset_zero(mask); + cpuset_set(c, mask); + int ret = pthread_setaffinity_np(pthread_self(), cpuset_size(mask), mask); + cpuset_destroy(mask); + return ret; +} + +CK_CC_UNUSED static int +aff_iterate_core(struct affinity *acb CK_CC_UNUSED, unsigned int *core) +{ + cpuset_t *mask; + + *core = ck_pr_faa_uint(&acb->request, acb->delta) % CORES; + mask = cpuset_create(); + if (!mask) + return -1; + cpuset_zero(mask); + cpuset_set(*core, mask); + int ret = pthread_setaffinity_np(pthread_self(), cpuset_size(mask), mask); + cpuset_destroy(mask); + return ret; +} #else CK_CC_UNUSED static int aff_iterate(struct affinity *acb CK_CC_UNUSED) @@ -451,6 +502,11 @@ rdtsc(void) __asm __volatile__ ("mrs %0, cntvct_el0" : "=r" (r) : : "memory"); return r; +#elif defined(__riscv) && __riscv_xlen == 64 + uint64_t r; + + __asm __volatile__("rdtime %0" : "=r" (r) :: "memory"); + return r; #else return 0; #endif diff --git a/src/ck_rhs.c b/src/ck_rhs.c index 1d6b0f0..aaf1d71 100644 --- a/src/ck_rhs.c +++ b/src/ck_rhs.c @@ -914,6 +914,8 @@ ck_rhs_put_robin_hood(struct ck_rhs *hs, long prev; void *key; long prevs[CK_RHS_MAX_RH]; + int prev_probes[CK_RHS_MAX_RH]; + long last_slot = -1; unsigned int prevs_nb = 0; unsigned int i; @@ -938,8 +940,13 @@ restart: if (ck_rhs_grow(hs, map->capacity << 1) == false) { desc->in_rh = false; - for (i = 0; i < prevs_nb; i++) + for (i = 0; i < prevs_nb; i++) { + if (i > 0) + ck_rhs_set_probes(map, prevs[i], prev_probes[i - 1]); ck_rhs_unset_rh(map, prevs[i]); + } + if (last_slot != -1) + ck_rhs_set_probes(map, last_slot, prev_probes[prevs_nb - 1]); return -1; } @@ -951,10 +958,13 @@ restart: desc = ck_rhs_desc(map, first); int old_probes = desc->probes; + last_slot = first; + desc->probes = n_probes; h = ck_rhs_get_first_offset(map, first, n_probes); ck_rhs_map_bound_set(map, h, n_probes); prev = orig_slot; + prev_probes[prevs_nb] = old_probes; prevs[prevs_nb++] = prev; n_probes = old_probes; goto restart; |