rculfhash: introduce cds_lfht_node_init_deleted master
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 10 Jan 2022 20:35:53 +0000 (15:35 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 18 Jan 2022 14:56:34 +0000 (09:56 -0500)
Allow initializing lfht node to "removed" state to allow querying
whether the node is published in a hash table before it is added to the
hash table and after it has been removed from the hash table.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I6e364a3ea076f33e34b4c63c7b23be22b35e9bb1

ChangeLog
include/urcu/arch.h
include/urcu/rculfhash.h
include/urcu/tls-compat.h
include/urcu/uatomic/x86.h
src/compat_arch.c
src/rculfhash.c
tests/unit/test_build.c

index fe236ace900199bab5b5abda814b918c8f32f5e3..c9c64b81797f6e5946cbbb6428c2995458cf46f5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,4 @@
-2020-06-03 Userspace RCU 0.13.0
+2021-06-03 Userspace RCU 0.13.0
        * Document known ABI issue in README.md
        * Add serialized ABI definition files
        * bump SONAME major to 8
index 620743c0f68fb33dd004d3266bcf900e2a96b898..d3914da27d41e9caf5158b2351ccc78b4b4b8ee8 100644 (file)
 #define URCU_ARCH_AMD64 1
 #include <urcu/arch/x86.h>
 
-#elif (defined(__i486__) || defined(__i586__) || defined(__i686__))
-
-#define URCU_ARCH_X86 1
-#include <urcu/arch/x86.h>
-
 #elif (defined(__i386__) || defined(__i386))
 
 #define URCU_ARCH_X86 1
+
+/*
+ * URCU_ARCH_X86_NO_CAS enables a compat layer that will detect the presence of
+ * the cmpxchg instructions at runtime and provide a compat mode based on a
+ * pthread mutex when it isn't.
+ *
+ * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 was introduced in GCC 4.3 and Clang 3.3,
+ * building with older compilers will result in the compat layer always being
+ * used on x86-32.
+ */
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
+#define URCU_ARCH_X86_NO_CAS 1
+/* For backwards compat */
 #define URCU_ARCH_I386 1
+#endif
+
 #include <urcu/arch/x86.h>
 
 #elif (defined(__powerpc64__) || defined(__ppc64__))
index 29dd88f1f16b0ea320ffa82ef2ed0596c7aaba65..8586e1da371f86e2c19518f60a8cef69e6db691e 100644 (file)
@@ -109,6 +109,16 @@ void cds_lfht_node_init(struct cds_lfht_node *node __attribute__((unused)))
 {
 }
 
+/*
+ * cds_lfht_node_init_deleted - initialize a hash table node to "removed" state
+ * @node: the node to initialize.
+ *
+ * Initialize the node such that cds_lfht_is_node_deleted() can be used
+ * on the node before it is added to a hash table.
+ */
+extern
+void cds_lfht_node_init_deleted(struct cds_lfht_node *node);
+
 /*
  * Hash table creation flags.
  */
index a2c94ded9cd9833558bb25d19b9908c6f47a9007..431319d608518af222045f9467dfb8081dfaaa8c 100644 (file)
@@ -116,6 +116,7 @@ struct urcu_tls {
        type *__tls_access_ ## name(void)                       \
        {                                                       \
                static struct urcu_tls __tls_ ## name = {       \
+                       .key = 0,                               \
                        .init_mutex = PTHREAD_MUTEX_INITIALIZER,\
                        .init_done = 0,                         \
                };                                              \
@@ -132,9 +133,9 @@ struct urcu_tls {
                        pthread_mutex_unlock(&__tls_ ## name.init_mutex); \
                }                                               \
                cmm_smp_rmb();  /* read init_done before getting key */ \
-               __tls_p = pthread_getspecific(__tls_ ## name.key); \
+               __tls_p = (__typeof__(type) *) pthread_getspecific(__tls_ ## name.key); \
                if (caa_unlikely(__tls_p == NULL)) {            \
-                       __tls_p = calloc(1, sizeof(type));      \
+                       __tls_p = (__typeof__(type) *) calloc(1, sizeof(type)); \
                        do_init                                 \
                        (void) pthread_setspecific(__tls_ ## name.key,  \
                                __tls_p);                       \
index f4e1887477684f779edd2d865ad3e7edb86eee37..d416963c31aeca0cdd5003b67858c1209779627c 100644 (file)
@@ -529,7 +529,7 @@ void __uatomic_dec(void *addr, int len)
 
 #define _uatomic_dec(addr)     (__uatomic_dec((addr), sizeof(*(addr))))
 
-#if ((CAA_BITS_PER_LONG != 64) && defined(URCU_ARCH_I386))
+#ifdef URCU_ARCH_X86_NO_CAS
 
 /* For backwards compat */
 #define CONFIG_RCU_COMPAT_ARCH 1
index e1651d3db9a2110ae18702c85dc4b7f1cb574838..50bdffbe4935ad4d595b40f3a774ea1c087fc21d 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <urcu/arch.h>
 
-#if defined(URCU_ARCH_I386)
+#ifdef URCU_ARCH_X86_NO_CAS
 
 #include <stdio.h>
 #include <pthread.h>
index 04fd49946aa940184015a4921971feff5d3818e5..8046f3a63a280397be3986231f1db8921ea4bfdb 100644 (file)
@@ -851,6 +851,12 @@ int is_removal_owner(struct cds_lfht_node *node)
        return ((unsigned long) node) & REMOVAL_OWNER_FLAG;
 }
 
+static
+struct cds_lfht_node *flag_removed(struct cds_lfht_node *node)
+{
+       return (struct cds_lfht_node *) (((unsigned long) node) | REMOVED_FLAG);
+}
+
 static
 struct cds_lfht_node *flag_removal_owner(struct cds_lfht_node *node)
 {
@@ -1578,6 +1584,12 @@ const struct cds_lfht_mm_type *get_mm_type(
 }
 #endif
 
+void cds_lfht_node_init_deleted(struct cds_lfht_node *node)
+{
+       cds_lfht_node_init(node);
+       node->next = flag_removed(NULL);
+}
+
 struct cds_lfht *_cds_lfht_new(unsigned long init_size,
                        unsigned long min_nr_alloc_buckets,
                        unsigned long max_nr_buckets,
index b2786c55c00253d8d51ab6e1ae8ed90329755f85..7f062f19a236d85f99e1a3402dec9ad467b34582 100644 (file)
 
 #include "tap.h"
 
+struct my_tls_struct {
+       int int1;
+       char char1;
+       void *void1;
+};
+
+static DEFINE_URCU_TLS(int, my_tls_int);
+static DEFINE_URCU_TLS(struct my_tls_struct, my_tls_struct);
+
 static void test_lfstack(void)
 {
        struct cds_lfs_stack s;
@@ -97,6 +106,15 @@ void test_build_cds_list_head_init(void)
        };
 }
 
+static
+void test_urcu_tls(void)
+{
+       URCU_TLS(my_tls_int) = 1;
+       URCU_TLS(my_tls_struct).int1 = 1;
+       URCU_TLS(my_tls_struct).char1 = 'a';
+       URCU_TLS(my_tls_struct).void1 = NULL;
+}
+
 int main(void)
 {
        plan_tests(3);
@@ -105,6 +123,7 @@ int main(void)
        test_wfstack();
        test_wfcqueue();
        test_build_cds_list_head_init();
+       test_urcu_tls();
 
        return exit_status();
 }
This page took 0.041118 seconds and 4 git commands to generate.