diff --git a/configure b/configure index 19b6739..464cade 100755 --- a/configure +++ b/configure @@ -33,7 +33,7 @@ EXIT_FAILURE=1 P_PWD=`pwd` MAINTAINER='sbahra@repnop.org' -VERSION=${VERSION:-'0.2.15'} +VERSION=${VERSION:-'0.2.17'} VERSION_MAJOR='0' BUILD="$PWD/build/ck.build" PREFIX=${PREFIX:-"/usr/local"} @@ -419,10 +419,6 @@ else VMA_BITS_VALUE_R="${VMA_BITS}ULL" fi -# Platform will be used as a macro. -PROFILE="${PROFILE:-$PLATFORM}" -PLATFORM="__${PLATFORM}__" - # `which` on Solaris sucks pathsearch() { @@ -488,7 +484,10 @@ cat << EOF > .1.c #include int main(void) { #if defined(_WIN32) -#if defined(__MINGW32__) && (__MINGW32_MAJOR_VERSION >= 3) +#if defined(__MINGW64__) + puts("mingw64"); + return (0); +#elif defined(__MINGW32__) && (__MINGW32_MAJOR_VERSION >= 3) puts("mingw32"); return (0); #else @@ -525,7 +524,7 @@ if test "$COMPILER" = "suncc"; then LDFLAGS="-G -z text -h libck.so.$VERSION_MAJOR $LDFLAGS" CFLAGS="-xO5 $CFLAGS" PTHREAD_CFLAGS="-mt -lpthread" -elif test "$COMPILER" = "gcc" || test "$COMPILER" = "clang" || test "$COMPILER" = "mingw32"; then +elif test "$COMPILER" = "gcc" || test "$COMPILER" = "clang" || test "$COMPILER" = "mingw32" || test "$COMPILER" = "mingw64"; then LD=$CC if test "$SYSTEM" = "darwin"; then CC_WL_OPT="-install_name" @@ -535,6 +534,10 @@ elif test "$COMPILER" = "gcc" || test "$COMPILER" = "clang" || test "$COMPILER" LDFLAGS="-shared -fPIC -Wl,$CC_WL_OPT,libck.so.$VERSION_MAJOR $LDFLAGS" CFLAGS="-D_XOPEN_SOURCE=600 -D_BSD_SOURCE -std=gnu99 -pedantic -Wall -W -Wundef -Wendif-labels -Wshadow -Wpointer-arith -Wcast-align -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 else assert "" "unknown compiler" fi @@ -558,6 +561,10 @@ EOF fi done +# Platform will be used as a macro. +PROFILE="${PROFILE:-$PLATFORM}" +PLATFORM="__${PLATFORM}__" + printf "Generating header files.........." generate include/ck_md.h.in include/ck_md.h echo "success" diff --git a/doc/CK_COHORT_INIT b/doc/CK_COHORT_INIT index ed97487..42a2294 100644 --- a/doc/CK_COHORT_INIT +++ b/doc/CK_COHORT_INIT @@ -28,7 +28,7 @@ .Dt CK_COHORT_INIT 3 .Sh NAME .Nm CK_COHORT_INIT -.Nd Initialize an instance of a cohort type +.Nd initialize instance of a cohort type .Sh LIBRARY Concurrency Kit (libck, \-lck) .Sh SYNOPSIS diff --git a/doc/CK_COHORT_INSTANCE b/doc/CK_COHORT_INSTANCE index ee75465..cec1617 100644 --- a/doc/CK_COHORT_INSTANCE +++ b/doc/CK_COHORT_INSTANCE @@ -28,7 +28,7 @@ .Dt CK_COHORT_INSTANCE 3 .Sh NAME .Nm CK_COHORT_INSTANCE -.Nd Declare an instance of a cohort type +.Nd declare an instance of a cohort type .Sh LIBRARY Concurrency Kit (libck, \-lck) .Sh SYNOPSIS diff --git a/doc/CK_COHORT_LOCK b/doc/CK_COHORT_LOCK index 7f5e558..df39ad4 100644 --- a/doc/CK_COHORT_LOCK +++ b/doc/CK_COHORT_LOCK @@ -28,7 +28,7 @@ .Dt CK_COHORT_LOCK 3 .Sh NAME .Nm CK_COHORT_LOCK -.Nd Acquire a cohort's locks +.Nd acquire cohort lock .Sh LIBRARY Concurrency Kit (libck, \-lck) .Sh SYNOPSIS diff --git a/doc/CK_COHORT_PROTOTYPE b/doc/CK_COHORT_PROTOTYPE index f0977e0..0ed74b4 100644 --- a/doc/CK_COHORT_PROTOTYPE +++ b/doc/CK_COHORT_PROTOTYPE @@ -28,7 +28,7 @@ .Dt CK_COHORT_PROTOTYPE 3 .Sh NAME .Nm CK_COHORT_PROTOTYPE -.Nd Define a cohort type with the given lock types +.Nd define cohort type with specified lock types .Sh LIBRARY Concurrency Kit (libck, \-lck) .Sh SYNOPSIS diff --git a/doc/CK_COHORT_TRYLOCK b/doc/CK_COHORT_TRYLOCK index 6330642..fd9306e 100644 --- a/doc/CK_COHORT_TRYLOCK +++ b/doc/CK_COHORT_TRYLOCK @@ -28,7 +28,7 @@ .Dt CK_COHORT_TRYLOCK 3 .Sh NAME .Nm CK_COHORT_TRYLOCK -.Nd Try to acquire a cohort's locks +.Nd try to acquire cohort lock .Sh LIBRARY Concurrency Kit (libck, \-lck) .Sh SYNOPSIS diff --git a/doc/CK_COHORT_TRYLOCK_PROTOTYPE b/doc/CK_COHORT_TRYLOCK_PROTOTYPE index 6a038e5..7edc032 100644 --- a/doc/CK_COHORT_TRYLOCK_PROTOTYPE +++ b/doc/CK_COHORT_TRYLOCK_PROTOTYPE @@ -28,7 +28,7 @@ .Dt CK_COHORT_TRYLOCK_PROTOTYPE 3 .Sh NAME .Nm CK_COHORT_TRYLOCK_PROTOTYPE -.Nd Define a cohort type with the given lock types +.Nd define cohort type with specified lock types .Sh LIBRARY Concurrency Kit (libck, \-lck) .Sh SYNOPSIS diff --git a/doc/CK_COHORT_UNLOCK b/doc/CK_COHORT_UNLOCK index ffecaa4..6c5440a 100644 --- a/doc/CK_COHORT_UNLOCK +++ b/doc/CK_COHORT_UNLOCK @@ -28,7 +28,7 @@ .Dt CK_COHORT_UNLOCK 3 .Sh NAME .Nm CK_COHORT_UNLOCK -.Nd Acquire a cohort's locks +.Nd release cohort lock .Sh LIBRARY Concurrency Kit (libck, \-lck) .Sh SYNOPSIS diff --git a/doc/Makefile.in b/doc/Makefile.in index 6e61948..b67dfc8 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -5,6 +5,7 @@ GZIP=@GZIP@ GZIP_SUFFIX=.3@GZIP_SUFFIX@ BUILD_DIR=@BUILD_DIR@ SRC_DIR=@SRC_DIR@ +HTML_SUFFIX=.html OBJECTS=ck_ht_count \ ck_ht_destroy \ @@ -83,13 +84,53 @@ OBJECTS=ck_ht_count \ CK_COHORT_INIT \ CK_COHORT_LOCK \ CK_COHORT_UNLOCK \ - CK_COHORT_TRYLOCK + CK_COHORT_TRYLOCK \ + ck_pr \ + ck_pr_barrier \ + ck_pr_fas \ + ck_pr_fence_load \ + ck_pr_fence_load_depends \ + ck_pr_fence_memory \ + ck_pr_fence_store \ + ck_pr_stall \ + ck_pr_faa \ + ck_pr_inc \ + ck_pr_dec \ + ck_pr_not \ + ck_pr_neg \ + ck_pr_add \ + ck_pr_sub \ + ck_pr_and \ + ck_pr_xor \ + ck_pr_or \ + ck_pr_cas \ + ck_pr_bts \ + ck_pr_btc \ + ck_pr_btr \ + ck_pr_store \ + ck_pr_load \ + ck_ring_init \ + ck_ring_dequeue_spmc \ + ck_ring_enqueue_spmc \ + ck_ring_enqueue_spmc_size \ + ck_ring_trydequeue_spmc \ + ck_ring_dequeue_spsc \ + ck_ring_enqueue_spsc \ + ck_ring_enqueue_spsc_size all: for target in $(OBJECTS); do \ $(GZIP) $(SRC_DIR)/doc/$$target > $(BUILD_DIR)/doc/$$target$(GZIP_SUFFIX); \ done +html: + for target in $(OBJECTS); do \ + echo $$target; \ + groff -man -Tascii $(SRC_DIR)/doc/$$target | \ + man2html -noheads -bare -cgiurl='$$title.html' > \ + $(BUILD_DIR)/doc/$$target$(HTML_SUFFIX); \ + done + install: mkdir -p $(DESTDIR)/$(MANDIR)/man3 || exit cp *$(GZIP_SUFFIX) $(DESTDIR)/$(MANDIR)/man3 || exit @@ -100,5 +141,5 @@ uninstall: done clean: - rm -f $(BUILD_DIR)/doc/*~ $(BUILD_DIR)/doc/*.3.gz + rm -f $(BUILD_DIR)/doc/*~ $(BUILD_DIR)/doc/*.3.gz $(BUILD_DIR)/doc/*.html diff --git a/doc/ck_bag_init b/doc/ck_bag_init index e4eb254..8e5df75 100644 --- a/doc/ck_bag_init +++ b/doc/ck_bag_init @@ -35,7 +35,7 @@ Concurrency Kit (libck, \-lck) .Sh SYNOPSIS .In ck_bag.h .Ft bool -.Fn ck_bag_init "struct ck_bag *bag, size_t n_cachelines, enum ck_bag_allocation_strategy as" +.Fn ck_bag_init "struct ck_bag *bag" "size_t n_cachelines" "enum ck_bag_allocation_strategy as" .Sh DESCRIPTION The .Fn ck_bag_init diff --git a/doc/ck_bag_set_spmc b/doc/ck_bag_set_spmc index 4da8992..7bf262e 100644 --- a/doc/ck_bag_set_spmc +++ b/doc/ck_bag_set_spmc @@ -29,7 +29,7 @@ .Dt CK_BAG_SET_SPMC 3 .Sh NAME .Nm ck_bag_set_spmc -.Nd Replace the first occurence of a value in a bag. Insert value into the bag if value didn't previously exist. +.Nd replace the first occurence of a value in a bag .Sh LIBRARY Concurrency Kit (libck, \-lck) .Sh SYNOPSIS diff --git a/doc/ck_cohort b/doc/ck_cohort index a053385..d948db6 100644 --- a/doc/ck_cohort +++ b/doc/ck_cohort @@ -28,7 +28,7 @@ .Dt ck_cohort 3 .Sh NAME .Nm ck_cohort -.Nd Generalized interface for lock cohorts +.Nd generalized interface for lock cohorts .Sh LIBRARY Concurrency Kit (libck, \-lck) .Sh SYNOPSIS @@ -87,7 +87,6 @@ man pages for more details. .Pp .Sh EXAMPLE .Bd -literal -offset indent - #include #include @@ -133,7 +132,7 @@ CK_COHORT_PROTOTYPE(test_cohort, static ck_spinlock_t global_lock = CK_SPINLOCK_INITIALIZER; static unsigned int ready; -static void* +static void * function(void *context) { CK_COHORT_INSTANCE(test_cohort) *cohort = context; @@ -197,7 +196,7 @@ main(void) return 0; } - +.Ed .Sh SEE ALSO .Xr CK_COHORT_PROTOTYPE 3 , .Xr CK_COHORT_TRYLOCK_PROTOTYPE 3 , diff --git a/doc/ck_epoch_barrier b/doc/ck_epoch_barrier index c0087c0..e4b63ac 100644 --- a/doc/ck_epoch_barrier +++ b/doc/ck_epoch_barrier @@ -95,6 +95,7 @@ function(void) free(s); return; } +.Ed .Sh RETURN VALUES This function has no return value. .Sh ERRORS diff --git a/doc/ck_epoch_call b/doc/ck_epoch_call index 132b9d0..2736488 100644 --- a/doc/ck_epoch_call +++ b/doc/ck_epoch_call @@ -33,9 +33,7 @@ Concurrency Kit (libck, \-lck) .Sh SYNOPSIS .In ck_epoch.h - typedef struct ck_epoch_entry ck_epoch_entry_t; - typedef void ck_epoch_cb_t(ck_epoch_entry_t *); .Ft void .Fn ck_epoch_call "ck_epoch_t *epoch" "ck_epoch_record_t *record" "ck_epoch_entry_t *entry" "ck_epoch_cb_t *function" @@ -114,6 +112,7 @@ function(void) ck_epoch_poll(&epoch, record); return; } +.Ed .Sh RETURN VALUES This function has no return value. .Sh ERRORS diff --git a/doc/ck_epoch_synchronize b/doc/ck_epoch_synchronize index 08bd4f0..e1b8ab3 100644 --- a/doc/ck_epoch_synchronize +++ b/doc/ck_epoch_synchronize @@ -99,6 +99,7 @@ function(void) free(s); return; } +.Ed .Sh RETURN VALUES This function has no return value. .Sh ERRORS diff --git a/doc/ck_hs_destroy b/doc/ck_hs_destroy index 7d05b21..33d1f70 100644 --- a/doc/ck_hs_destroy +++ b/doc/ck_hs_destroy @@ -28,7 +28,7 @@ .Dt CK_HS_DESTROY 3 .Sh NAME .Nm ck_hs_destroy -.Nd initialize a hash set +.Nd destroy hash set .Sh LIBRARY Concurrency Kit (libck, \-lck) .Sh SYNOPSIS @@ -43,7 +43,6 @@ function will request that the underlying allocator, as specified by the function, immediately destroy the object pointed to by the .Fa hs argument. - The user must guarantee that no threads are accessing the object pointed to by .Fa hs diff --git a/doc/ck_hs_iterator_init b/doc/ck_hs_iterator_init index b6ffe54..5fe2d42 100644 --- a/doc/ck_hs_iterator_init +++ b/doc/ck_hs_iterator_init @@ -28,7 +28,7 @@ .Dt CK_HS_ITERATOR_INIT 3 .Sh NAME .Nm ck_hs_iterator_init -.Nd initialize a hash set +.Nd initialize hash set iterator .Sh LIBRARY Concurrency Kit (libck, \-lck) .Sh SYNOPSIS diff --git a/doc/ck_hs_stat b/doc/ck_hs_stat index 1f89f9a..b4ad5a9 100644 --- a/doc/ck_hs_stat +++ b/doc/ck_hs_stat @@ -48,6 +48,7 @@ struct ck_hs_stat { unsigned long n_entries; /* Current number of keys in hash set. */ unsigned int probe_maximum; /* Longest read-side probe sequence. */ }; +.Ed .Sh RETURN VALUES .Fn ck_hs_stat 3 has no return value. diff --git a/doc/ck_ht_stat b/doc/ck_ht_stat index 8b9c00e..1d1f55d 100644 --- a/doc/ck_ht_stat +++ b/doc/ck_ht_stat @@ -47,6 +47,7 @@ struct ck_ht_stat { uint64_t probe_maximum; /* Longest read-side probe sequence. */ uint64_t n_entries; /* Current number of keys in hash set. */ }; +.Ed .Sh RETURN VALUES .Fn ck_ht_stat 3 has no return value. diff --git a/doc/ck_pr b/doc/ck_pr new file mode 100644 index 0000000..ad77a47 --- /dev/null +++ b/doc/ck_pr @@ -0,0 +1,69 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 7, 2013 +.Dt ck_pr 3 +.Sh NAME +.Nm ck_pr +.Nd concurrency primitives interface +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Sh DESCRIPTION +ck_pr.h provides an interface to volatile atomic instructions, +memory barriers and busy-wait facilities as provided by the +underlying processor. The presence of an atomic operation +is detected by the presence of a corresponding CK_F_PR macro. +For example, the availability of +.Xr ck_pr_add_16 3 +would be determined by the presence of CK_F_PR_ADD_16. +.Sh SEE ALSO +.Xr ck_pr_stall 3 , +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_barrier 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_add b/doc/ck_pr_add new file mode 100644 index 0000000..3fe2c19 --- /dev/null +++ b/doc/ck_pr_add @@ -0,0 +1,85 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 11, 2013 +.Dt ck_pr_add 3 +.Sh NAME +.Nm ck_pr_add +.Nd atomic addition operation +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft void +.Fn ck_pr_add_ptr "void *target" "uintptr_t delta" +.Ft void +.Fn ck_pr_add_double "double *target" "double delta" +.Ft void +.Fn ck_pr_add_char "char *target" "char delta" +.Ft void +.Fn ck_pr_add_uint "unsigned int *target" "unsigned int delta" +.Ft void +.Fn ck_pr_add_int "int *target" "int delta" +.Ft void +.Fn ck_pr_add_64 "uint64_t *target" "uint64_t delta" +.Ft void +.Fn ck_pr_add_32 "uint32_t *target" "uint32_t delta" +.Ft void +.Fn ck_pr_add_16 "uint16_t *target" "uint16_t delta" +.Ft void +.Fn ck_pr_add_8 "uint8_t *target" "uint8_t delta" +.Sh DESCRIPTION +The +.Fn ck_pr_add 3 +family of functions atomically add the value specified by +.Fa delta +to the value pointed to by +.Fa target . +.Sh RETURN VALUES +This family of functions does not have a return value. +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_and b/doc/ck_pr_and new file mode 100644 index 0000000..4496149 --- /dev/null +++ b/doc/ck_pr_and @@ -0,0 +1,86 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 11, 2013 +.Dt ck_pr_and 3 +.Sh NAME +.Nm ck_pr_and +.Nd atomic bitwise-and operation +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft void +.Fn ck_pr_and_ptr "void *target" "uintptr_t delta" +.Ft void +.Fn ck_pr_and_char "char *target" "char delta" +.Ft void +.Fn ck_pr_and_uint "unsigned int *target" "unsigned int delta" +.Ft void +.Fn ck_pr_and_int "int *target" "int delta" +.Ft void +.Fn ck_pr_and_64 "uint64_t *target" "uint64_t delta" +.Ft void +.Fn ck_pr_and_32 "uint32_t *target" "uint32_t delta" +.Ft void +.Fn ck_pr_and_16 "uint16_t *target" "uint16_t delta" +.Ft void +.Fn ck_pr_and_8 "uint8_t *target" "uint8_t delta" +.Sh DESCRIPTION +The +.Fn ck_pr_and 3 +family of functions atomically compute and store the +result of a bitwise-and of the value pointed to by +.Fa target +and +.Fa delta +into the value pointed to by +.Fa target . +.Sh RETURN VALUES +This family of functions does not have a return value. +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_barrier b/doc/ck_pr_barrier new file mode 100644 index 0000000..128bf38 --- /dev/null +++ b/doc/ck_pr_barrier @@ -0,0 +1,66 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 7, 2013 +.Dt ck_pr_barrier 3 +.Sh NAME +.Nm ck_pr_barrier +.Nd compiler optimization barrier +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft void +.Fn ck_pr_barrier void +.Sh DESCRIPTION +The +.Fn ck_pr_barrier 3 +function is used to disable code movement optimizations +across the invocation of the function. +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_btc b/doc/ck_pr_btc new file mode 100644 index 0000000..55ced4a --- /dev/null +++ b/doc/ck_pr_btc @@ -0,0 +1,85 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 11, 2013 +.Dt ck_pr_btc 3 +.Sh NAME +.Nm ck_pr_btc +.Nd atomic bit test-and-complement operation +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft bool +.Fn ck_pr_btc_ptr "void *target" "unsigned int bit_index" +.Ft bool +.Fn ck_pr_btc_uint "uint *target" "unsigned int bit_index" +.Ft bool +.Fn ck_pr_btc_int "int *target" "unsigned int bit_index" +.Ft bool +.Fn ck_pr_btc_64 "uint64_t *target" "unsigned int bit_index" +.Ft bool +.Fn ck_pr_btc_32 "uint32_t *target" "unsigned int bit_index" +.Ft bool +.Fn ck_pr_btc_16 "uint16_t *target" "unsigned int bit_index" +.Sh DESCRIPTION +The +.Fn ck_pr_btc 3 +family of functions atomically fetch the value +of the bit in +.Fa target +at index +.Fa bit_index +and set that bit to its complement. +.Sh RETURN VALUES +These family of functions return the original value of +the bit at offset +.Fa bit_index +that is in the value pointed to by +.Fa target . +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_btr 3 , +.Xr ck_pr_cas 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_btr b/doc/ck_pr_btr new file mode 100644 index 0000000..fefa32a --- /dev/null +++ b/doc/ck_pr_btr @@ -0,0 +1,85 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 11, 2013 +.Dt ck_pr_btr 3 +.Sh NAME +.Nm ck_pr_btr +.Nd atomic bit test-and-reset operation +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft bool +.Fn ck_pr_btr_ptr "void *target" "unsigned int bit_index" +.Ft bool +.Fn ck_pr_btr_uint "uint *target" "unsigned int bit_index" +.Ft bool +.Fn ck_pr_btr_int "int *target" "unsigned int bit_index" +.Ft bool +.Fn ck_pr_btr_64 "uint64_t *target" "unsigned int bit_index" +.Ft bool +.Fn ck_pr_btr_32 "uint32_t *target" "unsigned int bit_index" +.Ft bool +.Fn ck_pr_btr_16 "uint16_t *target" "unsigned int bit_index" +.Sh DESCRIPTION +The +.Fn ck_pr_btr 3 +family of functions atomically fetch the value +of the bit in +.Fa target +at index +.Fa bit_index +and set that bit to 0. +.Sh RETURN VALUES +This family of functions returns the original value of +the bit at offset +.Fa bit_index +that is in the value pointed to by +.Fa target . +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_cas 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_bts b/doc/ck_pr_bts new file mode 100644 index 0000000..7cf1a0a --- /dev/null +++ b/doc/ck_pr_bts @@ -0,0 +1,85 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 11, 2013 +.Dt ck_pr_bts 3 +.Sh NAME +.Nm ck_pr_bts +.Nd atomic bit test-and-set operation +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft bool +.Fn ck_pr_bts_ptr "void *target" "unsigned int bit_index" +.Ft bool +.Fn ck_pr_bts_uint "uint *target" "unsigned int bit_index" +.Ft bool +.Fn ck_pr_bts_int "int *target" "unsigned int bit_index" +.Ft bool +.Fn ck_pr_bts_64 "uint64_t *target" "unsigned int bit_index" +.Ft bool +.Fn ck_pr_bts_32 "uint32_t *target" "unsigned int bit_index" +.Ft bool +.Fn ck_pr_bts_16 "uint16_t *target" "unsigned int bit_index" +.Sh DESCRIPTION +The +.Fn ck_pr_bts 3 +family of functions atomically fetch the value +of the bit in +.Fa target +at index +.Fa bit_index +and set that bit to 1. +.Sh RETURN VALUES +This family of functions returns the original value of +the bit at offset +.Fa bit_index +that is in the value pointed to by +.Fa target . +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_btr 3 , +.Xr ck_pr_cas 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_cas b/doc/ck_pr_cas new file mode 100644 index 0000000..fe6fc3f --- /dev/null +++ b/doc/ck_pr_cas @@ -0,0 +1,130 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 11, 2013 +.Dt ck_pr_cas 3 +.Sh NAME +.Nm ck_pr_cas +.Nd atomic compare-and-swap operation +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft bool +.Fn ck_pr_cas_ptr "void *target" "void *old_value" "void *new_value" +.Ft bool +.Fn ck_pr_cas_ptr_value "void *target" "void *old_value" "void *new_value" "void *original_value" +.Ft bool +.Fn ck_pr_cas_ptr_2 "void *target" "void *old_value" "void *new_value" +.Ft bool +.Fn ck_pr_cas_ptr_2_value "void *target" "void *old_value" "void *new_value" "void *original_value" +.Ft bool +.Fn ck_pr_cas_double "double *target" "double old_value" "double new_value" +.Ft bool +.Fn ck_pr_cas_double_value "double *target" "double old_value" "double new_value" "double *original_value" +.Ft bool +.Fn ck_pr_cas_char "char *target" "char old_value" "char new_value" +.Ft bool +.Fn ck_pr_cas_char_value "char *target" "char old_value" "char new_value" "char *original_value" +.Ft bool +.Fn ck_pr_cas_uint "unsigned int *target" "unsigned int old_value" "unsigned int new_value" +.Ft bool +.Fn ck_pr_cas_uint_value "unsigned int *target" "unsigned int old_value" "unsigned int new_value" "unsigned int *original_value" +.Ft bool +.Fn ck_pr_cas_int "int *target" "int old_value" "int new_value" +.Ft bool +.Fn ck_pr_cas_int_value "int *target" "int old_value" "int new_value" "int *original_value" +.Ft bool +.Fn ck_pr_cas_64_2 "uint64_t target[static 2]" "uint64_t old_value[static 2]" "uint64_t new_value[static 2]" +.Ft bool +.Fn ck_pr_cas_64_2_value "uint64_t target[static 2]" "uint64_t old_value[static 2]" "uint64_t new_value[static 2]" "uint64_t original_value[static 2]" +.Ft bool +.Fn ck_pr_cas_64 "uint64_t *target" "uint64_t old_value" "uint64_t new_value" +.Ft bool +.Fn ck_pr_cas_64_value "uint64_t *target" "uint64_t old_value" "uint64_t new_value" "uint64_t *original_value" +.Ft bool +.Fn ck_pr_cas_64_2 "uint64_t target[static 2]" "uint64_t old_value[static 2]" "uint64_t new_value[static 2]" +.Ft bool +.Fn ck_pr_cas_64_2_value "uint64_t target[static 2]" "uint64_t old_value[static 2]" "uint64_t new_value[static 2]" "uint64_t original_value[static 2]" +.Ft bool +.Fn ck_pr_cas_32 "uint32_t *target" "uint32_t old_value" "uint32_t new_value" +.Ft bool +.Fn ck_pr_cas_32_value "uint32_t *target" "uint32_t old_value" "uint32_t new_value" "uint32_t *original_value" +.Ft bool +.Fn ck_pr_cas_16 "uint16_t *target" "uint16_t old_value" "uint16_t new_value" +.Ft bool +.Fn ck_pr_cas_16_value "uint16_t *target" "uint16_t old_value" "uint16_t new_value" "uint16_t *original_value" +.Ft bool +.Fn ck_pr_cas_8 "uint8_t *target" "uint8_t old_value" "uint8_t new_value" +.Ft bool +.Fn ck_pr_cas_8_value "uint8_t *target" "uint8_t old_value" "uint8_t new_value" "uint8_t *original_value" +.Sh DESCRIPTION +The +.Fn ck_pr_cas 3 +family of functions atomically compare the value in +.Fa target +for equality with +.Fa old_value +and if so, replace the value pointed to by +.Fa target +with the value specified by +.Fa original_value . +If the value in +.Fa target +was not equal to the value specified by +.Fa old_value +then no modifications occur to the value in +.Fa target . +The *_value form of these functions unconditionally update +.Fa original_value . +.Sh RETURN VALUES +This family of functions return true if the value in +.Fa target +was modified as a result of the operation. Otherwise, they +return false. +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_dec b/doc/ck_pr_dec new file mode 100644 index 0000000..2aa4375 --- /dev/null +++ b/doc/ck_pr_dec @@ -0,0 +1,104 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 7, 2013 +.Dt ck_pr_dec 3 +.Sh NAME +.Nm ck_pr_dec +.Nd atomic decrement operation +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft void +.Fn ck_pr_dec_ptr "void *target" +.Ft bool +.Fn ck_pr_dec_ptr_zero "void *target" +.Ft void +.Fn ck_pr_dec_double "double *target" +.Ft bool +.Fn ck_pr_dec_double_zero "double *target" +.Ft void +.Fn ck_pr_dec_char "char *target" +.Ft bool +.Fn ck_pr_dec_char_zero "char *target" +.Ft void +.Fn ck_pr_dec_uint "unsigned int *target" +.Ft bool +.Fn ck_pr_dec_uint_zero "unsigned int *target" +.Ft void +.Fn ck_pr_dec_int "int *target" +.Ft bool +.Fn ck_pr_dec_int_zero "int *target" +.Ft void +.Fn ck_pr_dec_64 "uint64_t *target" +.Ft bool +.Fn ck_pr_dec_64_zero "uint64_t *target" +.Ft void +.Fn ck_pr_dec_32 "uint32_t *target" +.Ft bool +.Fn ck_pr_dec_32_zero "uint32_t *target" +.Ft void +.Fn ck_pr_dec_16 "uint16_t *target" +.Ft bool +.Fn ck_pr_dec_16_zero "uint16_t *target" +.Ft void +.Fn ck_pr_dec_8 "uint8_t *target" +.Ft bool +.Fn ck_pr_dec_8_zero "uint8_t *target" +.Sh DESCRIPTION +The +.Fn ck_pr_dec 3 +family of functions atomically decrement the value pointed to +by +.Fa target . +.Sh RETURN VALUES +The ck_pr_dec_zero family of functions returns true if the result +of the decrement operation was 0. They return +false otherwise. +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_faa b/doc/ck_pr_faa new file mode 100644 index 0000000..9622a36 --- /dev/null +++ b/doc/ck_pr_faa @@ -0,0 +1,91 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 7, 2013 +.Dt ck_pr_faa 3 +.Sh NAME +.Nm ck_pr_faa +.Nd atomic fetch-and-add operation +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft uintptr_t +.Fn ck_pr_faa_ptr "void *target" "uintptr_t delta" +.Ft double +.Fn ck_pr_faa_double "double *target" "double delta" +.Ft char +.Fn ck_pr_faa_char "char *target" "char delta" +.Ft unsigned int +.Fn ck_pr_faa_uint "unsigned int *target" "unsigned int delta" +.Ft int +.Fn ck_pr_faa_int "int *target" "int delta" +.Ft uint64_t +.Fn ck_pr_faa_64 "uint64_t *target" "uint64_t delta" +.Ft uint32_t +.Fn ck_pr_faa_32 "uint32_t *target" "uint32_t delta" +.Ft uint16_t +.Fn ck_pr_faa_16 "uint16_t *target" "uint16_t delta" +.Ft uint8_t +.Fn ck_pr_faa_8 "uint8_t *target" "uint8_t delta" +.Sh DESCRIPTION +The +.Fn ck_pr_faa 3 +family of functions atomically fetch the value pointed to +by +.Fa target +and add the value specified by +.Fa delta +to the value pointed to by +.Fa target . +.Sh RETURN VALUES +This function returns the value pointed to by +.Fa target +at the time of operation invocation before the +addition operation is applied. +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_fas b/doc/ck_pr_fas new file mode 100644 index 0000000..ce5e6f3 --- /dev/null +++ b/doc/ck_pr_fas @@ -0,0 +1,92 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 7, 2013 +.Dt ck_pr_fas 3 +.Sh NAME +.Nm ck_pr_fas +.Nd atomic swap operation +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft void * +.Fn ck_pr_fas_ptr "void *target" "void *new_value" +.Ft double +.Fn ck_pr_fas_double "double *target" "double new_value" +.Ft char +.Fn ck_pr_fas_char "char *target" "char new_value" +.Ft unsigned int +.Fn ck_pr_fas_uint "unsigned int *target" "unsigned int new_value" +.Ft int +.Fn ck_pr_fas_int "int *target" "int new_value" +.Ft uint64_t +.Fn ck_pr_fas_64 "uint64_t *target" "uint64_t new_value" +.Ft uint32_t +.Fn ck_pr_fas_32 "uint32_t *target" "uint32_t new_value" +.Ft uint16_t +.Fn ck_pr_fas_16 "uint16_t *target" "uint16_t new_value" +.Ft uint8_t +.Fn ck_pr_fas_8 "uint8_t *target" "uint8_t new_value" +.Sh DESCRIPTION +The +.Fn ck_pr_fas 3 +family of functions atomically fetch the value pointed to +by +.Fa target +and replace the value pointed to by +.Fa target +with the value specified by +.Fa new_value . +.Sh RETURN VALUES +This function returns the value pointed to by +.Fa target +at the time of operation invocation before it was +atomically replaced with +.Fa new_value . +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_fence_load b/doc/ck_pr_fence_load new file mode 100644 index 0000000..97cb848 --- /dev/null +++ b/doc/ck_pr_fence_load @@ -0,0 +1,108 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 7, 2013 +.Dt ck_pr_fence_load 3 +.Sh NAME +.Nm ck_pr_fence_load +.Nd enforce partial ordering of load operations +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft void +.Fn ck_pr_fence_load void +.Ft void +.Fn ck_pr_fence_strict_load void +.Sh DESCRIPTION +This function enforces the ordering of any memory load +and +.Fn ck_pr_load 3 +operations relative to the invocation of the function. Any +store operations that were committed on remote processors +and received by the calling processor before the invocation of +.Fn ck_pr_fence_load +is also be made visible only after a call to +.Fn ck_pr_fence_load . +This function always serves as an implicit compiler barrier. +On architectures with CK_MD_TSO or CK_MD_PSO specified (total store ordering +and partial store ordering respectively), this operation only serves +as a compiler barrier and no fence instructions will be emitted. To +force the unconditional emission of a load fence, use +.Fn ck_pr_fence_strict_load . +Architectures implementing CK_MD_RMO always emit a load fence. +.Sh EXAMPLE +.Bd -literal -offset indent + +#include + +static unsigned int a; +static unsigned int b; + +void +function(void) +{ + unsigned int snapshot_a, snapshot_b; + + snapshot_a = ck_pr_load_uint(&a); + + /* + * Guarantee that the load from "a" completes + * before the load from "b". + */ + ck_pr_fence_load(); + snapshot_b = ck_pr_load_uint(&b); + + return; +} +.Ed +.Sh RETURN VALUES +This function has no return value. +.Sh SEE ALSO +.Xr ck_pr_stall 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_barrier 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_fence_load_depends b/doc/ck_pr_fence_load_depends new file mode 100644 index 0000000..7a98389 --- /dev/null +++ b/doc/ck_pr_fence_load_depends @@ -0,0 +1,70 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 7, 2013 +.Dt ck_pr_fence_load_depends 3 +.Sh NAME +.Nm ck_pr_fence_load_depends +.Nd data dependency barrier +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft void +.Fn ck_pr_fence_load_depends void +.Sh DESCRIPTION +The +.Fn ck_pr_fence_load_depends 3 +emits necessary fences for pure data-dependent loads. It currently only serves as a compiler +barrier for Concurrency Kit's supported platforms. Unless you're on architecture +which re-orders data-dependent loads (such as the defunct Alpha), this function is unnecessary. +.Sh RETURN VALUES +This function has no return value. +.Sh SEE ALSO +.Xr ck_pr_stall 3 , +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_barrier 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_fence_memory b/doc/ck_pr_fence_memory new file mode 100644 index 0000000..31eed57 --- /dev/null +++ b/doc/ck_pr_fence_memory @@ -0,0 +1,110 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 7, 2013 +.Dt ck_pr_fence_memory 3 +.Sh NAME +.Nm ck_pr_fence_memory +.Nd enforce partial ordering of all memory operations +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft void +.Fn ck_pr_fence_memory +.Ft void +.Fn ck_pr_fence_strict_memory +.Sh DESCRIPTION +The +.Fn ck_pr_fence_memory 3 +function enforces the ordering of any memory operations +with respect to the invocation of the function. This function +always serves as an implicit compiler barrier. +Achitectures implementing CK_MD_TSO do not emit +a barrier, but compiler barrier semantics remain. +Architectures implementing CK_MD_PSO and CK_MD_RMO always emit +an instructions which provides the specified ordering +guarantees. To force the unconditional emission of a memory +fence, use +.Fn ck_pr_fence_strict_memory . +.Sh EXAMPLE +.Bd -literal -offset indent + +#include + +static int a = 0; +static int b; +static int c; +static int d; + +void +function(void) +{ + int snapshot_a; + + ck_pr_store_int(&b, 1); + snapshot_a = ck_pr_load_int(&a); + + /* + * Make sure previous memory operations are + * ordered with respect to memory operations + * following the ck_pr_fence_memory. + */ + ck_pr_fence_memory(); + + ck_pr_store_int(&d, 3); + ck_pr_store_int(&c, 2); + + return; +} +.Ed +.Sh RETURN VALUES +This function has no return value. +.Sh SEE ALSO +.Xr ck_pr_stall 3 , +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_barrier 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_fence_store b/doc/ck_pr_fence_store new file mode 100644 index 0000000..0fa573d --- /dev/null +++ b/doc/ck_pr_fence_store @@ -0,0 +1,107 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 7, 2013 +.Dt ck_pr_fence_store 3 +.Sh NAME +.Nm ck_pr_fence_store +.Nd enforce partial ordering of store operations +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft void +.Fn ck_pr_fence_store void +.Ft void +.Fn ck_pr_fence_strict_store void +.Sh DESCRIPTION +The +.Fn ck_pr_fence_store +function enfores the ordering of any memory store, +.Fn ck_pr_store +and atomic read-modify-write operations relative to +the invocation of the function. 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 +are emitted. On architectures implementing +CK_MD_PSO and CK_MD_RMO, a store fence is +emitted. To force the unconditional emission of +a store fence, use +.Fn ck_pr_fence_strict_store . +.Sh EXAMPLE +.Bd -literal -offset indent + +#include + +static int a = 0; +static int b = 0; +static int c = 0; + +void +function(void) +{ + + ck_pr_store_int(&a, 1); + + /* + * Guarantee that the store to a is completed + * with respect to the stores of b and c. + */ + ck_pr_fence_store(); + ck_pr_store_int(&b, 2); + ck_pr_store_int(&c, 2); + + return; +} +.Ed +.Sh RETURN VALUES +This function has no return value. +.Sh SEE ALSO +.Xr ck_pr_stall 3 , +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_barrier 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_inc b/doc/ck_pr_inc new file mode 100644 index 0000000..fe2cb9e --- /dev/null +++ b/doc/ck_pr_inc @@ -0,0 +1,104 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 7, 2013 +.Dt ck_pr_inc 3 +.Sh NAME +.Nm ck_pr_inc +.Nd atomic increment operation +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft void +.Fn ck_pr_inc_ptr "void *target" +.Ft bool +.Fn ck_pr_inc_ptr_zero "void *target" +.Ft void +.Fn ck_pr_inc_double "double *target" +.Ft bool +.Fn ck_pr_inc_double_zero "double *target" +.Ft void +.Fn ck_pr_inc_char "char *target" +.Ft bool +.Fn ck_pr_inc_char_zero "char *target" +.Ft void +.Fn ck_pr_inc_uint "unsigned int *target" +.Ft bool +.Fn ck_pr_inc_uint_zero "unsigned int *target" +.Ft void +.Fn ck_pr_inc_int "int *target" +.Ft bool +.Fn ck_pr_inc_int_zero "int *target" +.Ft void +.Fn ck_pr_inc_64 "uint64_t *target" +.Ft bool +.Fn ck_pr_inc_64_zero "uint64_t *target" +.Ft void +.Fn ck_pr_inc_32 "uint32_t *target" +.Ft bool +.Fn ck_pr_inc_32_zero "uint32_t *target" +.Ft void +.Fn ck_pr_inc_16 "uint16_t *target" +.Ft bool +.Fn ck_pr_inc_16_zero "uint16_t *target" +.Ft void +.Fn ck_pr_inc_8 "uint8_t *target" +.Ft bool +.Fn ck_pr_inc_8_zero "uint8_t *target" +.Sh DESCRIPTION +The +.Fn ck_pr_inc 3 +family of functions atomically increment the value pointed to +by +.Fa target . +.Sh RETURN VALUES +The ck_pr_inc_zero family of functions return true +if the result of the increment operation was 0. The functions return +false otherwise. +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_load b/doc/ck_pr_load new file mode 100644 index 0000000..3a0406b --- /dev/null +++ b/doc/ck_pr_load @@ -0,0 +1,88 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 15, 2013 +.Dt ck_pr_load 3 +.Sh NAME +.Nm ck_pr_load +.Nd atomic volatile load operation +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft void * +.Fn ck_pr_load_ptr "const void *target" +.Ft double +.Fn ck_pr_load_double "const double *target" +.Ft unsigned int +.Fn ck_pr_load_uint "const unsigned int *target" +.Ft int +.Fn ck_pr_load_int "const int *target" +.Ft char +.Fn ck_pr_load_char "const char *target" +.Ft uint64_t +.Fn ck_pr_load_64 "const uint64_t *target" +.Ft uint32_t +.Fn ck_pr_load_32 "const uint32_t *target" +.Ft uint16_t +.Fn ck_pr_load_16 "const uint16_t *target" +.Ft uint8_t +.Fn ck_pr_load_8 "const uint8_t *target" +.Sh DESCRIPTION +The +.Fn ck_pr_load 3 +family of functions atomically loads the value +pointed to by +.Fa target +and returns it. This family of functions always +serves as an implicit compiler barrier and is not +susceptible to re-ordering by the compiler. +.Sh RETURN VALUES +This family of functions returns the value contained +in the location pointed to by the first argument. +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_neg b/doc/ck_pr_neg new file mode 100644 index 0000000..fb441e8 --- /dev/null +++ b/doc/ck_pr_neg @@ -0,0 +1,103 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 7, 2013 +.Dt ck_pr_neg 3 +.Sh NAME +.Nm ck_pr_neg +.Nd atomic negation operation +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft void +.Fn ck_pr_neg_ptr "void *target" +.Ft bool +.Fn ck_pr_neg_ptr_zero "void *target" +.Ft void +.Fn ck_pr_neg_double "double *target" +.Ft bool +.Fn ck_pr_neg_double_zero "double *target" +.Ft void +.Fn ck_pr_neg_char "char *target" +.Ft bool +.Fn ck_pr_neg_char_zero "char *target" +.Ft void +.Fn ck_pr_neg_uint "unsigned int *target" +.Ft bool +.Fn ck_pr_neg_uint_zero "unsigned int *target" +.Ft void +.Fn ck_pr_neg_int "int *target" +.Ft bool +.Fn ck_pr_neg_int_zero "int *target" +.Ft void +.Fn ck_pr_neg_64 "uint64_t *target" +.Ft bool +.Fn ck_pr_neg_64_zero "uint64_t *target" +.Ft void +.Fn ck_pr_neg_32 "uint32_t *target" +.Ft bool +.Fn ck_pr_neg_32_zero "uint32_t *target" +.Ft void +.Fn ck_pr_neg_16 "uint16_t *target" +.Ft bool +.Fn ck_pr_neg_16_zero "uint16_t *target" +.Ft void +.Fn ck_pr_neg_8 "uint8_t *target" +.Ft bool +.Fn ck_pr_neg_8_zero "uint8_t *target" +.Sh DESCRIPTION +The +.Fn ck_pr_neg 3 +family of functions atomically negate the value pointed to +by +.Fa target . +.Sh RETURN VALUES +The ck_pr_neg_zero functions return true if the result +of the negation operation was 0. They return false otherwise. +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_not b/doc/ck_pr_not new file mode 100644 index 0000000..0847bf6 --- /dev/null +++ b/doc/ck_pr_not @@ -0,0 +1,84 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 7, 2013 +.Dt ck_pr_not 3 +.Sh NAME +.Nm ck_pr_not +.Nd atomic complement operation +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft void +.Fn ck_pr_not_ptr "void *target" +.Ft void +.Fn ck_pr_not_double "double *target" +.Ft void +.Fn ck_pr_not_char "char *target" +.Ft void +.Fn ck_pr_not_uint "unsigned int *target" +.Ft void +.Fn ck_pr_not_int "int *target" +.Ft void +.Fn ck_pr_not_64 "uint64_t *target" +.Ft void +.Fn ck_pr_not_32 "uint32_t *target" +.Ft void +.Fn ck_pr_not_16 "uint16_t *target" +.Ft void +.Fn ck_pr_not_8 "uint8_t *target" +.Sh DESCRIPTION +The +.Fn ck_pr_not 3 +family of functions atomically complement the value pointed to +by +.Fa target . +.Sh RETURN VALUES +These functions have no return value. +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_or b/doc/ck_pr_or new file mode 100644 index 0000000..dfb4a1e --- /dev/null +++ b/doc/ck_pr_or @@ -0,0 +1,86 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 11, 2013 +.Dt ck_pr_or 3 +.Sh NAME +.Nm ck_pr_or +.Nd atomic bitwise-or operation +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft void +.Fn ck_pr_or_ptr "void *target" "uintptr_t delta" +.Ft void +.Fn ck_pr_or_char "char *target" "char delta" +.Ft void +.Fn ck_pr_or_uint "unsigned int *target" "unsigned int delta" +.Ft void +.Fn ck_pr_or_int "int *target" "int delta" +.Ft void +.Fn ck_pr_or_64 "uint64_t *target" "uint64_t delta" +.Ft void +.Fn ck_pr_or_32 "uint32_t *target" "uint32_t delta" +.Ft void +.Fn ck_pr_or_16 "uint16_t *target" "uint16_t delta" +.Ft void +.Fn ck_pr_or_8 "uint8_t *target" "uint8_t delta" +.Sh DESCRIPTION +The +.Fn ck_pr_or 3 +family of functions atomically compute and store the +result of a bitwise-or of the value pointed to by +.Fa target +and +.Fa delta +into the value pointed to by +.Fa target . +.Sh RETURN VALUES +This family of functions does not have a return value. +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_stall b/doc/ck_pr_stall new file mode 100644 index 0000000..762a739 --- /dev/null +++ b/doc/ck_pr_stall @@ -0,0 +1,86 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 7, 2013 +.Dt ck_pr_stall 3 +.Sh NAME +.Nm ck_pr_stall +.Nd busy-wait primitive +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft void +.Fn ck_pr_stall void +.Sh DESCRIPTION +The +.Fn ck_pr_stall 3 +function should be used inside retry paths of busy-wait loops. +It not only serves as a compiler barrier, but on some architectures +it emits cycle-saving instructions. +.Sh EXAMPLE +.Bd -literal -offset indent + +#include + +static int ready = 0; + +void +function(void) +{ + + /* Busy-wait until ready is non-zero. */ + while (ck_pr_load_int(&ready) == 0) + ck_pr_stall(); + + return; +} +.Ed +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_barrier 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_store b/doc/ck_pr_store new file mode 100644 index 0000000..d4b527f --- /dev/null +++ b/doc/ck_pr_store @@ -0,0 +1,88 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 15, 2013 +.Dt ck_pr_store 3 +.Sh NAME +.Nm ck_pr_store +.Nd atomic volatile store operation +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft void +.Fn ck_pr_store_ptr "void *target" "void *value" +.Ft void +.Fn ck_pr_store_double "double *target" "double value" +.Ft void +.Fn ck_pr_store_uint "unsigned int *target" "unsigned int value" +.Ft void +.Fn ck_pr_store_int "int *target" "int value" +.Ft void +.Fn ck_pr_store_char "char *target" "char value" +.Ft void +.Fn ck_pr_store_64 "uint64_t *target" "uint64_t value" +.Ft void +.Fn ck_pr_store_32 "uint32_t *target" "uint32_t value" +.Ft void +.Fn ck_pr_store_16 "uint16_t *target" "uint16_t value" +.Ft void +.Fn ck_pr_store_8 "uint8_t *target" "uint8_t value" +.Sh DESCRIPTION +The +.Fn ck_pr_store 3 +family of functions atomically stores the value specified +by +.Fa value +into the location pointed to by +.Fa target . +This family of functions always serves as an implicit compiler +barrier and is not susceptible to compiler re-ordering. +.Sh RETURN VALUES +This family of functions has no return value. +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_sub b/doc/ck_pr_sub new file mode 100644 index 0000000..df03031 --- /dev/null +++ b/doc/ck_pr_sub @@ -0,0 +1,85 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 11, 2013 +.Dt ck_pr_sub 3 +.Sh NAME +.Nm ck_pr_sub +.Nd atomic subtraction operation +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft void +.Fn ck_pr_sub_ptr "void *target" "uintptr_t delta" +.Ft void +.Fn ck_pr_sub_double "double *target" "double delta" +.Ft void +.Fn ck_pr_sub_char "char *target" "char delta" +.Ft void +.Fn ck_pr_sub_uint "unsigned int *target" "unsigned int delta" +.Ft void +.Fn ck_pr_sub_int "int *target" "int delta" +.Ft void +.Fn ck_pr_sub_64 "uint64_t *target" "uint64_t delta" +.Ft void +.Fn ck_pr_sub_32 "uint32_t *target" "uint32_t delta" +.Ft void +.Fn ck_pr_sub_16 "uint16_t *target" "uint16_t delta" +.Ft void +.Fn ck_pr_sub_8 "uint8_t *target" "uint8_t delta" +.Sh DESCRIPTION +The +.Fn ck_pr_sub 3 +family of functions atomically subtract the value specified by +.Fa delta +from the value pointed to by +.Fa target . +.Sh RETURN VALUES +This family of functions does not have a return value. +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_xor 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_pr_xor b/doc/ck_pr_xor new file mode 100644 index 0000000..e3c1db8 --- /dev/null +++ b/doc/ck_pr_xor @@ -0,0 +1,86 @@ +.\" +.\" Copyright 2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 11, 2013 +.Dt ck_pr_xor 3 +.Sh NAME +.Nm ck_pr_xor +.Nd atomic bitwise-xor operation +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_pr.h +.Ft void +.Fn ck_pr_xor_ptr "void *target" "uintptr_t delta" +.Ft void +.Fn ck_pr_xor_char "char *target" "char delta" +.Ft void +.Fn ck_pr_xor_uint "unsigned int *target" "unsigned int delta" +.Ft void +.Fn ck_pr_xor_int "int *target" "int delta" +.Ft void +.Fn ck_pr_xor_64 "uint64_t *target" "uint64_t delta" +.Ft void +.Fn ck_pr_xor_32 "uint32_t *target" "uint32_t delta" +.Ft void +.Fn ck_pr_xor_16 "uint16_t *target" "uint16_t delta" +.Ft void +.Fn ck_pr_xor_8 "uint8_t *target" "uint8_t delta" +.Sh DESCRIPTION +The +.Fn ck_pr_xor 3 +family of functions atomically compute and store the +result of a bitwise-xor of the value pointed to by +.Fa target +and +.Fa delta +into the value pointed to by +.Fa target . +.Sh RETURN VALUES +This family of functions does not have a return value. +.Sh SEE ALSO +.Xr ck_pr_fence_load 3 , +.Xr ck_pr_fence_load_depends 3 , +.Xr ck_pr_fence_store 3 , +.Xr ck_pr_fence_memory 3 , +.Xr ck_pr_load 3 , +.Xr ck_pr_store 3 , +.Xr ck_pr_fas 3 , +.Xr ck_pr_faa 3 , +.Xr ck_pr_inc 3 , +.Xr ck_pr_dec 3 , +.Xr ck_pr_neg 3 , +.Xr ck_pr_not 3 , +.Xr ck_pr_add 3 , +.Xr ck_pr_sub 3 , +.Xr ck_pr_or 3 , +.Xr ck_pr_and 3 , +.Xr ck_pr_cas 3 , +.Xr ck_pr_btc 3 , +.Xr ck_pr_bts 3 , +.Xr ck_pr_btr 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_ring_dequeue_spmc b/doc/ck_ring_dequeue_spmc new file mode 100644 index 0000000..076ceec --- /dev/null +++ b/doc/ck_ring_dequeue_spmc @@ -0,0 +1,107 @@ +.\" +.\" Copyright 2012-2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 20, 2013 +.Dt CK_RING_DEQUEUE_SPMC 3 +.Sh NAME +.Nm ck_ring_dequeue_spmc +.Nd dequeue pointer from bounded FIFO +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_ring.h +.Ft bool +.Fn ck_ring_dequeue_spmc "ck_ring_t *ring" "void *result" +.Sh DESCRIPTION +The +.Fn ck_ring_dequeue_spmc 3 +function dequeues a pointer from the bounded buffer +pointed to by +.Fa ring +in FIFO fashion. The pointer is stored in the pointer +pointed to by +.Fa result . +If you are on non-POSIX platforms or wish for strict +compliance with C, then it is recommended to pass a +pointer of type void ** for +.Fa result . +This function is safe to call without locking for UINT_MAX +concurrent invocations of +.Fn ck_ring_dequeue_spmc 3 +or +.Fn ck_ring_trydequeue_spmc 3 +and up to one concurrent +.Fn ck_ring_enqueue_spmc 3 +or +.Fn ck_ring_tryenqueue_spmc 3 +invocation. This function provides lock-free progress +guarantees. +.Sh EXAMPLE +.Bd -literal -offset indent +#include + +/* This ring was previously initialized with ck_ring_init. */ +ck_ring_t ring; + +void +dequeue(void) +{ + void *result; + + /* Dequeue from ring until it is empty. */ + while (ck_ring_dequeue_spmc(&ring, &result) == true) { + /* + * Results contains the oldest pointer in ring + * since the dequeue operation returned true. + */ + operation(result); + } + + /* An empty ring was encountered, leave. */ + return; +} +.Ed +.Sh RETURN VALUES +The function returns true if the buffer was non-empty. +The result of the dequeue operation is stored in the +value pointed to by +.Fa result . +The function will return false if the buffer was empty +and the value in +.Fa result +will be undefined. +.Sh SEE ALSO +.Xr ck_ring_init 3 , +.Xr ck_ring_trydequeue_spmc 3 , +.Xr ck_ring_enqueue_spmc 3 , +.Xr ck_ring_enqueue_spmc_size 3 , +.Xr ck_ring_dequeue_spsc 3 , +.Xr ck_ring_enqueue_spsc 3 , +.Xr ck_ring_enqueue_spsc_size 3 , +.Xr ck_ring_capacity 3 , +.Xr ck_ring_size 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_ring_dequeue_spsc b/doc/ck_ring_dequeue_spsc new file mode 100644 index 0000000..ed362f1 --- /dev/null +++ b/doc/ck_ring_dequeue_spsc @@ -0,0 +1,103 @@ +.\" +.\" Copyright 2012-2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 20, 2013 +.Dt CK_RING_DEQUEUE_SPSC 3 +.Sh NAME +.Nm ck_ring_dequeue_spsc +.Nd dequeue pointer from bounded FIFO +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_ring.h +.Ft bool +.Fn ck_ring_dequeue_spsc "ck_ring_t *ring" "void *result" +.Sh DESCRIPTION +The +.Fn ck_ring_dequeue_spsc 3 +function dequeues a pointer from the bounded buffer +pointed to by +.Fa ring +in FIFO fashion. The pointer is stored in the pointer +pointed to by +.Fa result . +If you are on non-POSIX platforms or wish for strict +compliance with C, then it is recommended to pass a +pointer of type void ** for +.Fa result . +This function is safe to call without locking for one +concurrent invocation of +.Fn ck_ring_dequeue_spsc 3 +and up to one concurrent +.Fn ck_ring_enqueue_spsc 3 +invocation. This function provides wait-free progress +guarantees. +.Sh EXAMPLE +.Bd -literal -offset indent +#include + +/* This ring was previously initialized with ck_ring_init. */ +ck_ring_t ring; + +void +dequeue(void) +{ + void *result; + + /* Dequeue from ring until it is empty. */ + while (ck_ring_dequeue_spsc(&ring, &result) == true) { + /* + * Results contains the oldest pointer in ring + * since the dequeue operation returned true. + */ + operation(result); + } + + /* An empty ring was encountered, leave. */ + return; +} +.Ed +.Sh RETURN VALUES +The function returns true if the buffer was non-empty. +The result of the dequeue operation is stored in the +value pointed to by +.Fa result . +The function will return false if the buffer was empty +and the value in +.Fa result +will be undefined. +.Sh SEE ALSO +.Xr ck_ring_init 3 , +.Xr ck_ring_trydequeue_spmc 3 , +.Xr ck_ring_enqueue_spmc 3 , +.Xr ck_ring_enqueue_spmc_size 3 , +.Xr ck_ring_dequeue_spmc 3 , +.Xr ck_ring_enqueue_spsc 3 , +.Xr ck_ring_enqueue_spsc_size 3 , +.Xr ck_ring_capacity 3 , +.Xr ck_ring_size 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_ring_enqueue_spmc b/doc/ck_ring_enqueue_spmc new file mode 100644 index 0000000..12732aa --- /dev/null +++ b/doc/ck_ring_enqueue_spmc @@ -0,0 +1,103 @@ +.\" +.\" Copyright 2012-2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 20, 2013 +.Dt CK_RING_ENQUEUE_SPMC 3 +.Sh NAME +.Nm ck_ring_enqueue_spmc +.Nd enqueue pointer into bounded FIFO +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_ring.h +.Ft bool +.Fn ck_ring_enqueue_spmc "ck_ring_t *ring" "void *entry" +.Sh DESCRIPTION +The +.Fn ck_ring_enqueue_spmc 3 +function enqueues the pointer +.Fa entry +into the bounded buffer pointed to by +.Fa ring +in FIFO fashion. +If you are on non-POSIX platforms or wish for strict +compliance with C, then it is recommended to pass a +pointer of type void ** for +.Fa entry . +This function is safe to call without locking for UINT_MAX +concurrent invocations of +.Fn ck_ring_dequeue_spmc 3 +or +.Fn ck_ring_trydequeue_spmc 3 . +This function provides wait-free progress +guarantees for one active invocation. +.Sh EXAMPLE +.Bd -literal -offset indent +#include + +/* This ring was previously initialized with ck_ring_init. */ +ck_ring_t ring; + +void +enqueue(void) +{ + void *entry = some_object; + + /* Attempt to enqueue pointer to some_object into buffer. */ + if (ck_ring_enqueue_spmc(&ring, &entry) == false) { + /* + * The buffer was full and the enqueue operation + * has failed. + */ + return; + } + + /* Enqueue operation completed successfully. */ + return; +} +.Ed +.Sh RETURN VALUES +The function returns true if the value of +.Fa entry +was successfully enqueued into +.Fa ring . +The function will return false if the value of +.Fa entry +could not be enqueued which only occurs if +.Fa ring +was full. +.Sh SEE ALSO +.Xr ck_ring_init 3 , +.Xr ck_ring_dequeue_spmc 3 , +.Xr ck_ring_trydequeue_spmc 3 , +.Xr ck_ring_enqueue_spmc_size 3 , +.Xr ck_ring_dequeue_spsc 3 , +.Xr ck_ring_enqueue_spsc 3 , +.Xr ck_ring_enqueue_spsc_size 3 , +.Xr ck_ring_capacity 3 , +.Xr ck_ring_size 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_ring_enqueue_spmc_size b/doc/ck_ring_enqueue_spmc_size new file mode 100644 index 0000000..a137789 --- /dev/null +++ b/doc/ck_ring_enqueue_spmc_size @@ -0,0 +1,115 @@ +.\" +.\" Copyright 2012-2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 20, 2013 +.Dt CK_RING_ENQUEUE_SPMC_SIZE 3 +.Sh NAME +.Nm ck_ring_enqueue_spmc_size +.Nd enqueue pointer into bounded FIFO and return size of buffer +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_ring.h +.Ft bool +.Fn ck_ring_enqueue_spmc_size "ck_ring_t *ring" "void *entry" "unsigned int *length" +.Sh DESCRIPTION +The +.Fn ck_ring_enqueue_spmc 3 +function enqueues the pointer +.Fa entry +into the bounded buffer pointed to by +.Fa ring +in FIFO fashion. +If you are on non-POSIX platforms or wish for strict +compliance with C, then it is recommended to pass a +pointer of type void ** for +.Fa entry . +This function is safe to call without locking for UINT_MAX +concurrent invocations of +.Fn ck_ring_dequeue_spmc 3 +or +.Fn ck_ring_trydequeue_spmc 3 . +This function provides wait-free progress +guarantees for one active invocation. +.Sh EXAMPLE +.Bd -literal -offset indent +#include + +/* This ring was previously initialized with ck_ring_init. */ +ck_ring_t ring; + +void +enqueue(void) +{ + void *entry = some_object; + unsigned int length; + + /* Attempt to enqueue pointer to some_object into buffer. */ + if (ck_ring_enqueue_spmc_size(&ring, &entry, &length) == false) { + /* + * The buffer was full and the enqueue operation + * has failed. + */ + return; + } + + /* + * If entry was the 101st or greater pointer in the buffer, + * do something. + */ + if (length > 100) { + do_something; + } + + return; +} +.Ed +.Sh RETURN VALUES +The function returns true if the value of +.Fa entry +was successfully enqueued into +.Fa ring . +The function will return false if the value of +.Fa entry +could not be enqueued which only occurs if +.Fa ring +was full. The number of entries in the buffer +with respect to the point in time that +.Fa entry +is enqueued is stored in the integer pointed to by +.Fa length . +.Sh SEE ALSO +.Xr ck_ring_init 3 , +.Xr ck_ring_dequeue_spmc 3 , +.Xr ck_ring_trydequeue_spmc 3 , +.Xr ck_ring_enqueue_spmc 3 , +.Xr ck_ring_dequeue_spsc 3 , +.Xr ck_ring_enqueue_spsc 3 , +.Xr ck_ring_enqueue_spsc_size 3 , +.Xr ck_ring_capacity 3 , +.Xr ck_ring_size 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_ring_enqueue_spsc b/doc/ck_ring_enqueue_spsc new file mode 100644 index 0000000..b1384d5 --- /dev/null +++ b/doc/ck_ring_enqueue_spsc @@ -0,0 +1,101 @@ +.\" +.\" Copyright 2012-2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 20, 2013 +.Dt CK_RING_ENQUEUE_SPSC 3 +.Sh NAME +.Nm ck_ring_enqueue_spsc +.Nd enqueue pointer into bounded FIFO +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_ring.h +.Ft bool +.Fn ck_ring_enqueue_spsc "ck_ring_t *ring" "void *entry" +.Sh DESCRIPTION +The +.Fn ck_ring_enqueue_spsc 3 +function enqueues the pointer +.Fa entry +into the bounded buffer pointed to by +.Fa ring +in FIFO fashion. +If you are on non-POSIX platforms or wish for strict +compliance with C, then it is recommended to pass a +pointer of type void ** for +.Fa entry . +This function is safe to call without locking for up to +one concurrent invocation of +.Fn ck_ring_dequeue_spsc 3 . +This function provides wait-free progress +guarantees. +.Sh EXAMPLE +.Bd -literal -offset indent +#include + +/* This ring was previously initialized with ck_ring_init. */ +ck_ring_t ring; + +void +enqueue(void) +{ + void *entry = some_object; + + /* Attempt to enqueue pointer to some_object into buffer. */ + if (ck_ring_enqueue_spsc(&ring, &entry) == false) { + /* + * The buffer was full and the enqueue operation + * has failed. + */ + return; + } + + /* Enqueue operation completed successfully. */ + return; +} +.Ed +.Sh RETURN VALUES +The function returns true if the value of +.Fa entry +was successfully enqueued into +.Fa ring . +The function will return false if the value of +.Fa entry +could not be enqueued which only occurs if +.Fa ring +was full. +.Sh SEE ALSO +.Xr ck_ring_init 3 , +.Xr ck_ring_dequeue_spmc 3 , +.Xr ck_ring_trydequeue_spmc 3 , +.Xr ck_ring_enqueue_spmc 3 , +.Xr ck_ring_enqueue_spmc_size 3 , +.Xr ck_ring_dequeue_spsc 3 , +.Xr ck_ring_enqueue_spsc_size 3 , +.Xr ck_ring_capacity 3 , +.Xr ck_ring_size 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_ring_enqueue_spsc_size b/doc/ck_ring_enqueue_spsc_size new file mode 100644 index 0000000..3cfb507 --- /dev/null +++ b/doc/ck_ring_enqueue_spsc_size @@ -0,0 +1,116 @@ +.\" +.\" Copyright 2012-2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 20, 2013 +.Dt CK_RING_ENQUEUE_SPSC_SIZE 3 +.Sh NAME +.Nm ck_ring_enqueue_spsc_size +.Nd enqueue pointer into bounded FIFO and return size of buffer +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_ring.h +.Ft bool +.Fn ck_ring_enqueue_spsc_size "ck_ring_t *ring" "void *entry" "unsigned int *size" +.Sh DESCRIPTION +The +.Fn ck_ring_enqueue_spsc_size 3 +function enqueues the pointer +.Fa entry +into the bounded buffer pointed to by +.Fa ring +in FIFO fashion. +If you are on non-POSIX platforms or wish for strict +compliance with C, then it is recommended to pass a +pointer of type void ** for +.Fa entry . +This function is safe to call without locking for up to +one concurrent invocation of +.Fn ck_ring_dequeue_spsc 3 . +This function provides wait-free progress +guarantees. +.Sh EXAMPLE +.Bd -literal -offset indent +#include + +/* This ring was previously initialized with ck_ring_init. */ +ck_ring_t ring; + +void +enqueue(void) +{ + void *entry = some_object; + unsigned int length; + + /* Attempt to enqueue pointer to some_object into buffer. */ + if (ck_ring_enqueue_spsc(&ring, &entry, &length) == false) { + /* + * The buffer was full and the enqueue operation + * has failed. + */ + return; + } + + /* + * If buffer length was 100 items or more at the time entry was + * enqueued, do something. + */ + if (length > 100) { + do_something; + } + + return; +} +.Ed +.Sh RETURN VALUES +The function returns true if the value of +.Fa entry +was successfully enqueued into +.Fa ring . +This function will return the number of items +in +.Fa ring +with respect to the linearization point (the +point in item that +.Fa entry +is enqueued). +The function will return false if the value of +.Fa entry +could not be enqueued which only occurs if +.Fa ring +was full. +.Sh SEE ALSO +.Xr ck_ring_init 3 , +.Xr ck_ring_dequeue_spmc 3 , +.Xr ck_ring_trydequeue_spmc 3 , +.Xr ck_ring_enqueue_spmc 3 , +.Xr ck_ring_enqueue_spmc_size 3 , +.Xr ck_ring_dequeue_spsc 3 , +.Xr ck_ring_enqueue_spsc 3 , +.Xr ck_ring_capacity 3 , +.Xr ck_ring_size 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_ring_init b/doc/ck_ring_init new file mode 100644 index 0000000..11c4074 --- /dev/null +++ b/doc/ck_ring_init @@ -0,0 +1,66 @@ +.\" +.\" Copyright 2012-2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 20, 2013 +.Dt CK_RING_INIT 3 +.Sh NAME +.Nm ck_ring_init +.Nd initialize bounded FIFO +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_ring.h +.Ft void +.Fn ck_ring_init "ck_ring_t *ring" "void *buffer" "unsigned int size" +.Sh DESCRIPTION +The +.Fn ck_ring_init +function initializes a bounded FIFO buffer pointed to by +.Fa ring +for the storage of up to +.Fa size +number of pointers. The +.Fa buffer +argument must be a pointer to an array of void * of +length +.Fa size . +The +.Fa size +argument must be a power-of-two greater than or equal to 4. +.Sh RETURN VALUES +This function has no return value. +.Sh SEE ALSO +.Xr ck_ring_dequeue_spmc 3 , +.Xr ck_ring_trydequeue_spmc 3 , +.Xr ck_ring_enqueue_spmc 3 , +.Xr ck_ring_enqueue_spmc_size 3 , +.Xr ck_ring_dequeue_spsc 3 , +.Xr ck_ring_enqueue_spsc 3 , +.Xr ck_ring_enqueue_spsc_size 3 , +.Xr ck_ring_capacity 3 , +.Xr ck_ring_size 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/doc/ck_ring_trydequeue_spmc b/doc/ck_ring_trydequeue_spmc new file mode 100644 index 0000000..4551724 --- /dev/null +++ b/doc/ck_ring_trydequeue_spmc @@ -0,0 +1,114 @@ +.\" +.\" Copyright 2012-2013 Samy Al Bahra. +.\" 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. +.\" +.\" 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. +.\" +.\" +.Dd April 20, 2013 +.Dt CK_RING_TRYDEQUEUE_SPMC 3 +.Sh NAME +.Nm ck_ring_trydequeue_spmc +.Nd dequeue from bounded FIFO and allow for spurious failure +.Sh LIBRARY +Concurrency Kit (libck, \-lck) +.Sh SYNOPSIS +.In ck_ring.h +.Ft bool +.Fn ck_ring_trydequeue_spmc "ck_ring_t *ring" "void *result" +.Sh DESCRIPTION +The +.Fn ck_ring_trydequeue_spmc 3 +function attempts to dequeue a pointer from the bounded buffer +pointed to by +.Fa ring +in FIFO fashion. The pointer is stored in the pointer +pointed to by +.Fa result . +If you are on non-POSIX platforms or wish for strict +compliance with C, then it is recommended to pass a +pointer of type void ** for +.Fa result . +This function is safe to call without locking for UINT_MAX +concurrent +.Fn ck_ring_dequeue_spmc 3 +or +.Fn ck_ring_trydequeue_spmc 3 +invocations and up to one concurrent +.Fn ck_ring_enqueue_spmc 3 +or +.Fn ck_ring_tryenqueue_spmc 3 +invocation. This operation will always complete +in a bounded number of steps. It is +possible for the function to return false even +if +.Fa ring +is non-empty. This +.Sh EXAMPLE +.Bd -literal -offset indent +#include + +/* This ring was previously initialized with ck_ring_init. */ +ck_ring_t ring; + +void +dequeue(void) +{ + void *result; + + /* Dequeue from ring until contention is actively observed. */ + while (ck_ring_trydequeue_spmc(&ring, &result) == true) { + /* + * Results contains the oldest pointer in ring + * since the dequeue operation returned true. + */ + operation(result); + } + + /* An empty ring was encountered, leave. */ + return; +} +.Ed +.Sh RETURN VALUES +The function returns true if the dequeue operation +completely successfully in a bounded number of steps. +The result of the dequeue operation is stored in the +value pointed to by +.Fa result . +Otherwise, the function will return false if the buffer was empty +or if the operation could not be completed in a bounded +number of steps. If the function returns false, then the contents +of +.Fa result +are undefined. +.Sh SEE ALSO +.Xr ck_ring_init 3 , +.Xr ck_ring_dequeue_spmc 3 , +.Xr ck_ring_enqueue_spmc 3 , +.Xr ck_ring_enqueue_spmc_size 3 , +.Xr ck_ring_dequeue_spsc 3 , +.Xr ck_ring_enqueue_spsc 3 , +.Xr ck_ring_enqueue_spsc_size 3 , +.Xr ck_ring_capacity 3 , +.Xr ck_ring_size 3 +.Pp +Additional information available at http://concurrencykit.org/ diff --git a/include/ck_fifo.h b/include/ck_fifo.h index c7e76aa..5805c49 100644 --- a/include/ck_fifo.h +++ b/include/ck_fifo.h @@ -139,13 +139,13 @@ ck_fifo_spsc_dequeue(struct ck_fifo_spsc *fifo, void *value) */ entry = ck_pr_load_ptr(&fifo->head->next); if (entry == NULL) - return (false); + return false; /* If entry is visible, guarantee store to value is visible. */ ck_pr_store_ptr(value, entry->value); ck_pr_fence_store(); ck_pr_store_ptr(&fifo->head, entry); - return (true); + return true; } /* @@ -165,14 +165,14 @@ ck_fifo_spsc_recycle(struct ck_fifo_spsc *fifo) garbage = fifo->garbage; fifo->garbage = garbage->next; - return (garbage); + return garbage; } CK_CC_INLINE static bool ck_fifo_spsc_isempty(struct ck_fifo_spsc *fifo) { struct ck_fifo_spsc_entry *head = ck_pr_load_ptr(&fifo->head); - return (ck_pr_load_ptr(&head->next) == NULL); + return ck_pr_load_ptr(&head->next) == NULL; } #define CK_FIFO_SPSC_ISEMPTY(f) ((f)->head->next == NULL) @@ -355,12 +355,20 @@ ck_fifo_mpmc_dequeue(struct ck_fifo_mpmc *fifo, * queue is empty. */ if (next.pointer == NULL) - return (false); + return false; /* Forward the tail pointer if necessary. */ update.generation = tail.generation + 1; ck_pr_cas_ptr_2(&fifo->tail, &tail, &update); } else { + /* + * It is possible for head snapshot to have been + * re-used. Avoid deferencing during enqueue + * re-use. + */ + if (next.pointer == NULL) + continue; + /* Save value before commit. */ *(void **)value = ck_pr_load_ptr(&next.pointer->value); @@ -372,7 +380,7 @@ ck_fifo_mpmc_dequeue(struct ck_fifo_mpmc *fifo, } *garbage = head.pointer; - return (true); + return true; } CK_CC_INLINE static bool @@ -408,6 +416,13 @@ ck_fifo_mpmc_trydequeue(struct ck_fifo_mpmc *fifo, ck_pr_cas_ptr_2(&fifo->tail, &tail, &update); return false; } else { + /* + * It is possible for head snapshot to have been + * re-used. Avoid deferencing during enqueue. + */ + if (next.pointer == NULL) + return false; + /* Save value before commit. */ *(void **)value = ck_pr_load_ptr(&next.pointer->value); diff --git a/include/ck_hp_fifo.h b/include/ck_hp_fifo.h index e40e90e..41064f3 100644 --- a/include/ck_hp_fifo.h +++ b/include/ck_hp_fifo.h @@ -81,7 +81,7 @@ ck_hp_fifo_enqueue_mpmc(ck_hp_record_t *record, for (;;) { tail = ck_pr_load_ptr(&fifo->tail); ck_hp_set(record, 0, tail); - ck_pr_fence_memory(); + ck_pr_fence_strict_memory(); if (tail != ck_pr_load_ptr(&fifo->tail)) continue; @@ -112,7 +112,7 @@ ck_hp_fifo_tryenqueue_mpmc(ck_hp_record_t *record, tail = ck_pr_load_ptr(&fifo->tail); ck_hp_set(record, 0, tail); - ck_pr_fence_memory(); + ck_pr_fence_strict_memory(); if (tail != ck_pr_load_ptr(&fifo->tail)) return false; @@ -140,19 +140,19 @@ ck_hp_fifo_dequeue_mpmc(ck_hp_record_t *record, ck_pr_fence_load(); tail = ck_pr_load_ptr(&fifo->tail); ck_hp_set(record, 0, head); - ck_pr_fence_memory(); + ck_pr_fence_strict_memory(); if (head != ck_pr_load_ptr(&fifo->head)) continue; next = ck_pr_load_ptr(&head->next); ck_hp_set(record, 1, next); - ck_pr_fence_memory(); + ck_pr_fence_strict_memory(); if (head != ck_pr_load_ptr(&fifo->head)) continue; if (head == tail) { if (next == NULL) - return (NULL); + return NULL; ck_pr_cas_ptr(&fifo->tail, tail, next); continue; @@ -161,7 +161,7 @@ ck_hp_fifo_dequeue_mpmc(ck_hp_record_t *record, } ck_pr_store_ptr(value, next->value); - return (head); + return head; } CK_CC_INLINE static struct ck_hp_fifo_entry * @@ -175,13 +175,13 @@ ck_hp_fifo_trydequeue_mpmc(ck_hp_record_t *record, ck_pr_fence_load(); tail = ck_pr_load_ptr(&fifo->tail); ck_hp_set(record, 0, head); - ck_pr_fence_memory(); + ck_pr_fence_strict_memory(); if (head != ck_pr_load_ptr(&fifo->head)) return NULL; next = ck_pr_load_ptr(&head->next); ck_hp_set(record, 1, next); - ck_pr_fence_memory(); + ck_pr_fence_strict_memory(); if (head != ck_pr_load_ptr(&fifo->head)) return NULL; diff --git a/include/ck_hp_stack.h b/include/ck_hp_stack.h index 412d8d5..2a7856c 100644 --- a/include/ck_hp_stack.h +++ b/include/ck_hp_stack.h @@ -59,30 +59,30 @@ ck_hp_stack_pop_mpmc(ck_hp_record_t *record, struct ck_stack *target) do { entry = ck_pr_load_ptr(&target->head); if (entry == NULL) - return (NULL); + return NULL; ck_hp_set(record, 0, entry); - ck_pr_fence_memory(); + ck_pr_fence_strict_memory(); } while (entry != ck_pr_load_ptr(&target->head)); while (ck_pr_cas_ptr_value(&target->head, entry, entry->next, &entry) == false) { if (entry == NULL) - return (NULL); + return NULL; ck_hp_set(record, 0, entry); - ck_pr_fence_memory(); + ck_pr_fence_strict_memory(); update = ck_pr_load_ptr(&target->head); while (entry != update) { ck_hp_set(record, 0, update); - ck_pr_fence_memory(); + ck_pr_fence_strict_memory(); entry = update; update = ck_pr_load_ptr(&target->head); if (update == NULL) - return (NULL); + return NULL; } } - return (entry); + return entry; } CK_CC_INLINE static bool @@ -95,7 +95,7 @@ ck_hp_stack_trypop_mpmc(ck_hp_record_t *record, struct ck_stack *target, struct return false; ck_hp_set(record, 0, entry); - ck_pr_fence_memory(); + ck_pr_fence_strict_memory(); if (entry != ck_pr_load_ptr(&target->head)) goto leave; diff --git a/include/ck_hs.h b/include/ck_hs.h index 938266e..07db610 100644 --- a/include/ck_hs.h +++ b/include/ck_hs.h @@ -88,7 +88,8 @@ typedef struct ck_hs_iterator ck_hs_iterator_t; void ck_hs_iterator_init(ck_hs_iterator_t *); bool ck_hs_next(ck_hs_t *, ck_hs_iterator_t *, void **); -bool ck_hs_init(ck_hs_t *, unsigned int, ck_hs_hash_cb_t *, ck_hs_compare_cb_t *, struct ck_malloc *, unsigned long, unsigned long); +bool ck_hs_init(ck_hs_t *, unsigned int, ck_hs_hash_cb_t *, + ck_hs_compare_cb_t *, struct ck_malloc *, unsigned long, unsigned long); void ck_hs_destroy(ck_hs_t *); void *ck_hs_get(ck_hs_t *, unsigned long, const void *); bool ck_hs_put(ck_hs_t *, unsigned long, const void *); @@ -100,3 +101,4 @@ bool ck_hs_reset(ck_hs_t *); void ck_hs_stat(ck_hs_t *, struct ck_hs_stat *); #endif /* _CK_HS_H */ + diff --git a/include/ck_pflock.h b/include/ck_pflock.h index b352339..49a47ac 100644 --- a/include/ck_pflock.h +++ b/include/ck_pflock.h @@ -29,8 +29,8 @@ #define _CK_PFLOCK_H /* - * This is a naive implementation of phase-fair locks derived - * from the work described in: + * This is an implementation of phase-fair locks derived from the work + * described in: * Brandenburg, B. and Anderson, J. 2010. Spin-Based * Reader-Writer Synchronization for Multiprocessor Real-Time Systems */ diff --git a/include/ck_queue.h b/include/ck_queue.h index a9a502d..0393eef 100644 --- a/include/ck_queue.h +++ b/include/ck_queue.h @@ -88,24 +88,25 @@ * This facility is currently unsupported on architectures such as the Alpha * which require load-depend memory fences. * - * CK_SLIST CK_LIST - * _HEAD + + - * _HEAD_INITIALIZER + + - * _ENTRY + + - * _INIT + + - * _EMPTY + + - * _FIRST + + - * _NEXT + + - * _FOREACH + + - * _FOREACH_SAFE + + - * _INSERT_HEAD + + - * _INSERT_BEFORE - + - * _INSERT_AFTER + + - * _REMOVE_AFTER + - - * _REMOVE_HEAD + - - * _REMOVE + + - * _SWAP + + - * _MOVE + + + * CK_SLIST CK_LIST CK_STAILQ + * _HEAD + + + + * _HEAD_INITIALIZER + + + + * _ENTRY + + + + * _INIT + + + + * _EMPTY + + + + * _FIRST + + + + * _NEXT + + + + * _FOREACH + + + + * _FOREACH_SAFE + + + + * _INSERT_HEAD + + + + * _INSERT_BEFORE - + - + * _INSERT_AFTER + + + + * _INSERT_TAIL - - + + * _REMOVE_AFTER + - + + * _REMOVE_HEAD + - + + * _REMOVE + + + + * _SWAP + + + + * _MOVE + + + */ /* @@ -202,6 +203,130 @@ struct { \ (b)->slh_first = swap_first; \ } while (0) +/* + * Singly-linked Tail queue declarations. + */ +#define CK_STAILQ_HEAD(name, type) \ +struct name { \ + struct type *stqh_first;/* first element */ \ + struct type **stqh_last;/* addr of last next element */ \ +} + +#define CK_STAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).stqh_first } + +#define CK_STAILQ_ENTRY(type) \ +struct { \ + struct type *stqe_next; /* next element */ \ +} + +/* + * Singly-linked Tail queue functions. + */ +#define CK_STAILQ_CONCAT(head1, head2) do { \ + if ((head2)->stqh_first == NULL) { \ + ck_pr_store_ptr((head1)->stqh_last, (head2)->stqh_first); \ + ck_pr_fence_store(); \ + (head1)->stqh_last = (head2)->stqh_last; \ + CK_STAILQ_INIT((head2)); \ + } \ +} while (0) + +#define CK_STAILQ_EMPTY(head) (ck_pr_load_ptr(&(head)->stqh_first) == NULL) + +#define CK_STAILQ_FIRST(head) (ck_pr_load_ptr(&(head)->stqh_first)) + +#define CK_STAILQ_FOREACH(var, head, field) \ + for((var) = CK_STAILQ_FIRST((head)); \ + (var) && (ck_pr_fence_load(), 1); \ + (var) = CK_STAILQ_NEXT((var), field)) + +#define CK_STAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = CK_STAILQ_FIRST((head)); \ + (var) && (ck_pr_fence_load(), (tvar) = \ + CK_STAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define CK_STAILQ_INIT(head) do { \ + ck_pr_store_ptr(&(head)->stqh_first, NULL); \ + ck_pr_fence_store(); \ + (head)->stqh_last = &(head)->stqh_first; \ +} while (0) + +#define CK_STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ + (elm)->field.stqe_next = (tqelm)->field.stqe_next; \ + ck_pr_fence_store(); \ + ck_pr_store_ptr(&(tqelm)->field.stqe_next, elm); \ + if ((elm)->field.stqe_next == NULL) \ + (head)->stqh_last = &(elm)->field.stqe_next; \ +} while (0) + +#define CK_STAILQ_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.stqe_next = (head)->stqh_first; \ + ck_pr_fence_store(); \ + ck_pr_store_ptr(&(head)->stqh_first, elm); \ + if ((elm)->field.stqe_next == NULL) \ + (head)->stqh_last = &(elm)->field.stqe_next; \ +} while (0) + +#define CK_STAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.stqe_next = NULL; \ + ck_pr_fence_store(); \ + ck_pr_store_ptr((head)->stqh_last, (elm)); \ + (head)->stqh_last = &(elm)->field.stqe_next; \ +} while (0) + +#define CK_STAILQ_NEXT(elm, field) \ + (ck_pr_load_ptr(&(elm)->field.stqe_next)) + +#define CK_STAILQ_REMOVE(head, elm, type, field) do { \ + if ((head)->stqh_first == (elm)) { \ + CK_STAILQ_REMOVE_HEAD((head), field); \ + } else { \ + struct type *curelm = (head)->stqh_first; \ + while (curelm->field.stqe_next != (elm)) \ + curelm = curelm->field.stqe_next; \ + CK_STAILQ_REMOVE_AFTER(head, curelm, field); \ + } \ +} while (0) + +#define CK_STAILQ_REMOVE_AFTER(head, elm, field) do { \ + ck_pr_store_ptr(&(elm)->field.stqe_next, \ + (elm)->field.stqe_next->field.stqe_next); \ + if ((elm)->field.stqe_next == NULL) \ + (head)->stqh_last = &(elm)->field.stqe_next; \ +} while (0) + +#define CK_STAILQ_REMOVE_HEAD(head, field) do { \ + ck_pr_store_ptr(&(head)->stqh_first, \ + (head)->stqh_first->field.stqe_next); \ + if ((head)->stqh_first == NULL) \ + (head)->stqh_last = &(head)->stqh_first; \ +} while (0) + +#define CK_STAILQ_MOVE(head1, head2, field) do { \ + ck_pr_store_ptr(&(head1)->stqh_first, (head2)->stqh_first); \ + (head1)->stqh_last = (head2)->stqh_last; \ + if ((head2)->stqh_last == &(head2)->stqh_first) \ + (head1)->stqh_last = &(head1)->stqh_first; \ +} while (0) + +/* + * This operation is not applied atomically. + */ +#define CK_STAILQ_SWAP(head1, head2, type) do { \ + struct type *swap_first = CK_STAILQ_FIRST(head1); \ + struct type **swap_last = (head1)->stqh_last; \ + CK_STAILQ_FIRST(head1) = CK_STAILQ_FIRST(head2); \ + (head1)->stqh_last = (head2)->stqh_last; \ + CK_STAILQ_FIRST(head2) = swap_first; \ + (head2)->stqh_last = swap_last; \ + if (CK_STAILQ_EMPTY(head1)) \ + (head1)->stqh_last = &(head1)->stqh_first; \ + if (CK_STAILQ_EMPTY(head2)) \ + (head2)->stqh_last = &(head2)->stqh_first; \ +} while (0) + /* * List declarations. */ diff --git a/include/ck_ring.h b/include/ck_ring.h index ffd06f1..a089bd3 100644 --- a/include/ck_ring.h +++ b/include/ck_ring.h @@ -75,6 +75,27 @@ return ring->size; \ } \ CK_CC_INLINE static bool \ + ck_ring_enqueue_spsc_size_##name(struct ck_ring_##name *ring, \ + struct type *entry, \ + unsigned int *size) \ + { \ + unsigned int consumer, producer, delta; \ + unsigned int mask = ring->mask; \ + \ + consumer = ck_pr_load_uint(&ring->c_head); \ + producer = ring->p_tail; \ + delta = producer + 1; \ + *size = (producer - consumer) & mask; \ + \ + if ((delta & mask) == (consumer & mask)) \ + return false; \ + \ + ring->ring[producer & mask] = *entry; \ + ck_pr_fence_store(); \ + ck_pr_store_uint(&ring->p_tail, delta); \ + return true; \ + } \ + CK_CC_INLINE static bool \ ck_ring_enqueue_spsc_##name(struct ck_ring_##name *ring, \ struct type *entry) \ { \ @@ -114,6 +135,13 @@ return true; \ } \ CK_CC_INLINE static bool \ + ck_ring_enqueue_spmc_size_##name(struct ck_ring_##name *ring, \ + void *entry, unsigned int *size) \ + { \ + \ + return ck_ring_enqueue_spsc_size_##name(ring, entry, size); \ + } \ + CK_CC_INLINE static bool \ ck_ring_enqueue_spmc_##name(struct ck_ring_##name *ring, void *entry) \ { \ \ @@ -167,23 +195,27 @@ } -#define CK_RING_INSTANCE(name) \ +#define CK_RING_INSTANCE(name) \ struct ck_ring_##name -#define CK_RING_INIT(name, object, buffer, size) \ +#define CK_RING_INIT(name, object, buffer, size) \ ck_ring_init_##name(object, buffer, size) -#define CK_RING_SIZE(name, object) \ +#define CK_RING_SIZE(name, object) \ ck_ring_size_##name(object) -#define CK_RING_CAPACITY(name, object) \ +#define CK_RING_CAPACITY(name, object) \ ck_ring_capacity_##name(object) -#define CK_RING_ENQUEUE_SPSC(name, object, value) \ +#define CK_RING_ENQUEUE_SPSC_SIZE(name, object, value, s) \ + ck_ring_enqueue_spsc_size_##name(object, value, s) +#define CK_RING_ENQUEUE_SPSC(name, object, value) \ ck_ring_enqueue_spsc_##name(object, value) -#define CK_RING_DEQUEUE_SPSC(name, object, value) \ +#define CK_RING_DEQUEUE_SPSC(name, object, value) \ ck_ring_dequeue_spsc_##name(object, value) -#define CK_RING_DEQUEUE_SPMC(name, object, value) \ +#define CK_RING_DEQUEUE_SPMC(name, object, value) \ ck_ring_dequeue_spmc_##name(object, value) -#define CK_RING_TRYDEQUEUE_SPMC(name, object, value) \ +#define CK_RING_TRYDEQUEUE_SPMC(name, object, value) \ ck_ring_trydequeue_spmc_##name(object, value) -#define CK_RING_ENQUEUE_SPMC(name, object, value) \ +#define CK_RING_ENQUEUE_SPMC_SIZE(name, object, value, s) \ + ck_ring_enqueue_spmc_size_##name(object, value, s) +#define CK_RING_ENQUEUE_SPMC(name, object, value) \ ck_ring_enqueue_spmc_##name(object, value) struct ck_ring { @@ -197,9 +229,6 @@ struct ck_ring { }; typedef struct ck_ring ck_ring_t; -/* - * Single consumer and single producer ring buffer enqueue (producer). - */ CK_CC_INLINE static unsigned int ck_ring_size(struct ck_ring *ring) { @@ -217,6 +246,50 @@ ck_ring_capacity(struct ck_ring *ring) return ring->size; } +/* + * Atomically enqueues the specified entry. Returns true on success, returns + * false if the ck_ring is full. This operation only support one active + * invocation at a time and works in the presence of a concurrent invocation + * of ck_ring_dequeue_spsc. + * + * This variant of ck_ring_enqueue_spsc returns the snapshot of queue length + * with respect to the linearization point. This can be used to extract ring + * size without incurring additional cacheline invalidation overhead from the + * writer. + */ +CK_CC_INLINE static bool +ck_ring_enqueue_spsc_size(struct ck_ring *ring, + void *entry, + unsigned int *size) +{ + unsigned int consumer, producer, delta; + unsigned int mask = ring->mask; + + consumer = ck_pr_load_uint(&ring->c_head); + producer = ring->p_tail; + delta = producer + 1; + *size = (producer - consumer) & mask; + + if ((delta & mask) == (consumer & mask)) + return false; + + ring->ring[producer & mask] = entry; + + /* + * Make sure to update slot value before indicating + * that the slot is available for consumption. + */ + ck_pr_fence_store(); + ck_pr_store_uint(&ring->p_tail, delta); + return true; +} + +/* + * Atomically enqueues the specified entry. Returns true on success, returns + * false if the ck_ring is full. This operation only support one active + * invocation at a time and works in the presence of a concurrent invocation + * of ck_ring_dequeue_spsc. + */ CK_CC_INLINE static bool ck_ring_enqueue_spsc(struct ck_ring *ring, void *entry) { @@ -275,6 +348,32 @@ ck_ring_dequeue_spsc(struct ck_ring *ring, void *data) return true; } +/* + * Atomically enqueues the specified entry. Returns true on success, returns + * false if the ck_ring is full. This operation only support one active + * invocation at a time and works in the presence of up to UINT_MAX concurrent + * invocations of ck_ring_dequeue_spmc. + * + * This variant of ck_ring_enqueue_spmc returns the snapshot of queue length + * with respect to the linearization point. This can be used to extract ring + * size without incurring additional cacheline invalidation overhead from the + * writer. + */ +CK_CC_INLINE static bool +ck_ring_enqueue_spmc_size(struct ck_ring *ring, + void *entry, + unsigned int *size) +{ + + return ck_ring_enqueue_spsc_size(ring, entry, size); +} + +/* + * Atomically enqueues the specified entry. Returns true on success, returns + * false if the ck_ring is full. This operation only support one active + * invocation at a time and works in the presence of up to UINT_MAX concurrent + * invocations of ck_ring_dequeue_spmc. + */ CK_CC_INLINE static bool ck_ring_enqueue_spmc(struct ck_ring *ring, void *entry) { diff --git a/regressions/ck_backoff/validate/Makefile b/regressions/ck_backoff/validate/Makefile index 60cd40b..39e6d4f 100644 --- a/regressions/ck_backoff/validate/Makefile +++ b/regressions/ck_backoff/validate/Makefile @@ -9,7 +9,7 @@ check: all ./validate clean: - rm -rf validate *.dSYM + rm -rf validate *.dSYM *.exe include ../../../build/regressions.build CFLAGS+=-D_GNU_SOURCE diff --git a/regressions/ck_bag/validate/Makefile b/regressions/ck_bag/validate/Makefile index 3df6823..b06f8b7 100644 --- a/regressions/ck_bag/validate/Makefile +++ b/regressions/ck_bag/validate/Makefile @@ -11,7 +11,7 @@ check: all ./order clean: - rm -rf *.dSYM *~ *.o $(OBJECTS) + rm -rf *.dSYM *.exe *~ *.o $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_barrier/benchmark/Makefile b/regressions/ck_barrier/benchmark/Makefile index 864c6fc..ea973d2 100644 --- a/regressions/ck_barrier/benchmark/Makefile +++ b/regressions/ck_barrier/benchmark/Makefile @@ -8,7 +8,7 @@ throughput: throughput.c ../../../include/ck_barrier.h ../../../src/ck_barrier_c $(CC) $(CFLAGS) -o throughput throughput.c ../../../src/ck_barrier_centralized.c clean: - rm -rf *.dSYM *~ *.o $(OBJECTS) + rm -rf *.dSYM *.exe *~ *.o $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_barrier/validate/Makefile b/regressions/ck_barrier/validate/Makefile index f11b70a..f31a1a6 100644 --- a/regressions/ck_barrier/validate/Makefile +++ b/regressions/ck_barrier/validate/Makefile @@ -28,7 +28,7 @@ check: all exit $$rc clean: - rm -rf *.dSYM *~ *.o $(OBJECTS) + rm -rf *.dSYM *.exe *~ *.o $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_bitmap/validate/Makefile b/regressions/ck_bitmap/validate/Makefile index c96f924..85e13c8 100644 --- a/regressions/ck_bitmap/validate/Makefile +++ b/regressions/ck_bitmap/validate/Makefile @@ -8,7 +8,7 @@ serial: serial.c ../../../include/ck_bitmap.h $(CC) $(CFLAGS) -o serial serial.c clean: - rm -rf *~ *.o $(OBJECTS) *.dSYM + rm -rf *~ *.o $(OBJECTS) *.dSYM *.exe check: all ./serial diff --git a/regressions/ck_brlock/benchmark/Makefile b/regressions/ck_brlock/benchmark/Makefile index 1c6c0d6..cd12e7c 100644 --- a/regressions/ck_brlock/benchmark/Makefile +++ b/regressions/ck_brlock/benchmark/Makefile @@ -11,7 +11,7 @@ throughput: throughput.c ../../../include/ck_brlock.h $(CC) $(CFLAGS) -o throughput throughput.c clean: - rm -rf *.dSYM *~ *.o $(OBJECTS) + rm -rf *.dSYM *.exe *~ *.o $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_brlock/validate/Makefile b/regressions/ck_brlock/validate/Makefile index e233d69..3a49c43 100644 --- a/regressions/ck_brlock/validate/Makefile +++ b/regressions/ck_brlock/validate/Makefile @@ -11,7 +11,7 @@ check: all ./validate $(CORES) 1 clean: - rm -rf *.dSYM *~ *.o $(OBJECTS) + rm -rf *.dSYM *.exe *~ *.o $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_bytelock/benchmark/Makefile b/regressions/ck_bytelock/benchmark/Makefile index 0fe3712..c819099 100644 --- a/regressions/ck_bytelock/benchmark/Makefile +++ b/regressions/ck_bytelock/benchmark/Makefile @@ -8,7 +8,7 @@ latency: latency.c $(CC) $(CFLAGS) -o latency latency.c clean: - rm -rf *.dSYM *~ *.o $(OBJECTS) + rm -rf *.dSYM *.exe *~ *.o $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_bytelock/validate/Makefile b/regressions/ck_bytelock/validate/Makefile index dce3a0a..2a890e0 100644 --- a/regressions/ck_bytelock/validate/Makefile +++ b/regressions/ck_bytelock/validate/Makefile @@ -11,7 +11,7 @@ check: all ./validate $(CORES) 1 clean: - rm -rf *.dSYM *~ *.o $(OBJECTS) + rm -rf *.dSYM *.exe *~ *.o $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_cohort/benchmark/Makefile b/regressions/ck_cohort/benchmark/Makefile index 7cf62da..6af18b9 100644 --- a/regressions/ck_cohort/benchmark/Makefile +++ b/regressions/ck_cohort/benchmark/Makefile @@ -11,7 +11,7 @@ ck_cohort.LATENCY: ck_cohort.c $(CC) -DLATENCY $(CFLAGS) -o ck_cohort.LATENCY ck_cohort.c clean: - rm -rf *.dSYM $(OBJECTS) + rm -rf *.dSYM *.exe $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE -lm diff --git a/regressions/ck_cohort/ck_cohort.h b/regressions/ck_cohort/ck_cohort.h index 8427d6b..b0d7f0a 100644 --- a/regressions/ck_cohort/ck_cohort.h +++ b/regressions/ck_cohort/ck_cohort.h @@ -1,5 +1,5 @@ #define LOCK_NAME "ck_cohort" -#define LOCK_DEFINE\ +#define LOCK_DEFINE \ static ck_spinlock_fas_t global_fas_lock = CK_SPINLOCK_FAS_INITIALIZER; \ static ck_spinlock_fas_t local_fas_lock = CK_SPINLOCK_FAS_INITIALIZER; \ static void \ @@ -28,7 +28,8 @@ ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_locked_with_context) \ static CK_COHORT_INSTANCE(fas_fas) CK_CC_CACHELINE cohort = CK_COHORT_INITIALIZER -#define LOCK_INIT CK_COHORT_INIT(fas_fas, &cohort, &global_fas_lock, &local_fas_lock,\ + +#define LOCK_INIT CK_COHORT_INIT(fas_fas, &cohort, &global_fas_lock, &local_fas_lock, \ CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT) #define LOCK CK_COHORT_LOCK(fas_fas, &cohort, NULL, NULL) #define UNLOCK CK_COHORT_UNLOCK(fas_fas, &cohort, NULL, NULL) diff --git a/regressions/ck_cohort/validate/Makefile b/regressions/ck_cohort/validate/Makefile index 794e3e6..145af3a 100644 --- a/regressions/ck_cohort/validate/Makefile +++ b/regressions/ck_cohort/validate/Makefile @@ -11,7 +11,7 @@ check: all ./validate `expr $(CORES) / 2` 2 1 clean: - rm -rf *.dSYM *~ *.o $(OBJECTS) + rm -rf *.dSYM *.exe *~ *.o $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_epoch/validate/Makefile b/regressions/ck_epoch/validate/Makefile index 59b2252..73f8e5d 100644 --- a/regressions/ck_epoch/validate/Makefile +++ b/regressions/ck_epoch/validate/Makefile @@ -20,7 +20,7 @@ ck_stack: ck_stack.c ../../../include/ck_stack.h ../../../include/ck_epoch.h ../ $(CC) $(CFLAGS) -o ck_stack ck_stack.c ../../../src/ck_epoch.c clean: - rm -rf *~ *.o $(OBJECTS) *.dSYM + rm -rf *~ *.o $(OBJECTS) *.dSYM *.exe include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_fifo/benchmark/Makefile b/regressions/ck_fifo/benchmark/Makefile index 50e5a09..6e2df2a 100644 --- a/regressions/ck_fifo/benchmark/Makefile +++ b/regressions/ck_fifo/benchmark/Makefile @@ -8,7 +8,7 @@ latency: latency.c $(CC) $(CFLAGS) -o latency latency.c clean: - rm -rf *~ *.o *.dSYM $(OBJECTS) + rm -rf *~ *.o *.dSYM *.exe $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_fifo/validate/Makefile b/regressions/ck_fifo/validate/Makefile index d12d703..a669896 100644 --- a/regressions/ck_fifo/validate/Makefile +++ b/regressions/ck_fifo/validate/Makefile @@ -23,7 +23,7 @@ ck_fifo_mpmc_iterator: ck_fifo_mpmc_iterator.c ../../../include/ck_fifo.h $(CC) $(CFLAGS) -o ck_fifo_mpmc_iterator ck_fifo_mpmc_iterator.c clean: - rm -rf *.dSYM *~ *.o $(OBJECTS) + rm -rf *.dSYM *.exe *~ *.o $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_hp/benchmark/Makefile b/regressions/ck_hp/benchmark/Makefile index 8ab5273..2025ea9 100644 --- a/regressions/ck_hp/benchmark/Makefile +++ b/regressions/ck_hp/benchmark/Makefile @@ -11,7 +11,7 @@ stack_latency: stack_latency.c $(CC) $(CFLAGS) -o stack_latency ../../../src/ck_hp.c stack_latency.c clean: - rm -rf *~ *.o *.dSYM $(OBJECTS) + rm -rf *~ *.o *.dSYM *.exe $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_hp/validate/Makefile b/regressions/ck_hp/validate/Makefile index f1e091c..476b34f 100644 --- a/regressions/ck_hp/validate/Makefile +++ b/regressions/ck_hp/validate/Makefile @@ -27,7 +27,7 @@ nbds_haz_test: ../../../src/ck_hp.c nbds_haz_test.c $(CC) $(CFLAGS) ../../../src/ck_hp.c -o nbds_haz_test nbds_haz_test.c clean: - rm -rf *~ *.o *.dSYM $(OBJECTS) + rm -rf *~ *.o *.dSYM *.exe $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_hs/benchmark/Makefile b/regressions/ck_hs/benchmark/Makefile index 6ffdb43..18ccdba 100644 --- a/regressions/ck_hs/benchmark/Makefile +++ b/regressions/ck_hs/benchmark/Makefile @@ -11,7 +11,7 @@ parallel_bytestring: parallel_bytestring.c ../../../include/ck_hs.h ../../../src $(CC) $(PTHREAD_CFLAGS) $(CFLAGS) -o parallel_bytestring parallel_bytestring.c ../../../src/ck_hs.c ../../../src/ck_epoch.c clean: - rm -rf *~ *.o $(OBJECTS) *.dSYM + rm -rf *~ *.o $(OBJECTS) *.dSYM *.exe include ../../../build/regressions.build CFLAGS+=-D_GNU_SOURCE diff --git a/regressions/ck_hs/benchmark/parallel_bytestring.c b/regressions/ck_hs/benchmark/parallel_bytestring.c index fa52b85..7910ac2 100644 --- a/regressions/ck_hs/benchmark/parallel_bytestring.c +++ b/regressions/ck_hs/benchmark/parallel_bytestring.c @@ -70,7 +70,7 @@ struct hs_epoch { ck_epoch_entry_t epoch_entry; }; -COMMON_ALARM_DECLARE_GLOBAL(alarm_event, next_stage) +COMMON_ALARM_DECLARE_GLOBAL(hs_alarm, alarm_event, next_stage) static void alarm_handler(int s) @@ -287,7 +287,7 @@ main(int argc, char *argv[]) pthread_t *readers; double p_r, p_d; - COMMON_ALARM_DECLARE_LOCAL(alarm_event) + COMMON_ALARM_DECLARE_LOCAL(hs_alarm, alarm_event) r = 20; s = 8; @@ -327,7 +327,7 @@ main(int argc, char *argv[]) } } - COMMON_ALARM_INIT(alarm_event, r) + COMMON_ALARM_INIT(hs_alarm, alarm_event, r) affinerator.delta = 1; readers = malloc(sizeof(pthread_t) * n_threads); diff --git a/regressions/ck_hs/validate/Makefile b/regressions/ck_hs/validate/Makefile index a01a08a..a96e652 100644 --- a/regressions/ck_hs/validate/Makefile +++ b/regressions/ck_hs/validate/Makefile @@ -11,7 +11,7 @@ check: all ./serial clean: - rm -rf *~ *.o $(OBJECTS) *.dSYM + rm -rf *~ *.o $(OBJECTS) *.dSYM *.exe include ../../../build/regressions.build CFLAGS+=-D_GNU_SOURCE diff --git a/regressions/ck_ht/benchmark/Makefile b/regressions/ck_ht/benchmark/Makefile index df5e16c..8e21d5b 100644 --- a/regressions/ck_ht/benchmark/Makefile +++ b/regressions/ck_ht/benchmark/Makefile @@ -14,7 +14,7 @@ parallel_direct: parallel_direct.c ../../../include/ck_ht.h ../../../src/ck_ht.c $(CC) $(PTHREAD_CFLAGS) $(CFLAGS) -o parallel_direct parallel_direct.c ../../../src/ck_ht.c ../../../src/ck_epoch.c clean: - rm -rf *~ *.o $(OBJECTS) *.dSYM + rm -rf *~ *.o $(OBJECTS) *.dSYM *.exe include ../../../build/regressions.build CFLAGS+=-D_GNU_SOURCE diff --git a/regressions/ck_ht/benchmark/parallel_bytestring.c b/regressions/ck_ht/benchmark/parallel_bytestring.c index 4f222ec..f530788 100644 --- a/regressions/ck_ht/benchmark/parallel_bytestring.c +++ b/regressions/ck_ht/benchmark/parallel_bytestring.c @@ -71,7 +71,7 @@ struct ht_epoch { ck_epoch_entry_t epoch_entry; }; -COMMON_ALARM_DECLARE_GLOBAL(alarm_event, next_stage) +COMMON_ALARM_DECLARE_GLOBAL(ht_alarm, alarm_event, next_stage) static void alarm_handler(int s) @@ -265,7 +265,7 @@ main(int argc, char *argv[]) pthread_t *readers; double p_r, p_d; - COMMON_ALARM_DECLARE_LOCAL(alarm_event) + COMMON_ALARM_DECLARE_LOCAL(ht_alarm, alarm_event) r = 20; s = 8; @@ -305,7 +305,7 @@ main(int argc, char *argv[]) } } - COMMON_ALARM_INIT(alarm_event, r) + COMMON_ALARM_INIT(ht_alarm, alarm_event, r) affinerator.delta = 1; readers = malloc(sizeof(pthread_t) * n_threads); diff --git a/regressions/ck_ht/benchmark/parallel_direct.c b/regressions/ck_ht/benchmark/parallel_direct.c index 067e8f1..94e3e22 100644 --- a/regressions/ck_ht/benchmark/parallel_direct.c +++ b/regressions/ck_ht/benchmark/parallel_direct.c @@ -70,7 +70,7 @@ struct ht_epoch { ck_epoch_entry_t epoch_entry; }; -COMMON_ALARM_DECLARE_GLOBAL(alarm_event, next_stage) +COMMON_ALARM_DECLARE_GLOBAL(ht_alarm, alarm_event, next_stage) static void alarm_handler(int s) @@ -269,7 +269,7 @@ main(int argc, char *argv[]) pthread_t *readers; double p_r, p_d; - COMMON_ALARM_DECLARE_LOCAL(alarm_event) + COMMON_ALARM_DECLARE_LOCAL(ht_alarm, alarm_event) r = 20; s = 8; @@ -309,7 +309,7 @@ main(int argc, char *argv[]) } } - COMMON_ALARM_INIT(alarm_event, r) + COMMON_ALARM_INIT(ht_alarm, alarm_event, r) affinerator.delta = 1; readers = malloc(sizeof(pthread_t) * n_threads); diff --git a/regressions/ck_ht/validate/Makefile b/regressions/ck_ht/validate/Makefile index f89e117..5942975 100644 --- a/regressions/ck_ht/validate/Makefile +++ b/regressions/ck_ht/validate/Makefile @@ -11,7 +11,7 @@ check: all ./serial clean: - rm -rf *~ *.o $(OBJECTS) *.dSYM + rm -rf *~ *.o $(OBJECTS) *.dSYM *.exe include ../../../build/regressions.build CFLAGS+=-D_GNU_SOURCE diff --git a/regressions/ck_pflock/benchmark/Makefile b/regressions/ck_pflock/benchmark/Makefile index 59c0b53..6f739d9 100644 --- a/regressions/ck_pflock/benchmark/Makefile +++ b/regressions/ck_pflock/benchmark/Makefile @@ -11,7 +11,7 @@ throughput: throughput.c ../../../include/ck_rwlock.h $(CC) $(CFLAGS) -o throughput throughput.c clean: - rm -rf *.dSYM *~ *.o $(OBJECTS) + rm -rf *.dSYM *.exe *~ *.o $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_pflock/validate/Makefile b/regressions/ck_pflock/validate/Makefile index fd25fea..eea9d02 100644 --- a/regressions/ck_pflock/validate/Makefile +++ b/regressions/ck_pflock/validate/Makefile @@ -11,7 +11,7 @@ check: all ./validate $(CORES) 1 clean: - rm -rf *.dSYM *~ *.o $(OBJECTS) + rm -rf *.dSYM *.exe *~ *.o $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_pr/benchmark/Makefile b/regressions/ck_pr/benchmark/Makefile index 669b2a2..f43e792 100644 --- a/regressions/ck_pr/benchmark/Makefile +++ b/regressions/ck_pr/benchmark/Makefile @@ -12,7 +12,7 @@ ck_pr_fas_64: ck_pr_fas_64.c $(CC) $(CFLAGS) -o ck_pr_fas_64 ck_pr_fas_64.c clean: - rm -rf ck_pr_cas_64 ck_pr_fas_64 ck_pr_cas_64_2 *.dSYM + rm -rf ck_pr_cas_64 ck_pr_fas_64 ck_pr_cas_64_2 *.dSYM *.exe include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE -lm diff --git a/regressions/ck_pr/validate/Makefile b/regressions/ck_pr/validate/Makefile index c255b03..9e4a82d 100644 --- a/regressions/ck_pr/validate/Makefile +++ b/regressions/ck_pr/validate/Makefile @@ -78,7 +78,7 @@ ck_pr_unary: ck_pr_unary.c $(CC) $(CFLAGS) -o ck_pr_unary ck_pr_unary.c clean: - rm -rf *~ *.o $(OBJECTS) *.dSYM + rm -rf *~ *.o $(OBJECTS) *.dSYM *.exe include ../../../build/regressions.build CFLAGS+=-D_GNU_SOURCE diff --git a/regressions/ck_queue/validate/Makefile b/regressions/ck_queue/validate/Makefile index 07ce22b..d6be3dc 100644 --- a/regressions/ck_queue/validate/Makefile +++ b/regressions/ck_queue/validate/Makefile @@ -1,22 +1,26 @@ .PHONY: check clean distribution HEADER=../../../include/ck_queue.h -OBJECTS=ck_slist ck_list +OBJECTS=ck_list ck_slist ck_stailq all: $(OBJECTS) check: all - ./ck_slist $(CORES) 100000 - ./ck_list $(CORES) 100000 + ./ck_list $(CORES) 5 + ./ck_slist $(CORES) 5 + ./ck_stailq $(CORES) 1000000 + +ck_list: $(HEADER) ck_list.c + $(CC) $(CFLAGS) -o ck_list ck_list.c ck_slist: $(HEADER) ck_slist.c $(CC) $(CFLAGS) -o ck_slist ck_slist.c -ck_list: $(HEADER) ck_list.c - $(CC) $(CFLAGS) -o ck_list ck_list.c +ck_stailq: $(HEADER) ck_stailq.c + $(CC) $(CFLAGS) -o ck_stailq ck_stailq.c clean: - rm -rf *~ *.o $(OBJECTS) *.dSYM + rm -rf *~ *.o $(OBJECTS) *.dSYM *.exe include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_queue/validate/ck_list.c b/regressions/ck_queue/validate/ck_list.c index 0c6c504..58aa291 100644 --- a/regressions/ck_queue/validate/ck_list.c +++ b/regressions/ck_queue/validate/ck_list.c @@ -167,6 +167,21 @@ main(int argc, char *argv[]) ck_error("List is not empty after bulk removal.\n"); } + CK_LIST_INSERT_HEAD(&head, &a, list_entry); + CK_LIST_INSERT_AFTER(&a, &b, list_entry); + + if (CK_LIST_NEXT(&b, list_entry) != NULL) + ck_error("Inserted item after last, it should not have no next.\n"); + + CK_LIST_INIT(&head); + + CK_LIST_INSERT_HEAD(&head, &a, list_entry); + CK_LIST_INSERT_BEFORE(&a, &b, list_entry); + + if (CK_LIST_NEXT(&b, list_entry) != &a) + ck_error("Inserted item before last, it should point to last.\n"); + + CK_LIST_INIT(&head); fprintf(stderr, "done (success)\n"); fprintf(stderr, "Beginning parallel traversal..."); diff --git a/regressions/ck_queue/validate/ck_stailq.c b/regressions/ck_queue/validate/ck_stailq.c new file mode 100644 index 0000000..0268afc --- /dev/null +++ b/regressions/ck_queue/validate/ck_stailq.c @@ -0,0 +1,256 @@ +/* + * Copyright 2012-2013 Samy Al Bahra. + * 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. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include "../../common.h" + +struct test { + int value; + CK_STAILQ_ENTRY(test) list_entry; +}; +static CK_STAILQ_HEAD(test_list, test) head = CK_STAILQ_HEAD_INITIALIZER(head); + +static int goal; + +static void +test_foreach(void) +{ + struct test *n, *next, *safe; + int i, s = 0, j = 0, k = 0; + + for (i = goal; i != 0; i = goal) { + s = 0; + + CK_STAILQ_FOREACH(n, &head, list_entry) { + j++; + if (s == 0) + s = n->value; + else + s = s - 1; + + if (n->value != s) { + ck_error("\nExpected %d, but got %d.\n", + s, n->value); + } + + next = CK_STAILQ_NEXT(n, list_entry); + if (next != NULL && next->value != s - 1) { + ck_error("\nExpected %d, but got %d.\n", + s, next->value); + } + + i--; + } + + if (i == 0) + break; + + s = 0; + CK_STAILQ_FOREACH_SAFE(n, &head, list_entry, safe) { + k++; + + if (s == 0) + s = n->value; + else + s = s - 1; + + if (n->value != s) { + ck_error("\nExpected %d, but got %d.\n", + s, n->value); + } + + next = CK_STAILQ_NEXT(n, list_entry); + if (next != NULL && next->value != s - 1) { + ck_error("\nExpected %d, but got %d.\n", + s, next->value); + } + + i--; + } + + if (i == 0 || CK_STAILQ_EMPTY(&head) == true) + break; + } + + fprintf(stderr, "(%d, %d) ", j, k); + return; +} + +static void * +execute(void *c) +{ + + (void)c; + test_foreach(); + return NULL; +} + +int +main(int argc, char *argv[]) +{ + pthread_t *thread; + struct test *n, a, b; + struct test_list target; + int n_threads, i; + + if (argc != 3) { + ck_error("Usage: %s \n", argv[0]); + } + + n_threads = atoi(argv[1]); + if (n_threads < 1) { + ck_error("ERROR: Number of threads must be >= 1.\n"); + } + + thread = malloc(sizeof(pthread_t) * n_threads); + assert(thread != NULL); + + goal = atoi(argv[2]); + if (goal < 4) { + ck_error("ERROR: Number of entries must be >= 4.\n"); + } + + fprintf(stderr, "Beginning serial test..."); + CK_STAILQ_INIT(&head); + + for (i = 1; i <= goal; i++) { + n = malloc(sizeof *n); + assert(n != NULL); + n->value = i; + CK_STAILQ_INSERT_HEAD(&head, n, list_entry); + } + + test_foreach(); + + for (i = 1; i <= goal; i++) { + n = CK_STAILQ_FIRST(&head); + CK_STAILQ_REMOVE(&head, n, test, list_entry); + free(n); + } + + if (CK_STAILQ_EMPTY(&head) == false) { + ck_error("List is not empty after bulk removal.\n"); + } + + for (i = 1; i <= goal; i++) { + n = malloc(sizeof *n); + assert(n != NULL); + n->value = goal - i; + CK_STAILQ_INSERT_TAIL(&head, n, list_entry); + } + + test_foreach(); + + for (i = 1; i <= goal; i++) { + n = CK_STAILQ_FIRST(&head); + CK_STAILQ_REMOVE(&head, n, test, list_entry); + free(n); + } + + if (CK_STAILQ_EMPTY(&head) == false) { + ck_error("List is not empty after bulk removal.\n"); + } + + CK_STAILQ_INSERT_HEAD(&head, &a, list_entry); + CK_STAILQ_INSERT_HEAD(&head, &b, list_entry); + CK_STAILQ_REMOVE(&head, &a, test, list_entry); + if (CK_STAILQ_FIRST(&head) != &b) + ck_error("List is in invalid state.\n"); + CK_STAILQ_REMOVE(&head, &b, test, list_entry); + + if (CK_STAILQ_EMPTY(&head) == false) { + ck_error("List is not empty after bulk removal.\n"); + } + + CK_STAILQ_INSERT_HEAD(&head, &a, list_entry); + CK_STAILQ_INSERT_AFTER(&head, &a, &b, list_entry); + + if (CK_STAILQ_NEXT(&b, list_entry) != NULL) + ck_error("Inserted item after last, it should not have no next.\n"); + + CK_STAILQ_INIT(&head); + + CK_STAILQ_INSERT_HEAD(&head, &a, list_entry); + if (CK_STAILQ_NEXT(&a, list_entry) != NULL) + ck_error("Inserted item as last, but it contains next pointer.\n"); + + CK_STAILQ_INIT(&head); + fprintf(stderr, "done (success)\n"); + + fprintf(stderr, "Beginning parallel traversal..."); + + n = malloc(sizeof *n); + assert(n != NULL); + n->value = 1; + CK_STAILQ_INSERT_HEAD(&head, n, list_entry); + + for (i = 0; i < n_threads; i++) { + int r = pthread_create(&thread[i], NULL, execute, NULL); + assert(r == 0); + } + + for (i = 2; i <= goal; i++) { + volatile int j; + + n = malloc(sizeof *n); + assert(n != NULL); + n->value = i; + CK_STAILQ_INSERT_HEAD(&head, n, list_entry); + for (j = 0; j <= 1000; j++); + } + + for (i = 0; i < n_threads; i++) + pthread_join(thread[i], NULL); + + for (i = 0; i < n_threads; i++) { + int r = pthread_create(&thread[i], NULL, execute, NULL); + assert(r == 0); + } + + CK_STAILQ_MOVE(&target, &head, list_entry); + + for (i = 1; i <= goal; i++) { + volatile int j; + + if (CK_STAILQ_EMPTY(&target) == false) { + struct test *r = CK_STAILQ_FIRST(&target); + CK_STAILQ_REMOVE(&target, r, test, list_entry); + } + + for (j = 0; j <= 1000; j++); + } + + for (i = 0; i < n_threads; i++) + pthread_join(thread[i], NULL); + + fprintf(stderr, "done (success)\n"); + return (0); +} + diff --git a/regressions/ck_ring/benchmark/Makefile b/regressions/ck_ring/benchmark/Makefile index 7457654..4087ed1 100644 --- a/regressions/ck_ring/benchmark/Makefile +++ b/regressions/ck_ring/benchmark/Makefile @@ -8,7 +8,7 @@ latency: latency.c ../../../include/ck_ring.h $(CC) $(CFLAGS) -o latency latency.c clean: - rm -rf *~ *.o $(OBJECTS) *.dSYM + rm -rf *~ *.o $(OBJECTS) *.dSYM *.exe include ../../../build/regressions.build CFLAGS+=-D_GNU_SOURCE diff --git a/regressions/ck_ring/validate/Makefile b/regressions/ck_ring/validate/Makefile index a0b51cc..83d4273 100644 --- a/regressions/ck_ring/validate/Makefile +++ b/regressions/ck_ring/validate/Makefile @@ -1,7 +1,7 @@ .PHONY: check clean distribution OBJECTS=ck_ring_spsc ck_ring_spsc_template ck_ring_spmc ck_ring_spmc_template -SIZE=65536 +SIZE=16384 all: $(OBJECTS) @@ -28,7 +28,7 @@ ck_ring_spmc: ck_ring_spmc.c ../../../include/ck_ring.h ../../../src/ck_barrier_centralized.c clean: - rm -rf *~ *.o $(OBJECTS) *.dSYM + rm -rf *~ *.o $(OBJECTS) *.dSYM *.exe include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_ring/validate/ck_ring_spmc.c b/regressions/ck_ring/validate/ck_ring_spmc.c index 3655a6c..75b8d18 100644 --- a/regressions/ck_ring/validate/ck_ring_spmc.c +++ b/regressions/ck_ring/validate/ck_ring_spmc.c @@ -66,7 +66,8 @@ test_spmc(void *c) { unsigned int observed = 0; unsigned long previous = 0; - int i, j, tid; + unsigned int seed; + int i, k, j, tid; (void)c; if (aff_iterate(&a)) { @@ -81,6 +82,7 @@ test_spmc(void *c) for (i = 0; i < ITERATIONS; i++) { for (j = 0; j < size; j++) { struct entry *o; + int spin; /* Keep trying until we encounter at least one node. */ if (j & 1) { @@ -107,6 +109,13 @@ test_spmc(void *c) ck_error("[%p] We dequeued twice.\n", (void *)o); } + if ((i % 4) == 0) { + spin = common_rand_r(&seed) % 16384; + for (k = 0; k < spin; k++) { + ck_pr_stall(); + } + } + free(o); } } @@ -120,6 +129,7 @@ test(void *c) { struct context *context = c; struct entry *entry; + unsigned int s; int i, j; bool r; ck_barrier_centralized_state_t sense = @@ -145,7 +155,18 @@ test(void *c) entries[i].value = i; entries[i].tid = 0; - r = ck_ring_enqueue_spmc(ring, entries + i); + if (i & 1) { + r = ck_ring_enqueue_spmc(ring, entries + i); + } else { + r = ck_ring_enqueue_spmc_size(ring, + entries + i, &s); + + if ((int)s != i) { + ck_error("Size is %u, expected %d.\n", + s, size); + } + } + assert(r != false); } @@ -180,7 +201,19 @@ test(void *c) } entry->tid = context->tid; - r = ck_ring_enqueue_spmc(ring + context->tid, entry); + + if (i & 1) { + r = ck_ring_enqueue_spmc(ring + context->tid, + entry); + } else { + r = ck_ring_enqueue_spmc_size(ring + context->tid, + entry, &s); + + if ((int)s >= size) { + ck_error("Size %u out of range of %d\n", + s, size); + } + } assert(r == true); } } @@ -208,7 +241,7 @@ main(int argc, char *argv[]) assert(nthr >= 1); size = atoi(argv[3]); - assert(size > 4 && (size & size - 1) == 0); + assert(size >= 4 && (size & size - 1) == 0); size -= 1; ring = malloc(sizeof(ck_ring_t) * nthr); @@ -268,8 +301,21 @@ main(int argc, char *argv[]) entry->ref = 0; /* Wait until queue is not full. */ - while (ck_ring_enqueue_spmc(&ring_spmc, entry) == false) - ck_pr_stall(); + if (l & 1) { + while (ck_ring_enqueue_spmc(&ring_spmc, entry) == false) + ck_pr_stall(); + } else { + unsigned int s; + + while (ck_ring_enqueue_spmc_size(&ring_spmc, + entry, &s) == false) { + ck_pr_stall(); + } + + if ((int)s >= (size * ITERATIONS * (nthr - 1))) { + ck_error("MPMC: Unexpected size of %u\n", s); + } + } } for (i = 0; i < nthr - 1; i++) diff --git a/regressions/ck_ring/validate/ck_ring_spmc_template.c b/regressions/ck_ring/validate/ck_ring_spmc_template.c index f284710..379329b 100644 --- a/regressions/ck_ring/validate/ck_ring_spmc_template.c +++ b/regressions/ck_ring/validate/ck_ring_spmc_template.c @@ -121,6 +121,7 @@ test(void *c) { struct context *context = c; struct entry entry; + unsigned int s; int i, j; bool r; ck_barrier_centralized_state_t sense = @@ -141,7 +142,19 @@ test(void *c) memset(&entry, 0, sizeof(entry)); entry.value = i; - r = CK_RING_ENQUEUE_SPMC(spmc_ring, ring, &entry); + if (i & 1) { + r = CK_RING_ENQUEUE_SPMC(spmc_ring, ring, + &entry); + } else { + r = CK_RING_ENQUEUE_SPMC_SIZE(spmc_ring, ring, + &entry, &s); + + if ((int)s != i) { + ck_error("Size %u, expected %d.\n", + s, i); + } + } + assert(r != false); } @@ -201,7 +214,7 @@ main(int argc, char *argv[]) assert(nthr >= 1); size = atoi(argv[3]); - assert(size > 4 && (size & size - 1) == 0); + assert(size >= 4 && (size & size - 1) == 0); size -= 1; ring = malloc(sizeof(ck_ring_t) * nthr); diff --git a/regressions/ck_ring/validate/ck_ring_spsc.c b/regressions/ck_ring/validate/ck_ring_spsc.c index c54bf9e..9dbb079 100644 --- a/regressions/ck_ring/validate/ck_ring_spsc.c +++ b/regressions/ck_ring/validate/ck_ring_spsc.c @@ -59,6 +59,7 @@ test(void *c) { struct context *context = c; struct entry *entry; + unsigned int s; int i, j; bool r; ck_barrier_centralized_state_t sense = @@ -84,7 +85,18 @@ test(void *c) entries[i].value = i; entries[i].tid = 0; - r = ck_ring_enqueue_spsc(ring, entries + i); + if (i & 1) { + r = ck_ring_enqueue_spsc(ring, entries + i); + } else { + r = ck_ring_enqueue_spsc_size(ring, + entries + i, &s); + + if ((int)s != i) { + ck_error("Size is %u, expected %d\n", + s, i + 1); + } + } + assert(r != false); } @@ -116,7 +128,18 @@ test(void *c) } entry->tid = context->tid; - r = ck_ring_enqueue_spsc(ring + context->tid, entry); + if (i & 1) { + r = ck_ring_enqueue_spsc(ring + context->tid, + entry); + } else { + r = ck_ring_enqueue_spsc_size(ring + + context->tid, entry, &s); + + if ((int)s >= size) { + ck_error("Size %u is out of range %d\n", + s, size); + } + } assert(r == true); } } @@ -143,7 +166,7 @@ main(int argc, char *argv[]) assert(nthr >= 1); size = atoi(argv[3]); - assert(size > 4 && (size & size - 1) == 0); + assert(size >= 4 && (size & size - 1) == 0); size -= 1; ring = malloc(sizeof(ck_ring_t) * nthr); diff --git a/regressions/ck_ring/validate/ck_ring_spsc_template.c b/regressions/ck_ring/validate/ck_ring_spsc_template.c index 0cc0f69..d176986 100644 --- a/regressions/ck_ring/validate/ck_ring_spsc_template.c +++ b/regressions/ck_ring/validate/ck_ring_spsc_template.c @@ -60,6 +60,7 @@ test(void *c) { struct context *context = c; struct entry entry; + unsigned int s; int i, j; bool r; ck_barrier_centralized_state_t sense = @@ -85,7 +86,20 @@ test(void *c) entries[i].value = i; entries[i].tid = 0; - r = CK_RING_ENQUEUE_SPSC(entry_ring, ring, entries + i); + if (i & 1) { + r = CK_RING_ENQUEUE_SPSC(entry_ring, + ring, entries + i); + } else { + r = CK_RING_ENQUEUE_SPSC_SIZE(entry_ring, + ring, entries + i, &s); + + if ((int)s != i) { + ck_error("Size is %u, expected %d\n", + s, i); + } + } + + assert(r != false); } if (CK_RING_SIZE(entry_ring, ring) != @@ -113,7 +127,20 @@ test(void *c) } entry.tid = context->tid; - r = CK_RING_ENQUEUE_SPSC(entry_ring, ring + context->tid, &entry); + + if (i & 1) { + r = CK_RING_ENQUEUE_SPSC(entry_ring, + ring + context->tid, &entry); + } else { + r = CK_RING_ENQUEUE_SPSC_SIZE(entry_ring, + ring + context->tid, &entry, &s); + + if ((int)s >= size) { + ck_error("Size %u is out of range %d\n", + s, size); + } + } + assert(r == true); } } @@ -140,7 +167,7 @@ main(int argc, char *argv[]) assert(nthr >= 1); size = atoi(argv[3]); - assert(size > 4 && (size & size - 1) == 0); + assert(size >= 4 && (size & size - 1) == 0); size -= 1; ring = malloc(sizeof(CK_RING_INSTANCE(entry_ring)) * nthr); diff --git a/regressions/ck_rwlock/benchmark/Makefile b/regressions/ck_rwlock/benchmark/Makefile index 59c0b53..6f739d9 100644 --- a/regressions/ck_rwlock/benchmark/Makefile +++ b/regressions/ck_rwlock/benchmark/Makefile @@ -11,7 +11,7 @@ throughput: throughput.c ../../../include/ck_rwlock.h $(CC) $(CFLAGS) -o throughput throughput.c clean: - rm -rf *.dSYM *~ *.o $(OBJECTS) + rm -rf *.dSYM *.exe *~ *.o $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_rwlock/validate/Makefile b/regressions/ck_rwlock/validate/Makefile index 2dbaa37..eeab170 100644 --- a/regressions/ck_rwlock/validate/Makefile +++ b/regressions/ck_rwlock/validate/Makefile @@ -11,7 +11,7 @@ check: all ./validate $(CORES) 1 clean: - rm -rf *.dSYM *~ *.o $(OBJECTS) + rm -rf *.dSYM *.exe *~ *.o $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_sequence/validate/Makefile b/regressions/ck_sequence/validate/Makefile index 28e7db0..bc2e5be 100644 --- a/regressions/ck_sequence/validate/Makefile +++ b/regressions/ck_sequence/validate/Makefile @@ -11,7 +11,7 @@ check: all ./ck_sequence $(CORES) 1 clean: - rm -rf *~ *.o $(OBJECTS) *.dSYM + rm -rf *~ *.o $(OBJECTS) *.dSYM *.exe include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_spinlock/benchmark/Makefile b/regressions/ck_spinlock/benchmark/Makefile index 61e70db..14bd901 100644 --- a/regressions/ck_spinlock/benchmark/Makefile +++ b/regressions/ck_spinlock/benchmark/Makefile @@ -74,7 +74,7 @@ ck_anderson.LATENCY: ck_anderson.c $(CC) -DLATENCY $(CFLAGS) -o ck_anderson.LATENCY ck_anderson.c clean: - rm -rf *.dSYM $(OBJECTS) + rm -rf *.dSYM *.exe $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE -lm diff --git a/regressions/ck_spinlock/validate/Makefile b/regressions/ck_spinlock/validate/Makefile index 964085b..da37bae 100644 --- a/regressions/ck_spinlock/validate/Makefile +++ b/regressions/ck_spinlock/validate/Makefile @@ -47,7 +47,7 @@ ck_dec: ck_dec.c clean: rm -rf ck_ticket ck_mcs ck_dec ck_cas ck_fas ck_clh linux_spinlock ck_ticket_pb \ - ck_anderson ck_spinlock *.dSYM + ck_anderson ck_spinlock *.dSYM *.exe include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE -lm diff --git a/regressions/ck_stack/benchmark/Makefile b/regressions/ck_stack/benchmark/Makefile index 50e5a09..6e2df2a 100644 --- a/regressions/ck_stack/benchmark/Makefile +++ b/regressions/ck_stack/benchmark/Makefile @@ -8,7 +8,7 @@ latency: latency.c $(CC) $(CFLAGS) -o latency latency.c clean: - rm -rf *~ *.o *.dSYM $(OBJECTS) + rm -rf *~ *.o *.dSYM *.exe $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_stack/validate/Makefile b/regressions/ck_stack/validate/Makefile index b81c166..519dca1 100644 --- a/regressions/ck_stack/validate/Makefile +++ b/regressions/ck_stack/validate/Makefile @@ -50,7 +50,7 @@ mpmc_trypair mpmc_pair spinlock_pair spinlock_eb_pair pthreads_pair: pair.c $(CC) -DPTHREADS $(CFLAGS) -o pthreads_pair pair.c clean: - rm -rf *~ *.o *.dSYM $(OBJECTS) + rm -rf *~ *.o *.dSYM *.exe $(OBJECTS) include ../../../build/regressions.build CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_stack/validate/pair.c b/regressions/ck_stack/validate/pair.c index c26b11c..c0f1bb1 100644 --- a/regressions/ck_stack/validate/pair.c +++ b/regressions/ck_stack/validate/pair.c @@ -233,13 +233,17 @@ main(int argc, char *argv[]) for (i = 0; i < nthr; i++) pthread_create(&thread[i], NULL, stack_thread, bucket + i); - gettimeofday(&stv, NULL); + common_gettimeofday(&stv, NULL); barrier = 1; for (i = 0; i < nthr; i++) pthread_join(thread[i], NULL); - gettimeofday(&etv, NULL); + common_gettimeofday(&etv, NULL); stack_assert(); +#ifdef _WIN32 + printf("%3llu %.6f\n", nthr, TVTOD(etv) - TVTOD(stv)); +#else printf("%3llu %.6lf\n", nthr, TVTOD(etv) - TVTOD(stv)); +#endif return 0; } diff --git a/regressions/ck_stack/validate/pop.c b/regressions/ck_stack/validate/pop.c index 3d06aef..c1f5809 100644 --- a/regressions/ck_stack/validate/pop.c +++ b/regressions/ck_stack/validate/pop.c @@ -253,13 +253,17 @@ main(int argc, char *argv[]) for (i = 0; i < nthr; i++) pthread_create(&thread[i], NULL, stack_thread, NULL); - gettimeofday(&stv, NULL); + common_gettimeofday(&stv, NULL); barrier = 1; for (i = 0; i < nthr; i++) pthread_join(thread[i], NULL); - gettimeofday(&etv, NULL); + common_gettimeofday(&etv, NULL); stack_assert(); +#ifdef _WIN32 + printf("%3llu %.6f\n", nthr, TVTOD(etv) - TVTOD(stv)); +#else printf("%3llu %.6lf\n", nthr, TVTOD(etv) - TVTOD(stv)); +#endif return 0; } diff --git a/regressions/ck_stack/validate/push.c b/regressions/ck_stack/validate/push.c index 44d515b..a2aa1db 100644 --- a/regressions/ck_stack/validate/push.c +++ b/regressions/ck_stack/validate/push.c @@ -232,13 +232,17 @@ main(int argc, char *argv[]) for (i = 0; i < nthr; i++) pthread_create(&thread[i], NULL, stack_thread, bucket + i * n); - gettimeofday(&stv, NULL); + common_gettimeofday(&stv, NULL); barrier = 1; for (i = 0; i < nthr; i++) pthread_join(thread[i], NULL); - gettimeofday(&etv, NULL); + common_gettimeofday(&etv, NULL); stack_assert(); +#ifdef _WIN32 + printf("%3llu %.6f\n", nthr, TVTOD(etv) - TVTOD(stv)); +#else printf("%3llu %.6lf\n", nthr, TVTOD(etv) - TVTOD(stv)); +#endif return 0; } diff --git a/regressions/common.h b/regressions/common.h index c06a145..ce5aa92 100644 --- a/regressions/common.h +++ b/regressions/common.h @@ -29,6 +29,7 @@ #include #include #include +#include #ifdef __linux__ #include @@ -37,12 +38,13 @@ #elif defined(__MACH__) #include #include -#include #endif #if defined(_WIN32) #include +#include #include +#define DELTA_EPOCH 11644473600000000ULL #else #include #include @@ -128,6 +130,48 @@ common_sleep(unsigned int n) #endif } +CK_CC_INLINE static int +common_gettimeofday(struct timeval *tv, void *tz) +{ +#ifdef _WIN32 + FILETIME ft; + uint64_t tmp_time = 0; + static bool tzflag = false; + struct timezone *tzp = tz; + + if (tv != NULL) { + GetSystemTimeAsFileTime(&ft); + tmp_time |= ft.dwHighDateTime; + tmp_time <<= 32; + tmp_time |= ft.dwLowDateTime; + + /* GetSystemTimeAsFileTime returns 100 nanosecond intervals. */ + tmp_time /= 10; + + /* Windows' epoch starts on 01/01/1601, while Unix' starts on 01/01/1970. */ + tmp_time -= DELTA_EPOCH; + + tv->tv_sec = (long)(tmp_time / 1000000UL); + tv->tv_usec = (long)(tmp_time % 1000000UL); + } + + + if (tz != NULL) { + if (tzflag == false) { + _tzset(); + tzflag = true; + } + + tzp->tz_minuteswest = _timezone / 60; + tzp->tz_dsttime = _daylight; + } + + return 0; +#else + return gettimeofday(tv, tz); +#endif +} + CK_CC_UNUSED static unsigned int common_alarm(void (*sig_handler)(int), void *alarm_event, unsigned int duration) { @@ -135,7 +179,7 @@ common_alarm(void (*sig_handler)(int), void *alarm_event, unsigned int duration) (void)sig_handler; (void)duration; bool success; - HANDLE *alarm_handle = (HANDLE *)alarm_event; + HANDLE *alarm_handle = alarm_event; success = SetEvent(*alarm_handle); assert(success != false); return 0; @@ -150,55 +194,63 @@ common_alarm(void (*sig_handler)(int), void *alarm_event, unsigned int duration) #ifndef SECOND_TIMER #define SECOND_TIMER 10000000 #endif -#define COMMON_ALARM_DECLARE_GLOBAL(alarm_event_name, flag_name) \ -static HANDLE common_win_alarm_timer; \ -static HANDLE alarm_event_name; \ -static LARGE_INTEGER timer_length; \ - \ -static void CALLBACK \ -common_win_alarm_handler(LPVOID arg, DWORD timer_low_value, DWORD timer_high_value) \ -{ \ - (void)arg; \ - (void)timer_low_value; \ - (void)timer_high_value; \ - flag_name = true; \ - return; \ -} \ - \ -static void * \ -common_win_alarm(void *unused) \ -{ \ - (void)unused; \ - bool timer_success = false; \ - for (;;) { \ - WaitForSingleObjectEx(alarm_event_name, INFINITE, true); \ - timer_success = SetWaitableTimer(common_win_alarm_timer, &timer_length, 0, common_win_alarm_handler, NULL, false); \ - assert(timer_success != false); \ - WaitForSingleObjectEx(common_win_alarm_timer, INFINITE, true); \ - } \ - \ - return NULL; \ +#define COMMON_ALARM_DECLARE_GLOBAL(prefix, alarm_event_name, flag_name) \ +static HANDLE prefix##_common_win_alarm_timer; \ +static HANDLE alarm_event_name; \ +static LARGE_INTEGER prefix##_common_alarm_timer_length; \ + \ +static void CALLBACK \ +prefix##_common_win_alarm_handler(LPVOID arg, DWORD timer_low_value, DWORD timer_high_value) \ +{ \ + (void)arg; \ + (void)timer_low_value; \ + (void)timer_high_value; \ + flag_name = true; \ + return; \ +} \ + \ +static void * \ +prefix##_common_win_alarm(void *unused) \ +{ \ + (void)unused; \ + bool timer_success = false; \ + for (;;) { \ + WaitForSingleObjectEx(alarm_event_name, INFINITE, true); \ + timer_success = SetWaitableTimer(prefix##_common_win_alarm_timer, \ + &prefix##_common_alarm_timer_length, \ + 0, \ + prefix##_common_win_alarm_handler, NULL, false); \ + assert(timer_success != false); \ + WaitForSingleObjectEx(prefix##_common_win_alarm_timer, INFINITE, true); \ + } \ + \ + return NULL; \ } -#define COMMON_ALARM_DECLARE_LOCAL(alarm_event_name) \ - __int64 tl; \ - pthread_t common_win_alarm_thread; - -#define COMMON_ALARM_INIT(alarm_event_name, duration) \ - tl = -1 * duration * SECOND_TIMER; \ - timer_length.LowPart = (DWORD) (tl & 0xFFFFFFFF); \ - timer_length.HighPart = (LONG) (tl >> 32); \ - alarm_event_name = CreateEvent(NULL, false, false, NULL); \ - assert(alarm_event_name != NULL); \ - common_win_alarm_timer = CreateWaitableTimer(NULL, true, NULL); \ - assert(common_win_alarm_timer != NULL); \ - if (pthread_create(&common_win_alarm_thread, NULL, common_win_alarm, NULL) != 0) \ +#define COMMON_ALARM_DECLARE_LOCAL(prefix, alarm_event_name) \ + int64_t prefix##_common_alarm_tl; \ + pthread_t prefix##_common_win_alarm_thread; + +#define COMMON_ALARM_INIT(prefix, alarm_event_name, duration) \ + prefix##_common_alarm_tl = -1 * (duration) * SECOND_TIMER; \ + prefix##_common_alarm_timer_length.LowPart = \ + (DWORD) (prefix##_common_alarm_tl & 0xFFFFFFFF); \ + prefix##_common_alarm_timer_length.HighPart = \ + (LONG) (prefix##_common_alarm_tl >> 32); \ + alarm_event_name = CreateEvent(NULL, false, false, NULL); \ + assert(alarm_event_name != NULL); \ + prefix##_common_win_alarm_timer = CreateWaitableTimer(NULL, true, NULL); \ + assert(prefix##_common_win_alarm_timer != NULL); \ + if (pthread_create(&prefix##_common_win_alarm_thread, \ + NULL, \ + prefix##_common_win_alarm, \ + NULL) != 0) \ ck_error("ERROR: Failed to create common_win_alarm thread.\n"); #else -#define COMMON_ALARM_DECLARE_GLOBAL(alarm_event_name, flag_name) -#define COMMON_ALARM_DECLARE_LOCAL(alarm_event_name) \ +#define COMMON_ALARM_DECLARE_GLOBAL(prefix, alarm_event_name, flag_name) +#define COMMON_ALARM_DECLARE_LOCAL(prefix, alarm_event_name) \ int alarm_event_name = 0; -#define COMMON_ALARM_INIT(alarm_event_name, duration) +#define COMMON_ALARM_INIT(prefix, alarm_event_name, duration) #endif struct affinity {