From dc8f36c96c0ecb5a7d482bbfa95f1ee37a954d49 Mon Sep 17 00:00:00 2001 From: Samy Al Bahra Date: Thu, 12 Mar 2015 00:38:35 -0400 Subject: [PATCH 01/10] whitespace/spinlock: Remove extraneous end of file lines. --- include/spinlock/anderson.h | 1 - include/spinlock/cas.h | 1 - include/spinlock/clh.h | 1 - include/spinlock/dec.h | 1 - include/spinlock/fas.h | 1 - include/spinlock/hclh.h | 1 - include/spinlock/mcs.h | 1 - include/spinlock/ticket.h | 1 - 8 files changed, 8 deletions(-) diff --git a/include/spinlock/anderson.h b/include/spinlock/anderson.h index 8b2cf87..1386b18 100644 --- a/include/spinlock/anderson.h +++ b/include/spinlock/anderson.h @@ -162,4 +162,3 @@ ck_spinlock_anderson_unlock(struct ck_spinlock_anderson *lock, } #endif /* CK_F_SPINLOCK_ANDERSON */ #endif /* _CK_SPINLOCK_ANDERSON_H */ - diff --git a/include/spinlock/cas.h b/include/spinlock/cas.h index bda2bb3..ca087e3 100644 --- a/include/spinlock/cas.h +++ b/include/spinlock/cas.h @@ -118,4 +118,3 @@ CK_ELIDE_TRYLOCK_PROTOTYPE(ck_spinlock_cas, ck_spinlock_cas_t, #endif /* CK_F_SPINLOCK_CAS */ #endif /* _CK_SPINLOCK_CAS_H */ - diff --git a/include/spinlock/clh.h b/include/spinlock/clh.h index 4252ec3..b066244 100644 --- a/include/spinlock/clh.h +++ b/include/spinlock/clh.h @@ -114,4 +114,3 @@ ck_spinlock_clh_unlock(struct ck_spinlock_clh **thread) } #endif /* CK_F_SPINLOCK_CLH */ #endif /* _CK_SPINLOCK_CLH_H */ - diff --git a/include/spinlock/dec.h b/include/spinlock/dec.h index 350bbf2..35f44c1 100644 --- a/include/spinlock/dec.h +++ b/include/spinlock/dec.h @@ -140,4 +140,3 @@ CK_ELIDE_TRYLOCK_PROTOTYPE(ck_spinlock_dec, ck_spinlock_dec_t, #endif /* CK_F_SPINLOCK_DEC */ #endif /* _CK_SPINLOCK_DEC_H */ - diff --git a/include/spinlock/fas.h b/include/spinlock/fas.h index 6886e35..1774919 100644 --- a/include/spinlock/fas.h +++ b/include/spinlock/fas.h @@ -115,4 +115,3 @@ CK_ELIDE_TRYLOCK_PROTOTYPE(ck_spinlock_fas, ck_spinlock_fas_t, #endif /* CK_F_SPINLOCK_FAS */ #endif /* _CK_SPINLOCK_FAS_H */ - diff --git a/include/spinlock/hclh.h b/include/spinlock/hclh.h index dbae512..0838edb 100644 --- a/include/spinlock/hclh.h +++ b/include/spinlock/hclh.h @@ -142,4 +142,3 @@ ck_spinlock_hclh_unlock(struct ck_spinlock_hclh **thread) } #endif /* CK_F_SPINLOCK_HCLH */ #endif /* _CK_SPINLOCK_HCLH_H */ - diff --git a/include/spinlock/mcs.h b/include/spinlock/mcs.h index 54cddca..f0d0e77 100644 --- a/include/spinlock/mcs.h +++ b/include/spinlock/mcs.h @@ -146,4 +146,3 @@ ck_spinlock_mcs_unlock(struct ck_spinlock_mcs **queue, struct ck_spinlock_mcs *n } #endif /* CK_F_SPINLOCK_MCS */ #endif /* _CK_SPINLOCK_MCS_H */ - diff --git a/include/spinlock/ticket.h b/include/spinlock/ticket.h index 703feb7..de68851 100644 --- a/include/spinlock/ticket.h +++ b/include/spinlock/ticket.h @@ -295,4 +295,3 @@ CK_ELIDE_TRYLOCK_PROTOTYPE(ck_spinlock_ticket, ck_spinlock_ticket_t, #endif /* CK_F_SPINLOCK_TICKET */ #endif /* _CK_SPINLOCK_TICKET_H */ - From 14744714453530139b0f58e9bb94671d70c20871 Mon Sep 17 00:00:00 2001 From: Samy Al Bahra Date: Thu, 12 Mar 2015 02:14:27 -0400 Subject: [PATCH 02/10] ck_pr: Add basic ck_pr_rfo interface. This leverages prefetchw that is now finally available on both AMD and Intel processors. Additional ports coming. --- configure | 15 ++++++++++++--- include/ck_md.h.in | 4 ++++ include/ck_pr.h | 11 +++++++++++ include/gcc/x86_64/ck_pr.h | 20 ++++++++++++++++++++ 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 6df241a..7673b4d 100755 --- a/configure +++ b/configure @@ -103,6 +103,7 @@ generate() -e "s#@GZIP_SUFFIX@#$GZIP_SUFFIX#g" \ -e "s#@POINTER_PACK_ENABLE@#$POINTER_PACK_ENABLE#g" \ -e "s#@RTM_ENABLE@#$RTM_ENABLE#g" \ + -e "s#@RFO_ENABLE@#$RFO_ENABLE#g" \ -e "s#@VMA_BITS@#$VMA_BITS_R#g" \ -e "s#@VMA_BITS_VALUE@#$VMA_BITS_VALUE_R#g" \ -e "s#@MM@#$MM#g" \ @@ -137,6 +138,7 @@ generate_stdout() echo " POINTER_PACK = $POINTER_PACK_ENABLE" echo " VMA_BITS = $VMA_BITS" echo " MEMORY_MODEL = $MM" + echo " RFO = $RFO_ENABLE" echo " RTM = $RTM_ENABLE" echo echo "Headers will be installed in $HEADERS" @@ -170,13 +172,16 @@ for option; do echo " --mandir=N Manual pages directory (default is ${PREFIX}/man)" echo " --prefix=N Installs library files in N (default is $PREFIX)" echo - echo "The following options will modify code generation." - echo " --cores=N Specify number of cores available on target machine" + echo "The following options will affect generated code." echo " --enable-pointer-packing Assumes address encoding is subset of pointer range" - echo " --enable-rtm Enable restricted transactional memory (x86_64 only)" + echo " --enable-rtm Enable restricted transactional memory (power, x86_64)" + echo " --enable-rfo Enable read-for-ownership interface (power, x86_64)" echo " --memory-model=N Specify memory model (currently tso, pso or rmo)" echo " --vma-bits=N Specify valid number of VMA bits" echo + echo "The following options affect regression testing." + echo " --cores=N Specify number of cores available on target machine" + echo echo "The following environment variables may be used:" echo " CC C compiler command" echo " CFLAGS C compiler flags" @@ -212,6 +217,9 @@ for option; do --enable-rtm) RTM_ENABLE_SET="CK_MD_RTM_ENABLE" ;; + --enable-rfo) + RFO_ENABLE_SET="CK_MD_RFO_ENABLE" + ;; --cores=*) CORES=$value ;; @@ -272,6 +280,7 @@ MANDIR=${MANDIR:-"${PREFIX}/share/man"} GZIP=${GZIP:-"gzip -c"} POINTER_PACK_ENABLE=${POINTER_PACK_ENABLE:-"CK_MD_POINTER_PACK_DISABLE"} RTM_ENABLE=${RTM_ENABLE_SET:-"CK_MD_RTM_DISABLE"} +RFO_ENABLE=${RFO_ENABLE_SET:-"CK_MD_RFO_DISABLE"} VMA_BITS=${VMA_BITS:-"unknown"} if test "$PROFILE"; then diff --git a/include/ck_md.h.in b/include/ck_md.h.in index 4449cf8..63cbbf0 100644 --- a/include/ck_md.h.in +++ b/include/ck_md.h.in @@ -39,6 +39,10 @@ #define @RTM_ENABLE@ #endif /* @RTM_ENABLE@ */ +#ifndef @RFO_ENABLE@ +#define @RFO_ENABLE@ +#endif /* @RFO_ENABLE@ */ + #ifndef @POINTER_PACK_ENABLE@ #define @POINTER_PACK_ENABLE@ #endif /* @POINTER_PACK_ENABLE@ */ diff --git a/include/ck_pr.h b/include/ck_pr.h index 3ceea4c..f5533bb 100644 --- a/include/ck_pr.h +++ b/include/ck_pr.h @@ -138,6 +138,17 @@ CK_PR_FENCE_NOOP(release) #undef CK_PR_FENCE_EMIT #undef CK_PR_FENCE_NOOP +#ifndef CK_F_PR_RFO +#define CK_F_PR_RFO +CK_CC_INLINE static void +ck_pr_rfo(const void *m) +{ + + (void)m; + return; +} +#endif /* CK_F_PR_RFO */ + #define CK_PR_BIN(K, S, M, T, P, C) \ CK_CC_INLINE static void \ ck_pr_##K##_##S(M *target, T value) \ diff --git a/include/gcc/x86_64/ck_pr.h b/include/gcc/x86_64/ck_pr.h index 5dfa626..b57a845 100644 --- a/include/gcc/x86_64/ck_pr.h +++ b/include/gcc/x86_64/ck_pr.h @@ -91,6 +91,26 @@ CK_PR_FENCE(acquire, "mfence") #undef CK_PR_FENCE +/* + * Read for ownership. Older compilers will generate the 32-bit + * 3DNow! variant which is binary compatible with x86-64 variant + * of prefetchw. + */ +#ifdef CK_MD_RFO_ENABLE +#define CK_F_PR_RFO +CK_CC_INLINE static void +ck_pr_rfo(const void *m) +{ + + __asm__ __volatile__("prefetchw (%0)" + : + : "r" (m) + : "memory"); + + return; +} +#endif /* CD_MD_PREFETCHW_ENABLE */ + /* * Atomic fetch-and-store operations. */ From 5b76fe392827a667e542368ab4a6a41770c8eeed Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 13 Mar 2015 18:05:51 -0400 Subject: [PATCH 03/10] doc/Makefile: enforce consistent suffixes Signed-off-by: Emilio G. Cota --- doc/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Makefile.in b/doc/Makefile.in index dbd9daa..811cc7f 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -199,5 +199,5 @@ uninstall: done clean: - rm -f $(BUILD_DIR)/doc/*~ $(BUILD_DIR)/doc/*.3.gz $(BUILD_DIR)/doc/*.html + rm -f $(BUILD_DIR)/doc/*~ $(BUILD_DIR)/doc/*$(GZIP_SUFFIX) $(BUILD_DIR)/doc/*$(HTML_SUFFIX) From b4b916d7135b7dae7a80ea20ed4d890457308517 Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 13 Mar 2015 18:06:57 -0400 Subject: [PATCH 04/10] doc/Makefile: add 'objcheck' target to check for missing OBJECTS ck/doc$ make objcheck 1>/dev/null ck_hs_put_unique is missing from OBJECTS ck_rhs_put_unique is missing from OBJECTS Signed-off-by: Emilio G. Cota --- doc/Makefile.in | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/Makefile.in b/doc/Makefile.in index 811cc7f..78cbe4e 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -189,6 +189,14 @@ html: $(BUILD_DIR)/doc/$$target$(HTML_SUFFIX); \ done +# check for entries that are missing in OBJECTS +objcheck: all + for file in `ls * | egrep '(ck|CK)_' | egrep -v "($(GZIP_SUFFIX)|$(HTML_SUFFIX))$$"`; do \ + if [ ! -f $${file}$(GZIP_SUFFIX) ]; then \ + echo "$$file is missing from OBJECTS" >&2; \ + fi; \ + done + install: mkdir -p $(DESTDIR)/$(MANDIR)/man3 || exit cp *$(GZIP_SUFFIX) $(DESTDIR)/$(MANDIR)/man3 || exit From 055ec1108053e5424c8f324e19be59616937769e Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 13 Mar 2015 18:13:23 -0400 Subject: [PATCH 05/10] doc/Makefile: add missing files to OBJECTS Signed-off-by: Emilio G. Cota --- doc/Makefile.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/Makefile.in b/doc/Makefile.in index 78cbe4e..b79beb5 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -79,6 +79,7 @@ OBJECTS=CK_ARRAY_FOREACH \ ck_hs_next \ ck_hs_get \ ck_hs_put \ + ck_hs_put_unique \ ck_hs_set \ ck_hs_fas \ ck_hs_remove \ @@ -98,6 +99,7 @@ OBJECTS=CK_ARRAY_FOREACH \ ck_rhs_next \ ck_rhs_get \ ck_rhs_put \ + ck_rhs_put_unique \ ck_rhs_set \ ck_rhs_fas \ ck_rhs_remove \ From 1d3300ac3ab2e37b304efe8df61a834752fc1c9d Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 13 Mar 2015 18:16:18 -0400 Subject: [PATCH 06/10] doc/Makefile: add 'refcheck' to find missing cross-references Some missing references found are not surprising (e.g. *_INITIALIZER), but real mistakes are also found (ck_ht_init->ck_entry_set_direct). ck/doc$ make refcheck ck_brlock: ref to missing ck_bytelock(3) ck_ht_get_spmc: ref to missing ck_ht_entry_set_key(3) ck_ht_init: ref to missing ck_entry_set_direct(3) ck_ht_remove_spmc: ref to missing ck_ht_entry_set_key(3) ck_bitmap_test: ref to missing ck_bitmap_set_mpmc(3) ck_bitmap_test: ref to missing ck_bitmap_reset_mpmc(3) ck_bitmap_size: ref to missing ck_bitmap_set_mpmc(3) ck_bitmap_size: ref to missing ck_bitmap_reset_mpmc(3) ck_rwcohort: ref to missing CK_RWCOHORT_STRATEGY_PROTOTYPE(3) ck_rwcohort: ref to missing CK_COHORT_INITIALIZER(3) ck_rwcohort: ref to missing CK_COHORT_LOCKED(3) CK_RWCOHORT_INIT: ref to missing CK_RWCOHORT_TRYLOCK_PROTOTYPE(3) CK_RWCOHORT_INIT: ref to missing CK_RWCOHORT_INITIALIZER(3) CK_RWCOHORT_INIT: ref to missing CK_RWCOHORT_LOCK(3) CK_RWCOHORT_INIT: ref to missing CK_RWCOHORT_UNLOCK(3) CK_RWCOHORT_INIT: ref to missing CK_RWCOHORT_LOCKED(3) CK_RWCOHORT_INIT: ref to missing CK_RWCOHORT_TRYLOCK(3) CK_RWCOHORT_INSTANCE: ref to missing CK_RWCOHORT_TRYLOCK_PROTOTYPE(3) CK_RWCOHORT_INSTANCE: ref to missing CK_RWCOHORT_INITIALIZER(3) CK_RWCOHORT_INSTANCE: ref to missing CK_RWCOHORT_LOCK(3) CK_RWCOHORT_INSTANCE: ref to missing CK_RWCOHORT_UNLOCK(3) CK_RWCOHORT_INSTANCE: ref to missing CK_RWCOHORT_LOCKED(3) CK_RWCOHORT_INSTANCE: ref to missing CK_RWCOHORT_TRYLOCK(3) CK_RWCOHORT_PROTOTYPE: ref to missing CK_RWCOHORT_INITIALIZER(3) CK_RWCOHORT_READ_LOCK: ref to missing CK_RWCOHORT_INITIALIZER(3) CK_RWCOHORT_READ_UNLOCK: ref to missing CK_RWCOHORT_INITIALIZER(3) CK_RWCOHORT_WRITE_LOCK: ref to missing CK_RWCOHORT_INITIALIZER(3) CK_RWCOHORT_WRITE_UNLOCK: ref to missing CK_RWCOHORT_INITIALIZER(3) ck_cohort: ref to missing CK_COHORT_LOCKED(3) ck_cohort: ref to missing CK_COHORT_INITIALIZER(3) ck_cohort: ref to missing CK_COHORT_LOCKED(3) CK_COHORT_PROTOTYPE: ref to missing CK_COHORT_INITIALIZER(3) CK_COHORT_PROTOTYPE: ref to missing CK_COHORT_LOCKED(3) CK_COHORT_TRYLOCK_PROTOTYPE: ref to missing CK_COHORT_INITIALIZER(3) CK_COHORT_TRYLOCK_PROTOTYPE: ref to missing CK_COHORT_LOCKED(3) CK_COHORT_INSTANCE: ref to missing CK_COHORT_INITIALIZER(3) CK_COHORT_INSTANCE: ref to missing CK_COHORT_LOCKED(3) CK_COHORT_INIT: ref to missing CK_COHORT_INITIALIZER(3) CK_COHORT_INIT: ref to missing CK_COHORT_LOCKED(3) CK_COHORT_LOCK: ref to missing CK_COHORT_INITIALIZER(3) CK_COHORT_LOCK: ref to missing CK_COHORT_LOCKED(3) CK_COHORT_UNLOCK: ref to missing CK_COHORT_INITIALIZER(3) CK_COHORT_UNLOCK: ref to missing CK_COHORT_LOCKED(3) CK_COHORT_TRYLOCK: ref to missing CK_COHORT_INITIALIZER(3) CK_COHORT_TRYLOCK: ref to missing CK_COHORT_LOCKED(3) ck_sequence: ref to missing ck_bytelock(3) Signed-off-by: Emilio G. Cota --- doc/Makefile.in | 4 ++++ doc/refcheck.pl | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100755 doc/refcheck.pl diff --git a/doc/Makefile.in b/doc/Makefile.in index b79beb5..1915f2a 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -199,6 +199,10 @@ objcheck: all fi; \ done +# check for stale references +refcheck: + @./refcheck.pl $(OBJECTS) + install: mkdir -p $(DESTDIR)/$(MANDIR)/man3 || exit cp *$(GZIP_SUFFIX) $(DESTDIR)/$(MANDIR)/man3 || exit diff --git a/doc/refcheck.pl b/doc/refcheck.pl new file mode 100755 index 0000000..1ed3a65 --- /dev/null +++ b/doc/refcheck.pl @@ -0,0 +1,27 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +my @files = @ARGV; + +my $h; + +foreach my $file (@files) { + $h->{$file} = 1; +} + +foreach my $file (@files) { + open(my $fh, "<", $file) or die "cannot open < $file: $!"; + while (<$fh>) { + chomp; + if ($_ =~ /\.Xr ((ck|CK)_[a-zA-Z_]+) ([0-9])/) { + my $name = $1; + my $section = $3; + if (!$h->{$name}) { + print STDERR "$file: ref to missing ${name}($section)\n"; + } + } + } + close($fh) or die("cannot close $file: $!"); +} From ed3339eb203504fe9804ce7285a476e96153ab1f Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 13 Mar 2015 18:19:30 -0400 Subject: [PATCH 07/10] doc/ck_ht_init: fix reference to ck_ht_entry_set_direct Signed-off-by: Emilio G. Cota --- doc/ck_ht_init | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ck_ht_init b/doc/ck_ht_init index 602483d..757a39a 100644 --- a/doc/ck_ht_init +++ b/doc/ck_ht_init @@ -76,7 +76,7 @@ with using the .Xr ck_ht_entry_key_direct 3 , .Xr ck_ht_entry_value_direct 3 and -.Xr ck_entry_set_direct 3 +.Xr ck_ht_entry_set_direct 3 functions. Attempting a hash table operation with a key of value of 0 or UINTPTR_MAX will result in undefined behavior. .El From 03915998a83b397c7a20bd5e2ad9d47175d7b62d Mon Sep 17 00:00:00 2001 From: Samy Al Bahra Date: Sat, 14 Mar 2015 21:36:23 -0400 Subject: [PATCH 08/10] ck_ht: Defer version counter increment to re-use. This has been on the TODO for a while and helps reduce read-side retries. It also has the advantage of providing true wait-freedom on insertion (including termination safety). --- src/ck_ht.c | 74 ++++++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/ck_ht.c b/src/ck_ht.c index 5e0e79d..45fc96d 100644 --- a/src/ck_ht.c +++ b/src/ck_ht.c @@ -451,6 +451,8 @@ ck_ht_gc(struct ck_ht *ht, unsigned long cycles, unsigned long seed) offset = h.value & map->mask; if (priority != NULL) { + ck_pr_store_64(&map->deletions, map->deletions + 1); + ck_pr_fence_store(); #ifndef CK_HT_PP ck_pr_store_64(&priority->key_length, entry->key_length); ck_pr_store_64(&priority->hash, entry->hash); @@ -463,8 +465,6 @@ ck_ht_gc(struct ck_ht *ht, unsigned long cycles, unsigned long seed) ck_pr_fence_store(); ck_pr_store_ptr(&entry->key, (void *)CK_HT_KEY_TOMBSTONE); ck_pr_fence_store(); - ck_pr_store_64(&map->deletions, map->deletions + 1); - ck_pr_fence_store(); } if (cycles == 0) { @@ -768,29 +768,8 @@ ck_ht_remove_spmc(struct ck_ht *table, return false; *entry = snapshot; - ck_pr_store_ptr(&candidate->key, (void *)CK_HT_KEY_TOMBSTONE); - /* - * It is possible that the key is read before transition into - * the tombstone state. Assuming the keys do match, a reader - * may have already acquired a snapshot of the value at the time. - * However, assume the reader is preempted as a deletion occurs - * followed by a replacement. In this case, it is possible that - * the reader acquires some value V' instead of V. Let us assume - * however that any transition from V into V' (essentially, update - * of a value without the reader knowing of a K -> K' transition), - * is preceded by an update to the deletions counter. This guarantees - * any replacement of a T key also implies a D -> D' transition. - * If D has not transitioned, the value has yet to be replaced so it - * is a valid association with K and is safe to return. If D has - * transitioned after a reader has acquired a snapshot then it is - * possible that we are in the invalid state of (K, V'). The reader - * is then able to attempt a reprobe at which point the only visible - * states should be (T, V') or (K', V'). The latter is guaranteed - * through memory fencing. - */ - ck_pr_fence_store(); - ck_pr_store_64(&map->deletions, map->deletions + 1); + ck_pr_store_ptr(&candidate->key, (void *)CK_HT_KEY_TOMBSTONE); ck_pr_fence_store(); ck_pr_store_64(&map->n_entries, map->n_entries - 1); return true; @@ -884,13 +863,11 @@ ck_ht_set_spmc(struct ck_ht *table, if (candidate->key != CK_HT_KEY_EMPTY && priority != NULL && candidate != priority) { /* - * If we are replacing an existing entry and an earlier - * tombstone was found in the probe sequence then replace - * the existing entry in a manner that doesn't affect linearizability - * of concurrent get operations. We avoid a state of (K, B) - * (where [K, B] -> [K', B]) by guaranteeing a forced reprobe - * before transitioning from K to T. (K, B) implies (K, B, D') - * so we will reprobe successfully from this transient state. + * Entry is moved into another position in probe sequence. + * We avoid a state of (K, B) (where [K, B] -> [K', B]) by + * guaranteeing a forced reprobe before transitioning from K to + * T. (K, B) implies (K, B, D') so we will reprobe successfully + * from this transient state. */ probes = probes_wr; @@ -898,28 +875,47 @@ ck_ht_set_spmc(struct ck_ht *table, ck_pr_store_64(&priority->key_length, entry->key_length); ck_pr_store_64(&priority->hash, entry->hash); #endif + + /* + * Readers must observe version counter change before they + * observe re-use. If they observe re-use, it is at most + * a tombstone. + */ + if (priority->value == CK_HT_KEY_TOMBSTONE) { + ck_pr_store_64(&map->deletions, map->deletions + 1); + ck_pr_fence_store(); + } + ck_pr_store_ptr(&priority->value, (void *)entry->value); ck_pr_fence_store(); ck_pr_store_ptr(&priority->key, (void *)entry->key); ck_pr_fence_store(); + + /* + * Make sure that readers who observe the tombstone would + * also observe counter change. + */ ck_pr_store_64(&map->deletions, map->deletions + 1); ck_pr_fence_store(); + ck_pr_store_ptr(&candidate->key, (void *)CK_HT_KEY_TOMBSTONE); ck_pr_fence_store(); - ck_pr_store_64(&map->deletions, map->deletions + 1); - ck_pr_fence_store(); } else { /* * In this case we are inserting a new entry or replacing - * an existing entry. There is no need to force a re-probe - * on tombstone replacement due to the fact that previous - * deletion counter update would have been published with - * respect to any concurrent probes. + * an existing entry. Yes, this can be combined into above branch, + * but isn't because you are actually looking at dying code + * (ck_ht is effectively deprecated and is being replaced soon). */ bool replace = candidate->key != CK_HT_KEY_EMPTY && candidate->key != CK_HT_KEY_TOMBSTONE; if (priority != NULL) { + if (priority->key == CK_HT_KEY_TOMBSTONE) { + ck_pr_store_64(&map->deletions, map->deletions + 1); + ck_pr_fence_store(); + } + candidate = priority; probes = probes_wr; } @@ -991,6 +987,10 @@ ck_ht_put_spmc(struct ck_ht *table, } if (priority != NULL) { + /* Version counter is updated before re-use. */ + ck_pr_store_64(&map->deletions, map->deletions + 1); + ck_pr_fence_store(); + /* Re-use tombstone if one was found. */ candidate = priority; probes = probes_wr; From 4214561c97dd0edb50fd52e217cd2915454893cc Mon Sep 17 00:00:00 2001 From: Samy Al Bahra Date: Sat, 14 Mar 2015 21:47:13 -0400 Subject: [PATCH 09/10] ck_pr: (Re-)introduce ck_pr_rfo. This was accidentally grouped into previous commit. The destiny of this interface for internal use is still unclear (in context of utilization in built-in data structures). The interface is enabled by default on x86, as it is compatible with read-side prefetch* operations and binary-compatible with 3DNow! extension. Older compilers will waste an additional byte (they generate 3DNow! variant) on this, but older compilers waste more on spillage if we encode instruction. Power support is coming soon. --- configure | 7 ------- include/ck_md.h.in | 4 ---- include/gcc/x86_64/ck_pr.h | 4 ++-- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/configure b/configure index 7673b4d..185ecba 100755 --- a/configure +++ b/configure @@ -103,7 +103,6 @@ generate() -e "s#@GZIP_SUFFIX@#$GZIP_SUFFIX#g" \ -e "s#@POINTER_PACK_ENABLE@#$POINTER_PACK_ENABLE#g" \ -e "s#@RTM_ENABLE@#$RTM_ENABLE#g" \ - -e "s#@RFO_ENABLE@#$RFO_ENABLE#g" \ -e "s#@VMA_BITS@#$VMA_BITS_R#g" \ -e "s#@VMA_BITS_VALUE@#$VMA_BITS_VALUE_R#g" \ -e "s#@MM@#$MM#g" \ @@ -138,7 +137,6 @@ generate_stdout() echo " POINTER_PACK = $POINTER_PACK_ENABLE" echo " VMA_BITS = $VMA_BITS" echo " MEMORY_MODEL = $MM" - echo " RFO = $RFO_ENABLE" echo " RTM = $RTM_ENABLE" echo echo "Headers will be installed in $HEADERS" @@ -175,7 +173,6 @@ for option; do echo "The following options will affect generated code." echo " --enable-pointer-packing Assumes address encoding is subset of pointer range" echo " --enable-rtm Enable restricted transactional memory (power, x86_64)" - echo " --enable-rfo Enable read-for-ownership interface (power, x86_64)" echo " --memory-model=N Specify memory model (currently tso, pso or rmo)" echo " --vma-bits=N Specify valid number of VMA bits" echo @@ -217,9 +214,6 @@ for option; do --enable-rtm) RTM_ENABLE_SET="CK_MD_RTM_ENABLE" ;; - --enable-rfo) - RFO_ENABLE_SET="CK_MD_RFO_ENABLE" - ;; --cores=*) CORES=$value ;; @@ -280,7 +274,6 @@ MANDIR=${MANDIR:-"${PREFIX}/share/man"} GZIP=${GZIP:-"gzip -c"} POINTER_PACK_ENABLE=${POINTER_PACK_ENABLE:-"CK_MD_POINTER_PACK_DISABLE"} RTM_ENABLE=${RTM_ENABLE_SET:-"CK_MD_RTM_DISABLE"} -RFO_ENABLE=${RFO_ENABLE_SET:-"CK_MD_RFO_DISABLE"} VMA_BITS=${VMA_BITS:-"unknown"} if test "$PROFILE"; then diff --git a/include/ck_md.h.in b/include/ck_md.h.in index 63cbbf0..4449cf8 100644 --- a/include/ck_md.h.in +++ b/include/ck_md.h.in @@ -39,10 +39,6 @@ #define @RTM_ENABLE@ #endif /* @RTM_ENABLE@ */ -#ifndef @RFO_ENABLE@ -#define @RFO_ENABLE@ -#endif /* @RFO_ENABLE@ */ - #ifndef @POINTER_PACK_ENABLE@ #define @POINTER_PACK_ENABLE@ #endif /* @POINTER_PACK_ENABLE@ */ diff --git a/include/gcc/x86_64/ck_pr.h b/include/gcc/x86_64/ck_pr.h index b57a845..1a71d31 100644 --- a/include/gcc/x86_64/ck_pr.h +++ b/include/gcc/x86_64/ck_pr.h @@ -96,7 +96,7 @@ CK_PR_FENCE(acquire, "mfence") * 3DNow! variant which is binary compatible with x86-64 variant * of prefetchw. */ -#ifdef CK_MD_RFO_ENABLE +#ifndef CK_F_PR_RFO #define CK_F_PR_RFO CK_CC_INLINE static void ck_pr_rfo(const void *m) @@ -109,7 +109,7 @@ ck_pr_rfo(const void *m) return; } -#endif /* CD_MD_PREFETCHW_ENABLE */ +#endif /* CK_F_PR_RFO */ /* * Atomic fetch-and-store operations. From 6faceae8ad58d549c2f03a453cc87c689c9317dd Mon Sep 17 00:00:00 2001 From: Samy Al Bahra Date: Sat, 14 Mar 2015 21:58:49 -0400 Subject: [PATCH 10/10] ck_ht: Make deprecation official. --- include/ck_ht.h | 4 ++++ src/ck_ht.c | 1 + 2 files changed, 5 insertions(+) diff --git a/include/ck_ht.h b/include/ck_ht.h index f58a925..df032ee 100644 --- a/include/ck_ht.h +++ b/include/ck_ht.h @@ -27,6 +27,10 @@ #ifndef _CK_HT_H #define _CK_HT_H +#ifndef _CK_HT_IM +#warning ck_ht is deprecated, see ck_hm, ck_hs or ck_rhs. +#endif /* !_CK_HT_IM */ + #include #if defined(CK_F_PR_LOAD_64) && defined(CK_F_PR_STORE_64) diff --git a/src/ck_ht.c b/src/ck_ht.c index 45fc96d..80a3bfe 100644 --- a/src/ck_ht.c +++ b/src/ck_ht.c @@ -24,6 +24,7 @@ * SUCH DAMAGE. */ +#define _CK_HT_IM #include #ifdef CK_F_HT