userspace-rcu.git
11 months agoFix: allow clang to build liburcu on RISC-V
Mathieu Desnoyers [Mon, 18 Dec 2023 15:24:13 +0000 (10:24 -0500)] 
Fix: allow clang to build liburcu on RISC-V

Clang also defines __GNUC__, so use URCU_GCC_VERSION to detect if built
with gcc.

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

12 months agoFix -Walloc-size
Sam James [Sun, 5 Nov 2023 22:27:17 +0000 (22:27 +0000)] 
Fix -Walloc-size

GCC 14 introduces a new -Walloc-size included in -Wextra which gives:
```
urcu-call-rcu-impl.h:912:20: warning: allocation of insufficient size '1' for type 'struct call_rcu_completion' with size '16' [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
urcu-call-rcu-impl.h:927:22: warning: allocation of insufficient size '1' for type 'struct call_rcu_completion_work' with size '24' [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
urcu-call-rcu-impl.h:912:20: warning: allocation of insufficient size '1' for type 'struct call_rcu_completion' with size '16' [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
urcu-call-rcu-impl.h:927:22: warning: allocation of insufficient size '1' for type 'struct call_rcu_completion_work' with size '24' [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
urcu-call-rcu-impl.h:912:20: warning: allocation of insufficient size '1' for type 'struct call_rcu_completion' with size '16' [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
urcu-call-rcu-impl.h:927:22: warning: allocation of insufficient size '1' for type 'struct call_rcu_completion_work' with size '24' [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
urcu-call-rcu-impl.h:912:20: warning: allocation of insufficient size '1' for type 'struct call_rcu_completion' with size '16' [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
urcu-call-rcu-impl.h:927:22: warning: allocation of insufficient size '1' for type 'struct call_rcu_completion_work' with size '24' [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
urcu-call-rcu-impl.h:912:20: warning: allocation of insufficient size '1' for type 'struct call_rcu_completion' with size '16' [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
urcu-call-rcu-impl.h:927:22: warning: allocation of insufficient size '1' for type 'struct call_rcu_completion_work' with size '24' [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
workqueue.c:401:20: warning: allocation of insufficient size '1' for type 'struct urcu_workqueue_completion' with size '16' [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
workqueue.c:432:14: warning: allocation of insufficient size '1' for type 'struct urcu_workqueue_completion_work' with size '24' [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
urcu-call-rcu-impl.h:912:20: warning: allocation of insufficient size '1' for type 'struct call_rcu_completion' with size '16' [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
urcu-call-rcu-impl.h:927:22: warning: allocation of insufficient size '1' for type 'struct call_rcu_completion_work' with size '24' [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
qsbr.c:49:14: warning: allocation of insufficient size ‘1’ for type ‘struct mynode’ with size ‘40’ [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
mb.c:50:14: warning: allocation of insufficient size ‘1’ for type ‘struct mynode’ with size ‘40’ [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
membarrier.c:50:14: warning: allocation of insufficient size ‘1’ for type ‘struct mynode’ with size ‘40’ [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
signal.c:49:14: warning: allocation of insufficient size ‘1’ for type ‘struct mynode’ with size ‘40’ [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
bp.c:49:14: warning: allocation of insufficient size ‘1’ for type ‘struct mynode’ with size ‘40’ [-Walloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
```

The calloc prototype is:
```
void *calloc(size_t nmemb, size_t size);
```

So, just swap the number of members and size arguments to match the prototype, as
we're initialising 1 struct of size `sizeof(struct ...)`. GCC then sees we're not
doing anything wrong.

Signed-off-by: Sam James <sam@gentoo.org>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: Id84ce5cf9a1b97bfa942597aa188ef6e27e7c10d

13 months agourcu/uatomic/riscv: Mark RISC-V as broken
Olivier Dion [Thu, 28 Sep 2023 16:53:46 +0000 (12:53 -0400)] 
urcu/uatomic/riscv: Mark RISC-V as broken

Implementations of some atomic operations of GCC for RISC-V are
insufficient for sequential consistency. For this reason Userspace RCU
is currently marked as `broken' for RISC-V with GCC. However, it is
still possible to use other toolchains.

See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104831 for details.

For now, we mark every version of GCC as unsupported. Distribution
package maintainers will have to cherry-pick the relevant patches in GCC
then remove the #error in Userspace RCU if they want to support it.

As for us, we will incrementally add specific versions of GCC that have
fixed the issue whenever new stable releases are made from the GCC
project.

Change-Id: I2cd7c8f12068628b845a096e03f5f8100eacbe43
Signed-off-by: Olivier Dion <odion@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
13 months agoFix: urcu-bp: misaligned reader accesses
Jérémie Galarneau [Fri, 29 Sep 2023 19:16:48 +0000 (15:16 -0400)] 
Fix: urcu-bp: misaligned reader accesses

This is a port from a fix in LTTng-UST's embedded urcu (d1a0fad8). The
original message follows:

    Running the LTTng-tools tests (test_valid_filter, for example) under
    address sanitizer results in the following warning:

      /usr/include/lttng/urcu/static/urcu-ust.h:155:6: runtime error: member access within misaligned address 0x7fc45db3a020 for type 'struct lttng_ust_urcu_reader', which requires 128 byte alignment
      0x7fc45db3a020: note: pointer points here
       c4 7f 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00
                    ^

    While the node member of lttng_ust_urcu_reader has an "aligned"
    attribute of CAA_CACHE_LINE_SIZE, the compiler can't ensure the
    alignment of members for dynamically allocated instances.

    The `data` pointer is changed from char* to struct
    lttng_ust_urcu_reader*, allowing the compiler to enforce the expected
    alignment constraints.

    Since `data` was addressed in bytes, the code using this field is
    adapted to use element counts. As the chunks are only used to allocate
    reader instances (and not other types), it makes the code a bit easier
    to read.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I89ea1c32ca3c5c45621b562ab68f47a8428d3574

14 months agoLoongArch: Document that byte and short atomics are implemented with LL/SC
Mathieu Desnoyers [Wed, 6 Sep 2023 13:25:22 +0000 (09:25 -0400)] 
LoongArch: Document that byte and short atomics are implemented with LL/SC

Based on the LoongArch Reference Manual:

https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html

Section 2.2.7 "Atomic Memory Access Instructions" only lists atomic
operations for 32-bit and 64-bit integers. As detailed in Section
2.2.7.1, LL/SC instructions operating on 32-bit and 64-bit integers are
also available. Those are used by the compiler to support atomics on
byte and short types.

This means atomics on 32-bit and 64-bit types have stronger forward
progress guarantees than those operating on 8-bit and 16-bit types.

Link: https://github.com/urcu/userspace-rcu/pull/11#issuecomment-1706528796
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I01569b718f7300a46d984c34065c0bbfbd2f7cc6

14 months agoAdd LoongArch support
Wang Jing [Tue, 8 Jun 2021 11:44:49 +0000 (19:44 +0800)] 
Add LoongArch support

This commit completes LoongArch support.

LoongArch supports byte and short atomic operations,
and defines UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT.

Signed-off-by: Wang Jing <wangjing@loongson.cn>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I335e654939bfc90994275f2a4fad550c95f3eba4

16 months agotests/regression/rcutorture: Add wait state
Olivier Dion [Fri, 14 Jul 2023 16:59:23 +0000 (12:59 -0400)] 
tests/regression/rcutorture: Add wait state

pthread_cond_wait(3) can have spurious wakeups. Fix this by polling a
state associated with the the wait.

Change-Id: Iba034cba5f72ad88388d1b90a6093f4ae9f9beb9
Signed-off-by: Olivier Dion <odion@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
16 months agourcu-wait: Initialize node in URCU_WAIT_NODE_INIT
Olivier Dion [Fri, 14 Jul 2023 17:09:21 +0000 (13:09 -0400)] 
urcu-wait: Initialize node in URCU_WAIT_NODE_INIT

C++ emits warnings with the URCU_WAIT_NODE_INIT() macro because the
member node is not initialized.

Fix this by initializing the node to null.

Change-Id: I7ee3b35624ef61cab826e3668f111e2483ca3c05
Signed-off-by: Olivier Dion <odion@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
16 months agoFix: urcu-wait: add missing futex.h include
Mathieu Desnoyers [Wed, 5 Jul 2023 15:22:02 +0000 (11:22 -0400)] 
Fix: urcu-wait: add missing futex.h include

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

16 months agoAdjust shell scripts to allow Bash in other locations
Brad Smith [Sat, 25 Feb 2023 05:53:06 +0000 (00:53 -0500)] 
Adjust shell scripts to allow Bash in other locations

Linux-based OS for the most part provide Bash and being located in /bin,
but on other OS's the shell would be in another location. Utilize env(1)
and allow it to be located elsewhere.

Signed-off-by: Brad Smith <brad@comstyle.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I9d4d4a3feaf993754c64b740ea91e42b336ba2b4

16 months agoAdd support for OpenBSD
Brad Smith [Sat, 25 Feb 2023 02:17:16 +0000 (21:17 -0500)] 
Add support for OpenBSD

- Add OpenBSD to syscall compatibility header as appropriate.
- Add function for retrieving the thread id in urcu_get_thread_id().
- Rely on pthread cond variables for futex compatibility.

It builds on all of our archs and fully run time tested on amd64.

Signed-off-by: Brad Smith <brad@comstyle.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I5cca5962ba3dc3113c9bd12e544b6e6f77dfdb61

16 months agoRevert "compiler.h: Introduce caa_unqual_scalar_typeof"
Mathieu Desnoyers [Mon, 3 Jul 2023 15:21:08 +0000 (11:21 -0400)] 
Revert "compiler.h: Introduce caa_unqual_scalar_typeof"

This reverts commit 67988e204d2c471b24cae61f3f8fedb4f9375034.

_Generic requires C11, but liburcu supports C99.

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

16 months agorculfhash: Use caa_container_of_check_null in cds_lfht_entry
Mathieu Desnoyers [Mon, 3 Jul 2023 15:20:27 +0000 (11:20 -0400)] 
rculfhash: Use caa_container_of_check_null in cds_lfht_entry

Use caa_container_of_check_null in cds_lfht_entry to allow removing
caa_unqual_scalar_typeof, which requires C11.

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

16 months agocompiler.h: Introduce caa_container_of_check_null
Mathieu Desnoyers [Mon, 3 Jul 2023 15:17:04 +0000 (11:17 -0400)] 
compiler.h: Introduce caa_container_of_check_null

The approach taken by caa_unqual_scalar_typeof requires use of _Generic
which requires full C11 support. Currently liburcu supports C99.
Therefore, this approach is not appropriate for now.

Instead, introduce caa_container_of_check_null which returns NULL if the
ptr is NULL before offsetting by the member offset.

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

16 months agocompiler.h: Introduce caa_unqual_scalar_typeof
Mathieu Desnoyers [Thu, 22 Jun 2023 13:58:39 +0000 (09:58 -0400)] 
compiler.h: Introduce caa_unqual_scalar_typeof

Allow defining variables and cast with a typeof which removes the
volatile and const qualifiers.

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

16 months agoAvoid calling caa_container_of on NULL pointer in cds_lfht macros
Mathieu Desnoyers [Thu, 22 Jun 2023 13:59:53 +0000 (09:59 -0400)] 
Avoid calling caa_container_of on NULL pointer in cds_lfht macros

The cds_lfht_for_each_entry and cds_lfht_for_each_entry_duplicate macros
would call caa_container_of() macro on NULL pointer.  This is not a
problem under normal circumstances as the check in the for loop fails
and the loop-statement is not called with invalid (pos) value.

However AddressSanitizer doesn't like that and complains about this:

    runtime error: applying non-zero offset 18446744073709551056 to null pointer

Move the cds_lfht_iter_get_node(iter) != NULL from the cond-expression
of the for loop into both init-clause and iteration-expression as
conditional operator and check for (pos) value in the cond-expression
instead. Introduce the cds_lfht_entry() macro to eliminate code
duplication.

Reported-by: Ondřej Surý <ondrej@sury.org>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I9969c1e0bc0eefc8c90c0d8f17b2927f6a4feb2a

17 months agoFix: revise urcu_read_lock_update() comment
Li-Kuan Ou [Wed, 14 Jun 2023 01:51:48 +0000 (09:51 +0800)] 
Fix: revise urcu_read_lock_update() comment

Read-side critical section nesting is tracked in lower-order bits
and grace-period phase number use a single high-order bit.

Signed-off-by: Li-Kuan Ou <k777k777tw@gmail.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I4fc185aa12a367e997fa20bf37793cfb2023c96f

17 months agoFix: uatomic powerpc comment about lwsync
Mathieu Desnoyers [Fri, 9 Jun 2023 14:50:48 +0000 (10:50 -0400)] 
Fix: uatomic powerpc comment about lwsync

lwsync allows prior stores to be reordered against following loads.

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

17 months agofix: aarch64: allow RHEL7 gcc 4.8.5-11
Michael Jeanson [Mon, 5 Jun 2023 17:58:16 +0000 (13:58 -0400)] 
fix: aarch64: allow RHEL7 gcc 4.8.5-11

The patch for GCC upstream bug 63293[1] was backported in RHEL7 gcc
4.8.5-11 package, allow building with this version.

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63293

Change-Id: Ib5d8ef3c292a691167c5c4834c1e0bfdfe5b56b3
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
20 months agofix: warning 'noreturn' function does return on ppc
Michael Jeanson [Thu, 23 Mar 2023 18:23:55 +0000 (14:23 -0400)] 
fix: warning 'noreturn' function does return on ppc

On a ppc64 system with gcc 9.5.0 I get the following error when building
with -O0 :

/usr/include/urcu/uatomic/generic.h: In function 'void _uatomic_link_error()':
/usr/include/urcu/uatomic/generic.h:53:1: warning: 'noreturn' function does return
   53 | }
      | ^

Split the inline function in 2 variants and apply the noreturn attribute
only on the builtin_trap one.

Change-Id: I5ae8e764c4cc27af0463924a653b9eaa9f698c34
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
20 months agoFix: use __noreturn__ for C11-compatibility
Ondřej Surý [Fri, 17 Mar 2023 15:44:10 +0000 (16:44 +0100)] 
Fix: use __noreturn__ for C11-compatibility

The noreturn convenience macro provided by stdnoreturn.h might get
included before urcu headers, use __noreturn__ for better compatibility
with code using <stdnoreturn.h> header.

Signed-off-by: Ondřej Surý <ondrej@sury.org>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
21 months agoVersion 0.14.0 v0.14.0
Mathieu Desnoyers [Tue, 14 Feb 2023 15:25:27 +0000 (10:25 -0500)] 
Version 0.14.0

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

21 months agoFix: urcu-bp: only teardown call-rcu worker in destructor
Mathieu Desnoyers [Mon, 13 Feb 2023 17:24:09 +0000 (12:24 -0500)] 
Fix: urcu-bp: only teardown call-rcu worker in destructor

Do not invoke urcu_call_rcu_exit() every time a reader thread
unregisters from urcu-bp. This causes pthread join hangs observed on
Cygwin.

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

21 months agoFix: rculfhash: urcu_die() takes positive error value
Mathieu Desnoyers [Sat, 11 Feb 2023 01:29:39 +0000 (20:29 -0500)] 
Fix: rculfhash: urcu_die() takes positive error value

Found by Coverity:

** CID 1504537:  Error handling issues  (NEGATIVE_RETURNS)
/src/rculfhash.c: 1934 in do_auto_resize_destroy_cb()

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

21 months agoFix: call_rcu: teardown default call_rcu worker on application exit
Mathieu Desnoyers [Fri, 10 Feb 2023 19:55:24 +0000 (14:55 -0500)] 
Fix: call_rcu: teardown default call_rcu worker on application exit

Teardown the default call_rcu worker thread if there are no queued
callbacks on process exit. This prevents leaking memory.

Here is how an application can ensure graceful teardown of this
worker thread:

- An application queuing call_rcu callbacks should invoke
  rcu_barrier() before it exits.
- When chaining call_rcu callbacks, the number of calls to
  rcu_barrier() on application exit must match at least the maximum
  number of chained callbacks.
- If an application chains callbacks endlessly, it would have to be
  modified to stop chaining callbacks when it detects an application
  exit (e.g. with a flag), and wait for quiescence with rcu_barrier()
  after setting that flag.
- The statements above apply to a library which queues call_rcu
  callbacks, only it needs to invoke rcu_barrier in its library
  destructor.

Fixes: #1317
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I40556bc872d3df58a22fb88a0dbb528ce5c9b4af

21 months agoFix: join worker thread in call_rcu_data_free
Mathieu Desnoyers [Fri, 10 Feb 2023 20:46:04 +0000 (15:46 -0500)] 
Fix: join worker thread in call_rcu_data_free

When freeing the call rcu descriptor, join its associated thread as well
to ensure complete teardown.

Fixes: #1317
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: Ic522e0466f56deca8bde519e082f3d7f99ec2e7f

21 months agoDocs: clarify grace period polling API
Jérémie Galarneau [Fri, 10 Feb 2023 19:45:39 +0000 (14:45 -0500)] 
Docs: clarify grace period polling API

Reword the existing grace period polling API documentation. The
changes are:

  - Replace "should" by "must" to express obligations,
  - Attempt to clarify "which" grace period the API allows checking for.

Change-Id: Ib3a93faeef7bcdb94ebae2d294d45925e12873a4
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
21 months agoDocument grace period polling in rcu-api.md
Mathieu Desnoyers [Fri, 10 Feb 2023 17:24:44 +0000 (12:24 -0500)] 
Document grace period polling in rcu-api.md

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

21 months agoImplement poll rcu stress test in rcutorture
Mathieu Desnoyers [Fri, 10 Feb 2023 14:08:04 +0000 (09:08 -0500)] 
Implement poll rcu stress test in rcutorture

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

21 months agourcu-memb,mb,signal: Implement grace period polling
Mathieu Desnoyers [Thu, 2 Feb 2023 19:32:15 +0000 (14:32 -0500)] 
urcu-memb,mb,signal: Implement grace period polling

Implement a grace period polling mechanism for each urcu flavor. Its use
is documented in README.md.

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

21 months agoFix: auto-resize hash table destroy deadlock
Mathieu Desnoyers [Fri, 3 Feb 2023 19:11:50 +0000 (14:11 -0500)] 
Fix: auto-resize hash table destroy deadlock

Fix a deadlock for auto-resize hash tables when cds_lfht_destroy
is called with RCU read-side lock held.

Example stack track of a hang:

  Thread 2 (Thread 0x7f21ba876700 (LWP 26114)):
  #0  syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
  #1  0x00007f21beba7aa0 in futex (val3=0, uaddr2=0x0, timeout=0x0, val=-1, op=0, uaddr=0x7f21bedac308 <urcu_memb_gp+8>) at ../include/urcu/futex.h:81
  #2  futex_noasync (timeout=0x0, uaddr2=0x0, val3=0, val=-1, op=0, uaddr=0x7f21bedac308 <urcu_memb_gp+8>) at ../include/urcu/futex.h:90
  #3  wait_gp () at urcu.c:265
  #4  wait_for_readers (input_readers=input_readers@entry=0x7f21ba8751b0, cur_snap_readers=cur_snap_readers@entry=0x0,
      qsreaders=qsreaders@entry=0x7f21ba8751c0) at urcu.c:357
  #5  0x00007f21beba8339 in urcu_memb_synchronize_rcu () at urcu.c:498
  #6  0x00007f21be99f93f in fini_table (last_order=<optimized out>, first_order=13, ht=0x5651cec75400) at rculfhash.c:1489
  #7  _do_cds_lfht_shrink (new_size=<optimized out>, old_size=<optimized out>, ht=0x5651cec75400) at rculfhash.c:2001
  #8  _do_cds_lfht_resize (ht=ht@entry=0x5651cec75400) at rculfhash.c:2023
  #9  0x00007f21be99fa26 in do_resize_cb (work=0x5651e20621a0) at rculfhash.c:2063
  #10 0x00007f21be99dbfd in workqueue_thread (arg=0x5651cec74a00) at workqueue.c:234
  #11 0x00007f21bd7c06db in start_thread (arg=0x7f21ba876700) at pthread_create.c:463
  #12 0x00007f21bd4e961f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

  Thread 1 (Thread 0x7f21bf285300 (LWP 26098)):
  #0  syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
  #1  0x00007f21be99d8b7 in futex (val3=0, uaddr2=0x0, timeout=0x0, val=-1, op=0, uaddr=0x5651d8b38584) at ../include/urcu/futex.h:81
  #2  futex_async (timeout=0x0, uaddr2=0x0, val3=0, val=-1, op=0, uaddr=0x5651d8b38584) at ../include/urcu/futex.h:113
  #3  futex_wait (futex=futex@entry=0x5651d8b38584) at workqueue.c:135
  #4  0x00007f21be99e2c8 in urcu_workqueue_wait_completion (completion=completion@entry=0x5651d8b38580) at workqueue.c:423
  #5  0x00007f21be99e3f9 in urcu_workqueue_flush_queued_work (workqueue=0x5651cec74a00) at workqueue.c:452
  #6  0x00007f21be9a0c83 in cds_lfht_destroy (ht=0x5651d8b2fcf0, attr=attr@entry=0x0) at rculfhash.c:1906

This deadlock is easy to reproduce when rapidly adding a large number of
entries in the cds_lfht, removing them, and calling cds_lfht_destroy().

The deadlock will occur if the call to cds_lfht_destroy() takes place
while a resize of the hash table is ongoing.

Fix this by moving the teardown of the lfht worker thread to libcds
library destructor, so it does not have to wait on synchronize_rcu from
a resize callback from within a read-side critical section. As a
consequence, the atfork callbacks are left registered within each urcu
flavor for which a resizeable hash table is created until the end of the
executable lifetime.

The other part of the fix is to move the hash table destruction to the
worker thread for auto-resize hash tables. This prevents having to wait
for resize callbacks from RCU read-side critical section. This is
guaranteed by the fact that the worker thread serializes previously
queued resize callbacks before the destroy callback.

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

21 months agoFix building on MSYS2
Christopher Ng [Fri, 3 Feb 2023 12:16:06 +0000 (12:16 +0000)] 
Fix building on MSYS2

Update cygwin libtool config in `configure.ac` to match MSYS2 build
environments as well. MSYS2 is also a Windows build environment that
produces DLLs.

Signed-off-by: Christopher Ng <facboy@gmail.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I48ca648123fd40b8003c72c0447c70a8b4bde6d6

23 months agorculfhash: Include rculfhash-internal.h from local directory
Gavin Ray [Mon, 5 Dec 2022 02:07:17 +0000 (02:07 +0000)] 
rculfhash: Include rculfhash-internal.h from local directory

Use double quotes rather than angle brackets to include this local
header file. This fixes build scenarios where the liburcu build is used
from cmake.

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

2 years agoRemove "Darwin" from "should also work on list"
Mathieu Desnoyers [Thu, 10 Nov 2022 15:26:39 +0000 (10:26 -0500)] 
Remove "Darwin" from "should also work on list"

MacOS is already covered in the "tested on" list, and standalone Darwin
is relatively niche (http://www.puredarwin.org/).

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

2 years agoMerge branch 'adah1972-improve-md'
Mathieu Desnoyers [Tue, 1 Nov 2022 14:58:15 +0000 (10:58 -0400)] 
Merge branch 'adah1972-improve-md'

Change-Id: I7904f3cee368428a21fdd84d07c395e232f5cfdb

2 years agoAdd semicolons at the end of function prototypes
Wu Yongwei [Tue, 1 Nov 2022 14:19:02 +0000 (22:19 +0800)] 
Add semicolons at the end of function prototypes

This pleases the syntax highlighter for multi-line code. Also, other
files already have semicolons.

Signed-off-by: Wu Yongwei <wuyongwei@gmail.com>
2 years agoWrap a file name in backticks
Wu Yongwei [Tue, 1 Nov 2022 14:17:32 +0000 (22:17 +0800)] 
Wrap a file name in backticks

For consistency.

Signed-off-by: Wu Yongwei <wuyongwei@gmail.com>
2 years agoWrap command-line options in backticks
Wu Yongwei [Tue, 1 Nov 2022 14:11:02 +0000 (22:11 +0800)] 
Wrap command-line options in backticks

For consistency and visual clarity.

Signed-off-by: Wu Yongwei <wuyongwei@gmail.com>
2 years agoFix a wrong format
Wu Yongwei [Tue, 1 Nov 2022 14:06:17 +0000 (22:06 +0800)] 
Fix a wrong format

TAB should not be used, and a blank line is necessary.

Signed-off-by: Wu Yongwei <wuyongwei@gmail.com>
2 years agoWrap URLs in angle brackets
Wu Yongwei [Tue, 1 Nov 2022 13:58:38 +0000 (21:58 +0800)] 
Wrap URLs in angle brackets

Otherwise special symbols (like underscores) may again cause issues in
some Markdown editors.

Signed-off-by: Wu Yongwei <wuyongwei@gmail.com>
2 years agoFix Markdown issues
Wu Yongwei [Tue, 1 Nov 2022 13:48:24 +0000 (21:48 +0800)] 
Fix Markdown issues

`_`, `<`, and `>` are special characters in Markdown, and need to be
escaped except in code blocks.  So backticks or backslahes are used to
fix the apparent issues, which caused wrong rendering.

Signed-off-by: Wu Yongwei <wuyongwei@gmail.com>
2 years agoFix: Always check pthread_create for failures
Eric Wong [Sun, 2 Oct 2022 16:13:43 +0000 (12:13 -0400)] 
Fix: Always check pthread_create for failures

pthread_create may fail with EAGAIN (which is no fault of the
programmer), so don't allow the check to be compiled out.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: Ia2695ea6953b589ac8ab8b444fb668daee06a614

2 years agoDisable signals in URCU background threads
Mathieu Desnoyers [Fri, 23 Sep 2022 17:55:03 +0000 (13:55 -0400)] 
Disable signals in URCU background threads

Applications using signalfd depend on signals being blocked in all
threads of the process, otherwise threads with unblocked signals
can receive them and starve the signalfd.

While some threads in URCU do block signals (e.g. workqueue
worker for rculfhash), the call_rcu, defer_rcu, and rculfhash
partition_resize_helper threads do not.

Always block all signals before creating threads, and only unblock
SIGRCU when registering a urcu-signal thread. Restore the SIGRCU
signal to its pre-registration blocked state on unregistration.

For rculfhash, cds_lfht_worker_init can be removed, because its only
effect is to block all signals except SIGRCU. Blocking all signals is
already done by the workqueue code, and unbloking SIGRCU is now done by
the urcu signal flavor thread regisration.

Co-developed-by: Eric Wong <normalperson@yhbt.net>
Signed-off-by: Eric Wong <normalperson@yhbt.net>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: If78346b15bdc287417b992a8963098c6ea0dc7d2

2 years agoFix: futex.h: include headers outside extern C
Mathieu Desnoyers [Wed, 17 Aug 2022 20:41:47 +0000 (16:41 -0400)] 
Fix: futex.h: include headers outside extern C

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

2 years agoFix: add missing unused attribute to _rcu_dereference
Mathieu Desnoyers [Wed, 17 Aug 2022 19:32:38 +0000 (15:32 -0400)] 
Fix: add missing unused attribute to _rcu_dereference

Reproduced with gcc-8, gcc-10, gcc-11 in O2:

14:39:19 In file included from ../../include/urcu/pointer.h:39,
14:39:19                  from ../../include/urcu-pointer.h:1,
14:39:19                  from ../../include/urcu/rcuhlist.h:30,
14:39:19                  from ../../include/urcu/cds.h:28,
14:39:19                  from test_build.c:30:
14:39:19 test_build.c: In function ‘test_build_rcu_dereference’:
14:39:19 ../../include/urcu/static/pointer.h:102:55: warning: variable ‘_________p0’ set but not used [-Wunused-but-set-variable]
14:39:19   102 |                                         __typeof__(p) _________p0 = { 0 };              \
14:39:19       |                                                       ^~~~~~~~~~~
14:39:19 ../../include/urcu/pointer.h:47:33: note: in expansion of macro ‘_rcu_dereference’
14:39:19    47 | #define rcu_dereference         _rcu_dereference
14:39:19       |                                 ^~~~~~~~~~~~~~~~
14:39:19 test_build.c:133:9: note: in expansion of macro ‘rcu_dereference’
14:39:19   133 |         rcu_dereference(opaque_const);
14:39:19       |         ^~~~~~~~~~~~~~~
14:39:19 mv -f .deps/test_urcu_multiflavor_single_unit_dynlink_cxx-test_urcu_multiflavor_single_unit_cxx.Tpo .deps/test_urcu_multiflavor_single_unit_dynlink_cxx-test_urcu_multiflavor_single_unit_cxx.Po
14:39:19 ../../include/urcu/static/pointer.h:102:55: warning: variable ‘_________p0’ set but not used [-Wunused-but-set-variable]
14:39:19   102 |                                         __typeof__(p) _________p0 = { 0 };              \
14:39:19       |                                                       ^~~~~~~~~~~
14:39:19 ../../include/urcu/pointer.h:47:33: note: in expansion of macro ‘_rcu_dereference’
14:39:19    47 | #define rcu_dereference         _rcu_dereference
14:39:19       |                                 ^~~~~~~~~~~~~~~~
14:39:19 test_build.c:135:9: note: in expansion of macro ‘rcu_dereference’
14:39:19   135 |         rcu_dereference(clear_const);
14:39:19       |         ^~~~~~~~~~~~~~~

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

2 years agoFix: change method used by _rcu_dereference to strip type constness
Simon Marchi [Wed, 17 Aug 2022 15:24:25 +0000 (11:24 -0400)] 
Fix: change method used by _rcu_dereference to strip type constness

Commit 1e41ec3b07e4 ("Make temporary variable in _rcu_dereference
non-const") used the trick to add 0 to the pointer passed as a parameter
to the macro to get rid of its constness, should it be const (with the
end goal of avoiding compiler warnings).  This is problematic (as shown
in [1]) if it is a pointer to an opaque type though, as the compiler
cannot perform pointer arithmetic on such a pointer (even though it
wouldn't really need to here, as we add 0).

Change it to use another trick to strip away the constness, that
shouldn't hit this problem.  It was found in the same stackoverflow post
as the original trick [2].  It consists of using a statement expression
like so:

    __typeof__(({ const int foo; foo; }))

The statement expression yields a value of type `int`.  Statement
expressions are extensions to the C language, but we already use them
here.

The test_build* binaries now need to be linked against the urcu library,
otherwise they would be missing the rcu_dereference_sym symbol.

[1] https://lists.lttng.org/pipermail/lttng-dev/2022-August/030247.html
[2] https://stackoverflow.com/a/54016713

Change-Id: Ic73590ef4beaa1832161aa05a6df37e467f85116
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2 years agoFix: remove type constness in URCU_FORCE_CAST's C++ version
Simon Marchi [Wed, 17 Aug 2022 17:11:21 +0000 (13:11 -0400)] 
Fix: remove type constness in URCU_FORCE_CAST's C++ version

The test added by the following patch wouldn't compile, when built
without _LGPL_SOURCE:

      CXX      test_build_dynlink_cxx-test_build_cxx.o
    In file included from ../../include/urcu/arch.h:25,
                     from /home/simark/src/urcu/tests/unit/test_build.c:28,
                     from /home/simark/src/urcu/tests/unit/test_build_cxx.cpp:3:
    /home/simark/src/urcu/tests/unit/test_build.c: In function ‘void test_build_rcu_dereference()’:
    /home/simark/src/urcu/include/urcu/compiler.h:85:42: error: type qualifiers ignored on cast result type [-Werror=ignored-qualifiers]
       85 | #define URCU_FORCE_CAST(type, arg)      (reinterpret_cast<type>(arg))
          |                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~
    /home/simark/src/urcu/include/urcu/pointer.h:71:49: note: in expansion of macro ‘URCU_FORCE_CAST’
       71 |                 __typeof__(p) _________p1 =     URCU_FORCE_CAST(__typeof__(p), \
          |                                                 ^~~~~~~~~~~~~~~
    /home/simark/src/urcu/tests/unit/test_build.c:133:9: note: in expansion of macro ‘rcu_dereference’
      133 |         rcu_dereference(opaque_const);
          |         ^~~~~~~~~~~~~~~

The compiler complains that we do a cast to a const type, equivalent to:

  reinterpret_cast<const int>(arg)

... and that the const is meaningless in this context.

Use std::remove_cv to strip away any const or volatile qualifiers from
the type (using a volatile type would result in the same warning).

Change-Id: I94e79fcccfc2108021752f65977e1548084c646a
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2 years agoMove extern "C" down in include/urcu/urcu-bp.h
Simon Marchi [Wed, 17 Aug 2022 16:49:50 +0000 (12:49 -0400)] 
Move extern "C" down in include/urcu/urcu-bp.h

A following patch adds a <type_traits> include in
urcu/compiler.h.  However, compiler.h gets included by urcu/pointer.h,
which gets included by urcu/urcu-bp.h inside an extern "C" scope.
Including the C++ header file <type_traits> inside an extern "C" scope
doesn't work:

    In file included from /home/simark/src/urcu/include/urcu/compiler.h:25,
                     from /home/simark/src/urcu/include/urcu/pointer.h:29,
                     from /home/simark/src/urcu/include/urcu/urcu-bp.h:58,
                     from /home/simark/src/urcu/include/urcu-bp.h:2,
                     from /home/simark/src/urcu/tests/unit/test_urcu_multiflavor-bp.c:28,
                     from /home/simark/src/urcu/tests/unit/test_urcu_multiflavor-bp_cxx.cpp:3:
    /usr/include/c++/12.1.1/type_traits:44:3: error: template with C linkage
       44 |   template<typename _Tp>
          |   ^~~~~~~~
    /home/simark/src/urcu/include/urcu/urcu-bp.h:41:1: note: ‘extern "C"’ linkage started here
       41 | extern "C" {
          | ^~~~~~~~~~

Move the extern "C" in urcu-bp.h down, so that the includes are not
inside it.  Each header file is responsible to use extern "C" where
relevant, and we should avoid including files inside such a scope.

Change-Id: I42bdfa6ab445e8c40f5bcac1c1ae0786d443626c
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2 years agofix: ifdef linux specific cpu count compat
Michael Jeanson [Mon, 15 Aug 2022 15:11:54 +0000 (11:11 -0400)] 
fix: ifdef linux specific cpu count compat

Expand the '#ifdef __linux__' block in src/compat-cpu.h to all static
inline functions related to sysfs since they are only useful on Linux
and fail to build on some non-Linux platforms. This issue was reported
on QNX.

The corresponding unit tests have to be skipped on non-Linux platforms.

Thanks to Elad Lahav <e2lahav@gmail.com> for reporting this issue.

Change-Id: I17c88a9a2fb5b9be6cf5325234a18ff40788cd09
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2 years agoAdd unit tests for possible_cpus_array_len
Michael Jeanson [Mon, 1 Aug 2022 15:51:03 +0000 (11:51 -0400)] 
Add unit tests for possible_cpus_array_len

Change-Id: Ida3affbc7021c96bbc8941a96455ef93030c5c96
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2 years agofix: sysconf(_SC_NPROCESSORS_CONF) can be less than max cpu id
Michael Jeanson [Wed, 27 Jul 2022 14:44:00 +0000 (10:44 -0400)] 
fix: sysconf(_SC_NPROCESSORS_CONF) can be less than max cpu id

We rely on sysconf(_SC_NPROCESSORS_CONF) to get the maximum possible
number of CPUs that can be attached to the system for the lifetime of an
application.

As such we expect that the highest possible CPU id would be one less
than the number returned by sysconf(_SC_NPROCESSORS_CONF) which is
unfortunatly not always the case and can vary across libc
implementations and versions.

Glibc up to 2.35 will count the number of "cpuX" directories in
"/sys/devices/system/cpu" which doesn't include CPUS that were
hot-unplugged.

This information is however provided by the Linux kernel in
"/sys/devices/system/cpu/possible" in the form of a mask listing all the
CPUs that could possibly be hot-plugged in the system.

This patch replaces sysconf(_SC_NPROCESSORS_CONF) with an internal
function that first tries parsing the possible CPU mask to extract the
highest possible value and if this fails fallback to the previous
behavior.

Change-Id: I68dfed42ebbab02728a02eeefd4a395a22bb1bea
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2 years agoFix: revise obsolete command in README.md
Shao-Tse Hung [Tue, 2 Aug 2022 17:44:00 +0000 (01:44 +0800)] 
Fix: revise obsolete command in README.md

The obsolete command `make bench` was replaced by `make short_bench` and
`make long_bench` in 2015.  However, this command wasn't revised in
README, so I follow the previous commit and rewrite it.

Signed-off-by: Shao-Tse Hung <ccs100203@gmail.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I92fa6cc3937b0a65b0a005ce6bb1fe3d2b3250ab

2 years agoFix: workqueue: remove unused variable "ret"
Mathieu Desnoyers [Mon, 27 Jun 2022 15:22:08 +0000 (11:22 -0400)] 
Fix: workqueue: remove unused variable "ret"

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

2 years agoFix: urcu-qsbr: futex wait: handle spurious futex wakeups
Mathieu Desnoyers [Wed, 22 Jun 2022 20:49:11 +0000 (16:49 -0400)] 
Fix: urcu-qsbr: futex wait: handle spurious futex wakeups

Observed issue
==============

The urcu-qsbr wait_gp() implements a futex wait/wakeup scheme identical to
the workqueue code, which has an issue with spurious wakeups.

A spurious wakeup on wait_gp can cause wait_gp to return with a
urcu_qsbr_gp.futex state of -1, which is unexpected. It would cause the
following loops in wait_for_readers() to decrement the
urcu_qsbr_gp.futex to values below -1, thus actively using CPU as values
will be decremented to very low negative values until it reaches 0
through underflow, or until the input_readers list is found to be empty.
The state is restored to 0 when the input_readers list is found to be
empty, which restores the futex state to a correct state for the
following calls to wait_for_readers().

This issue will cause spurious unexpected high CPU use, but will not
lead to data corruption.

Cause
=====

From futex(5):

       FUTEX_WAIT
              Returns 0 if the caller was woken up.  Note that a  wake-up  can
              also  be caused by common futex usage patterns in unrelated code
              that happened to have previously used the  futex  word's  memory
              location  (e.g., typical futex-based implementations of Pthreads
              mutexes can cause this under some conditions).  Therefore, call‐
              ers should always conservatively assume that a return value of 0
              can mean a spurious wake-up, and  use  the  futex  word's  value
              (i.e.,  the user-space synchronization scheme) to decide whether
              to continue to block or not.

Solution
========

We therefore need to validate whether the value differs from -1 in
user-space after the call to FUTEX_WAIT returns 0.

Known drawbacks
===============

None.

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

2 years agoFix: urcu: futex wait: handle spurious futex wakeups
Mathieu Desnoyers [Wed, 22 Jun 2022 20:34:02 +0000 (16:34 -0400)] 
Fix: urcu: futex wait: handle spurious futex wakeups

Observed issue
==============

The urcu wait_gp() implements a futex wait/wakeup scheme identical to
the workqueue code, which has an issue with spurious wakeups.

A spurious wakeup on wait_gp can cause wait_gp to return with a
rcu_gp.futex state of -1, which is unexpected. It would cause the
following loops in wait_for_readers() to decrement the
rcu_gp.futex to values below -1, thus actively using CPU as values
will be decremented to very low negative values until it reaches 0
through underflow, or until the input_readers list is found to be empty.
The state is restored to 0 when the input_readers list is found to be
empty, which restores the futex state to a correct state for the
following calls to wait_for_readers().

This issue will cause spurious unexpected high CPU use, but will not
lead to data corruption.

Cause
=====

From futex(5):

       FUTEX_WAIT
              Returns 0 if the caller was woken up.  Note that a  wake-up  can
              also  be caused by common futex usage patterns in unrelated code
              that happened to have previously used the  futex  word's  memory
              location  (e.g., typical futex-based implementations of Pthreads
              mutexes can cause this under some conditions).  Therefore, call‐
              ers should always conservatively assume that a return value of 0
              can mean a spurious wake-up, and  use  the  futex  word's  value
              (i.e.,  the user-space synchronization scheme) to decide whether
              to continue to block or not.

Solution
========

We therefore need to validate whether the value differs from -1 in
user-space after the call to FUTEX_WAIT returns 0.

Known drawbacks
===============

None.

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

2 years agoFix: urcu-wait: futex wait: handle spurious futex wakeups
Mathieu Desnoyers [Wed, 22 Jun 2022 20:44:12 +0000 (16:44 -0400)] 
Fix: urcu-wait: futex wait: handle spurious futex wakeups

Observed issue
==============

The urcu-wait urcu_adaptative_busy_wait() implements a futex wait/wakeup
scheme similar to the workqueue code, which has an issue with spurious
wakeups.

A spurious wakeup on urcu_adaptative_busy_wait can cause
urcu_adaptative_busy_wait to reach label skip_futex_wait with a
wait->state state of URCU_WAIT_WAITING, which is unexpected. It would
cause busy-waiting on URCU_WAIT_TEARDOWN state to start early. The
wait-teardown stage is done with URCU_WAIT_ATTEMPTS active attempts,
following by attempts spaced by 10ms sleeps. I do not expect that these
spurious wakeups will cause user-observable effects other than being
slightly less efficient that it should be.

urcu-wait is used by all urcu flavor's synchronize_rcu() to implement
the grace period batching scheme.

This issue will cause spurious unexpected high CPU use, but will not
lead to data corruption.

Cause
=====

From futex(5):

       FUTEX_WAIT
              Returns 0 if the caller was woken up.  Note that a  wake-up  can
              also  be caused by common futex usage patterns in unrelated code
              that happened to have previously used the  futex  word's  memory
              location  (e.g., typical futex-based implementations of Pthreads
              mutexes can cause this under some conditions).  Therefore, call‐
              ers should always conservatively assume that a return value of 0
              can mean a spurious wake-up, and  use  the  futex  word's  value
              (i.e.,  the user-space synchronization scheme) to decide whether
              to continue to block or not.

Solution
========

We therefore need to validate whether the value differs from
URCU_WAIT_WAITING in user-space after the call to FUTEX_WAIT returns 0.

Known drawbacks
===============

None.

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

2 years agoFix: defer_rcu: futex wait: handle spurious futex wakeups
Mathieu Desnoyers [Wed, 22 Jun 2022 20:46:50 +0000 (16:46 -0400)] 
Fix: defer_rcu: futex wait: handle spurious futex wakeups

Observed issue
==============

The urcu-defer wait_defer() implements a futex wait/wakeup scheme identical to
the workqueue code, which has an issue with spurious wakeups.

A spurious wakeup on wait_defer can cause wait_defer to return with a
defer_thread_futex state of -1, which is unexpected. It would cause the
following loops in thr_defer() to decrement the defer_thread_futex to
values below -1, thus actively using CPU as values will be decremented
to very low negative values until it reaches 0 through underflow, or
until callbacks are eventually queued. The state is restored to 0 when
callbacks are found, which restores the futex state to a correct state
for the following calls to wait_defer().

This issue will cause spurious unexpected high CPU use, but will not
lead to data corruption.

Cause
=====

From futex(5):

       FUTEX_WAIT
              Returns 0 if the caller was woken up.  Note that a  wake-up  can
              also  be caused by common futex usage patterns in unrelated code
              that happened to have previously used the  futex  word's  memory
              location  (e.g., typical futex-based implementations of Pthreads
              mutexes can cause this under some conditions).  Therefore, call‐
              ers should always conservatively assume that a return value of 0
              can mean a spurious wake-up, and  use  the  futex  word's  value
              (i.e.,  the user-space synchronization scheme) to decide whether
              to continue to block or not.

Solution
========

We therefore need to validate whether the value differs from -1 in
user-space after the call to FUTEX_WAIT returns 0.

Known drawbacks
===============

None.

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

2 years agoFix: call_rcu: futex wait: handle spurious futex wakeups
Mathieu Desnoyers [Wed, 22 Jun 2022 20:38:06 +0000 (16:38 -0400)] 
Fix: call_rcu: futex wait: handle spurious futex wakeups

Observed issue
==============

The urcu call_rcu() and rcu_barrier() each implement a futex wait/wakeup
scheme identical to the workqueue code, which has an issue with spurious
wakeups.

* call_rcu

A spurious wakeup on call_rcu_wait can cause call_rcu_wait to return
with a crdp->futex state of -1, which is unexpected. It would cause the
following loops in call_rcu_thread() to decrement the crdp->futex to
values below -1, thus actively using CPU time as values will be
decremented to very low negative values until the futex value underflows
back to 0. The state is *not* restored to 0 when the callback list is
found to be non-empty, so this unexpected state will persist until the
crdp->futex state underflows back to 0, or until the call_rcu_thread is
stopped. What prevents this from having too much user-observable effects
is that the call rcu thread has a 10ms sleep between loops, to favor
batching of callbacks. Therefore, rather than being a purely 100% active
busy-wait, this scenario leads to a busy-wait which is paced by 10ms
sleeps.

Therefore the observed issue will be that the call_rcu_thread will
unexpectedly wake up the CPU each 10ms after this spurious wakeup
happens.

* rcu_barrier

A spurious wakeup on call_rcu_completion_wait can cause
call_rcu_completion_wait to return with a completion->futex state of -1,
which is unexpected. It would cause the following loops in rcu_barrier()
to decrement the completion->futex to values below -1, thus actively
using CPU time as values will be decremented to very low negative values
until either the barrier count reaches 0 or until the futex value
underflows to 0.

Therefore the observed issue will be that rcu_barrier() will
unexpectedly use a lot of CPU time when this spurious wakeup happens.

These issues will cause spurious unexpected high CPU use, but will not
lead to data corruption.

Cause
=====

From futex(5):

       FUTEX_WAIT
              Returns 0 if the caller was woken up.  Note that a  wake-up  can
              also  be caused by common futex usage patterns in unrelated code
              that happened to have previously used the  futex  word's  memory
              location  (e.g., typical futex-based implementations of Pthreads
              mutexes can cause this under some conditions).  Therefore, call‐
              ers should always conservatively assume that a return value of 0
              can mean a spurious wake-up, and  use  the  futex  word's  value
              (i.e.,  the user-space synchronization scheme) to decide whether
              to continue to block or not.

Solution
========

We therefore need to validate whether the value differs from -1 in
user-space after the call to FUTEX_WAIT returns 0.

Known drawbacks
===============

None.

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

2 years agoFix: workqueue: futex wait: handle spurious futex wakeups
Mathieu Desnoyers [Wed, 22 Jun 2022 20:28:53 +0000 (16:28 -0400)] 
Fix: workqueue: futex wait: handle spurious futex wakeups

Observed issue
==============

The workqueue thread futex_wait() returns with a workqueue->futex state
of -1, which is unexpected. In this situation, the workqueue thread is
observed to use 99% of CPU as workqueue->futex values are decremented to
very low negative values while the workqueue is empty.

This issue will cause spurious unexpected high CPU use, but will not
lead to data corruption.

Cause
=====

From futex(5):

       FUTEX_WAIT
              Returns 0 if the caller was woken up.  Note that a  wake-up  can
              also  be caused by common futex usage patterns in unrelated code
              that happened to have previously used the  futex  word's  memory
              location  (e.g., typical futex-based implementations of Pthreads
              mutexes can cause this under some conditions).  Therefore, call‐
              ers should always conservatively assume that a return value of 0
              can mean a spurious wake-up, and  use  the  futex  word's  value
              (i.e.,  the user-space synchronization scheme) to decide whether
              to continue to block or not.

Solution
========

We therefore need to validate whether the value differs from -1 in
user-space after the call to FUTEX_WAIT returns 0.

Known drawbacks
===============

None.

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

2 years agoFix: Use %lu rather than %ld to print count
yaowenbin1 [Thu, 9 Jun 2022 03:08:25 +0000 (11:08 +0800)] 
Fix: Use %lu rather than %ld to print count

In ht_count_del function, the type of count variable is defined as unsigned long,
so use %lu rather than %ld to print it.

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

2 years agoUpdate ABI definition files
Michael Jeanson [Tue, 12 Apr 2022 20:32:18 +0000 (16:32 -0400)] 
Update ABI definition files

Update all ABI definition files with artefacts built on an Ubuntu 18.04
x86_64 to allow straightforward comparision with artefacts from our CI
system.

Change-Id: I916db6fb3e8a44e36047186ec4519e94acbb5939
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2 years agoBump version current and age
Mathieu Desnoyers [Fri, 22 Apr 2022 18:59:03 +0000 (14:59 -0400)] 
Bump version current and age

The symbol cds_lfht_node_init_deleted was added, so increment both
current and age.

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

2 years agoalpha: allocate membarrier system call number
Michael Jeanson [Tue, 1 Mar 2022 20:41:53 +0000 (15:41 -0500)] 
alpha: allocate membarrier system call number

The membarrier syscall has been allocated in Linux 4.13, allocate its
number in our architecture header if the system headers don't allocate
it.

Change-Id: Iebb77b94bf803a7a8b7ebd9f4124219f386334ae
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2 years agoBump version to 0.14.0-pre
Michael Jeanson [Tue, 12 Apr 2022 19:48:22 +0000 (15:48 -0400)] 
Bump version to 0.14.0-pre

Change-Id: I144d5a982867bf8d17144f679427e6636a0ed483
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2 years agoImproved test framework
Michael Jeanson [Mon, 13 Sep 2021 20:13:44 +0000 (16:13 -0400)] 
Improved test framework

This is based on the babeltrace / librseq test framework with the
objective of standardising across projects.

Regroup all the configure detected values relevant to the test suite in
a single generated file. This file will be automatically sourced by the
test suite in most scenarios but can also be sourced in the shell of a
user.

 * All user overridable variables start with 'URCU_TESTS_'.
 * The priority for variables is :
     Environment -> env.sh -> utils.sh (defaults).
 * A user can source 'env.sh', override some of the values and manually
   run test scripts.
 * The test suite can run without an 'env.sh' file present.

Change-Id: Id94f7085ed1ea0e30207856cf1594ca30585536c
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2 years agorculfhash: introduce cds_lfht_node_init_deleted
Mathieu Desnoyers [Mon, 10 Jan 2022 20:35:53 +0000 (15:35 -0500)] 
rculfhash: introduce cds_lfht_node_init_deleted

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

2 years agoFix: changelog: v0.13.0 was released in 2021
Mathieu Desnoyers [Wed, 5 Jan 2022 20:08:17 +0000 (15:08 -0500)] 
Fix: changelog: v0.13.0 was released in 2021

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

2 years agocleanup: i386 arch detection
Michael Jeanson [Tue, 7 Dec 2021 20:22:23 +0000 (15:22 -0500)] 
cleanup: i386 arch detection

On x86-32, '__i386__' or '__i386' is always defined regardless of the
march / mtune value, simplify the detection code.

Change-Id: Icadabc60554b58d5d2611ec58f3efff9aa067dac
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2 years agofix: properly detect 'cmpxchg' on x86-32
Michael Jeanson [Tue, 7 Dec 2021 19:42:26 +0000 (14:42 -0500)] 
fix: properly detect 'cmpxchg' on x86-32

We wrongly assumed that on x86-32 when '__i386__' is defined but none of
'__i486__', '__i586__' or '__i686__' that the target arch is a literal
i386 cpu without the cmpxchg instructions. However, when building with
'-march=core2' we get '__i386__' but none of the others even if the arch
is newer than an i686.

Change the compat code to use the '__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4'
builtin define to detect an x86-32 system without the cmpxchg
instructions.

Since this builtin define was introduced in GCC 4.3 and Clang 3.3,
building with older compilers on any x86-32 system will enable the
compat layer regardless of the availability of the instructions.

Change-Id: I8329431e55d778405b2ca7007d90c2c6e5cdd426
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 years agofix: use urcu-tls compat with c++ compiler
Michael Jeanson [Thu, 18 Nov 2021 20:08:53 +0000 (15:08 -0500)] 
fix: use urcu-tls compat with c++ compiler

  * Initialize all fields of 'struct urcu_tls' to avoid :

    sorry, unimplemented: non-trivial designated initializers not supported

  * Cast void* to proper type pointers to avoid :

    error: invalid conversion from ‘void*’ to ...

Change-Id: I654f924324cda2eaea723f4a0759d706b2a2bf40
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 years agoFix typo
Dimitris Apostolou [Sat, 13 Nov 2021 11:16:03 +0000 (13:16 +0200)] 
Fix typo

Signed-off-by: Dimitris Apostolou <dimitris.apostolou@icloud.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: Iaefe3b69b228773463fe93b2d9ddd3860caa83a8

3 years agofix: remove autoconf features default value in help message
Michael Jeanson [Fri, 12 Nov 2021 18:13:59 +0000 (13:13 -0500)] 
fix: remove autoconf features default value in help message

The default values of yes|no can be confusing combined with the
--enable / --disable switches of autoconf, remove them from the help
message.

Change-Id: Id9c4036b2fa50e1144a43f68f71a24f0c11434eb
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 years agofix: add missing pkgconfig file for memb flavour lib
Michael Jeanson [Wed, 22 Sep 2021 20:06:23 +0000 (16:06 -0400)] 
fix: add missing pkgconfig file for memb flavour lib

We ship a pkg-config file for each urcu flavour library except the
latest introduced 'memb'.

Change-Id: If222949941d968f63b07616776440931657aa6db
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 years agoCleanup: Tests: Remove useless pre-C99 compatibility code from tap.h
Mathieu Desnoyers [Tue, 14 Sep 2021 18:13:37 +0000 (14:13 -0400)] 
Cleanup: Tests: Remove useless pre-C99 compatibility code from tap.h

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

3 years agoDocument C99 and C++11 requirement in README.md
Mathieu Desnoyers [Tue, 14 Sep 2021 18:15:41 +0000 (14:15 -0400)] 
Document C99 and C++11 requirement in README.md

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

3 years agoAlways use '__thread' for Thread local storage except on MSVC
Michael Jeanson [Tue, 14 Sep 2021 14:41:08 +0000 (10:41 -0400)] 
Always use '__thread' for Thread local storage except on MSVC

Use the GCC extension '__thread' [1] for Thread local storage on all C
and C++ compilers except MSVC.

While C11 and C++11 respectively offer '_Thread_local' and
'thread_local' as potentialy faster implementations, they offer no
guarantees of compatibility when used in a library interface which might
be used by both C and C++ client code.

[1] https://gcc.gnu.org/onlinedocs/gcc/Thread-Local.html

Change-Id: If4fe8bcdbda24b21dedf382112bd5c5f836c00c8
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 years agoFix: powerpc32: transparent unions alter calling convention
Mathieu Desnoyers [Mon, 13 Sep 2021 20:57:02 +0000 (16:57 -0400)] 
Fix: powerpc32: transparent unions alter calling convention

On powerpc32, transparent unions have an impact on the calling
convention used for the argument, as they use the calling convention of
the first field of the union rather than the union itself. On powerpc32,
the calling convention for a union is that the register has a pointer to
the union, which differs from the calling convention of its first field
(which is a pointer in this case).

"[...] the argument is passed to the function using the calling
conventions of the first member of the transparent union, not the
calling conventions of the union itself. All members of the union must
have the same machine representation; this is necessary for this
argument passing to work properly." [1]

Therefore, use a transparent union for c++ so c++ compilers can emit
caller code with a compatible stack layout. The "ignored attribute"
warning emitted by clang appears to be only for architectures where the
calling convention is not affected by the presence of transparent union
attribute. Therefore, simply silence this warning.

Link: https://gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Type-Attributes.html
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I07182dd4ed37a3f61a226fb199bc98c95f83bd37

3 years agofix: don't use C++ thread_local on MacOs
Michael Jeanson [Thu, 9 Sep 2021 16:11:16 +0000 (12:11 -0400)] 
fix: don't use C++ thread_local on MacOs

Recent versions of Apple's clang++ do support 'thread_local' but the
implementation generates additional helper symbols. This is a problem
when accessing an extern TLS variable in a C++ compile unit that is
provided by a C library that doesn't have those extra symbols.

Fallback to using '__thread' on MacOs.

Change-Id: I87cb5b3c9293f7bf66f7115f453b546dd793a449
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 years agowfcqueue API: implement overloaded wrappers with templates
Mathieu Desnoyers [Wed, 8 Sep 2021 20:25:55 +0000 (16:25 -0400)] 
wfcqueue API: implement overloaded wrappers with templates

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

3 years agowfcqueue: combine C++ API cds_wfcq_head_cast with overloading
Mathieu Desnoyers [Wed, 8 Sep 2021 20:19:39 +0000 (16:19 -0400)] 
wfcqueue: combine C++ API cds_wfcq_head_cast with overloading

For the sake of wrapper API, implement a cds_wfcq_head_cast_cpp with
overloading, thus leaving in place the cds_wfcq_head_cast and
__cds_wfcq_head_cast C identifiers already exposed by the C++ API.

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

3 years agowfstack C++ API: implement overloaded wrappers with templates
Mathieu Desnoyers [Wed, 8 Sep 2021 20:11:46 +0000 (16:11 -0400)] 
wfstack C++ API: implement overloaded wrappers with templates

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

3 years agolfstack C++ API: implement overloaded wrappers with templates
Mathieu Desnoyers [Wed, 8 Sep 2021 20:07:35 +0000 (16:07 -0400)] 
lfstack C++ API: implement overloaded wrappers with templates

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

3 years agowfstack: combine C++ API cds_wfs_stack_cast with overloading
Mathieu Desnoyers [Wed, 8 Sep 2021 19:59:43 +0000 (15:59 -0400)] 
wfstack: combine C++ API cds_wfs_stack_cast with overloading

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

3 years agolfstack: combine C++ API cds_lfs_stack_cast with overloading
Mathieu Desnoyers [Wed, 8 Sep 2021 19:57:49 +0000 (15:57 -0400)] 
lfstack: combine C++ API cds_lfs_stack_cast with overloading

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

3 years agofix: test_build tap plan
Michael Jeanson [Wed, 8 Sep 2021 19:48:35 +0000 (15:48 -0400)] 
fix: test_build tap plan

Change-Id: I83dc2343fe7c457a1ec0c94ed164c1365fce2bdb
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 years agoTest C++ build of list head init
Simon Marchi [Wed, 8 Sep 2021 19:31:08 +0000 (15:31 -0400)] 
Test C++ build of list head init

Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: Iaf7655c8a8e76d004910da14343bbebc4309576e

3 years agoFix order of initializers in CDS_LIST_HEAD_INIT
Mathieu Desnoyers [Wed, 8 Sep 2021 19:30:28 +0000 (15:30 -0400)] 
Fix order of initializers in CDS_LIST_HEAD_INIT

When using CDS_LIST_HEAD_INIT in a C++ program, we get (with clang
rather than gcc, because the error message is clearer):

    /home/simark/src/urcu/tests/unit/test_build_cxx.cpp:73:13: error: ISO C++ requires field designators to be specified in declaration order; field 'prev' will be initialized after field 'next' [-Werror,-Wreorder-init-list]
        .head = CDS_LIST_HEAD_INIT(list.head),
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /home/simark/src/urcu/include/urcu/list.h:49:53: note: expanded from macro 'CDS_LIST_HEAD_INIT'
    #define CDS_LIST_HEAD_INIT(name) { .prev = &(name), .next = &(name) }
                                                        ^~~~~~~~~~~~~~~
    /home/simark/src/urcu/tests/unit/test_build_cxx.cpp:73:13: note: previous initialization for field 'prev' is here
        .head = CDS_LIST_HEAD_INIT(list.head),
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /home/simark/src/urcu/include/urcu/list.h:49:44: note: expanded from macro 'CDS_LIST_HEAD_INIT'
    #define CDS_LIST_HEAD_INIT(name) { .prev = &(name), .next = &(name) }
                                               ^~~~~~~

Fix that by swapping the initializers in CDS_LIST_HEAD_INIT.

Change-Id: Ib127b9cc128fd64f5b2ae028e093be42ca10f437
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 years agounit tests: test wfcqueue, wfstack, lfstack empty check functions in C++
Mathieu Desnoyers [Wed, 8 Sep 2021 19:27:12 +0000 (15:27 -0400)] 
unit tests: test wfcqueue, wfstack, lfstack empty check functions in C++

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

3 years agowfcqueue: implement C++ API based on function overloading
Mathieu Desnoyers [Wed, 8 Sep 2021 19:26:59 +0000 (15:26 -0400)] 
wfcqueue: implement C++ API based on function overloading

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

3 years agowfstack: implement C++ API based on function overloading
Mathieu Desnoyers [Wed, 8 Sep 2021 19:26:41 +0000 (15:26 -0400)] 
wfstack: implement C++ API based on function overloading

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

3 years agolfstack: implement C++ API based on function overloading
Mathieu Desnoyers [Wed, 8 Sep 2021 19:26:15 +0000 (15:26 -0400)] 
lfstack: implement C++ API based on function overloading

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

3 years agoFix tap.h: remove extra semicolon in pass/fail macros
Mathieu Desnoyers [Wed, 8 Sep 2021 17:54:29 +0000 (13:54 -0400)] 
Fix tap.h: remove extra semicolon in pass/fail macros

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

3 years agoAdd C++ build tests
Simon Marchi [Thu, 29 Jul 2021 02:48:21 +0000 (22:48 -0400)] 
Add C++ build tests

Some urcu header files cause build failures when included in C++
programs.  Add a test file that includes all exported headers (except
those that are marked as deprecated) and build that test file as a C and
C++ program, with and without _LGPL_SOURCE defined (to test both the
static and non-static implementations).  This helps ensure that the code
in these headers works as both languages.  This alone does not ensure
full coverage, there may be code in unused macros that would need
fixing.  But by including the "static" headers, this already finds a few
issues.

The test doesn't run anything, its purpose is only to verify that things
build.

This catches the following build failures:

 - clang++ doesn't know the __transparent_union__ attribute, place some
   pragmas to ignore this warning around where __transparent_union__ is
   used.

 - CDS_WFS_WOULDBLOCK and CDS_WFS_END are cast to a void*.  This doesn't
   work in C++ when assigning to a field them to typed pointer.  Fix
   them by casting to the appropriate type.

 - The transparent union trick doesn't work in C++:

      CXX      test_build_cxx.o
    In file included from /home/simark/src/urcu/include/urcu/wfstack.h:116,
                     from /home/simark/src/urcu/include/urcu/cds.h:35,
                     from /home/simark/src/urcu/tests/unit/test_build_cxx.cpp:34:
    /home/simark/src/urcu/include/urcu/static/wfstack.h: In function ‘cds_wfs_node* _cds_wfs_pop_with_state_blocking(cds_wfs_stack*, int*)’:
    /home/simark/src/urcu/include/urcu/static/wfstack.h:350:54: error: could not convert ‘s’ from ‘cds_wfs_stack*’ to ‘cds_wfs_stack_ptr_t’
      350 |         retnode = ___cds_wfs_pop_with_state_blocking(s, state);
          |                                                      ^
          |                                                      |
          |                                                      cds_wfs_stack*

   A C++ user can fall back to instantiating a cds_wfs_stack_ptr_t
   explicitly, assigning the right field, and passing the
   cds_wfs_stack_ptr_t to the function.  Fix a few instances in the
   static headers.

   A follow up commit will introduce C++ API wrappers based on
   function overloading to provide a C++ API similar to the C API.

Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I30adc8df69414a0a019c5ec081f64cfac64843f5

3 years agoBuild and run regression and unit tests as C++ programs
Simon Marchi [Tue, 31 Aug 2021 22:12:44 +0000 (18:12 -0400)] 
Build and run regression and unit tests as C++ programs

Build and run all tests under tests/regression and tests/unit as C++
programs in addition to C.  This helps get confidence that urcu, when
used from a C++ program, behaves well.

Change-Id: Iacaa42dddbcbf59eff8e327edfd0352cce0b74b7
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 years agoAdd --enable-Werror configure switch
Simon Marchi [Tue, 31 Aug 2021 22:09:49 +0000 (18:09 -0400)] 
Add --enable-Werror configure switch

Change-Id: I514335a042b962dcb737f03e2c19c2223961b99c
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 years agoAdd `urcu_posix_assert()` as `assert()` replacement
Francis Deslauriers [Wed, 1 Sep 2021 17:34:17 +0000 (13:34 -0400)] 
Add `urcu_posix_assert()` as `assert()` replacement

This macro acts like the regular `assert()` macro unless NDEBUG is
defined in which case it consumes the expression and becomes a no-op.

This consumption trick (see `_urcu_use_expression()` macro) prevents the
compiler from warning about unused variables even when assert() are
removed by the NDEBUG define.

This macro is also used for the existing `urcu_assert_debug()` macro.

The implementation of `_urcu_use_expression()` is inspired by the
Babeltrace 2 approach.

See `BT_USE_EXPR()` macro and documentation in Babeltrace commit [1]:
  commit 1778c2a4134647150b199b2b57130817144446b0
  Author: Philippe Proulx <eeppeliteloop@gmail.com>
  Date:   Tue Apr 21 11:15:42 2020 -0400
  lib: assign a unique ID to each pre/postcond. and report it on failure

All assertion macros are moved to the new urcu/assert.h file.

Link: https://github.com/efficios/babeltrace/commit/1778c2a4134647150b199b2b57130817144446b0
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: If60ce2d3f45ea8f5ec1dbb92fb43f83fd9f8102b

3 years agoRename `urcu_assert()` to `urcu_assert_debug()`
Francis Deslauriers [Wed, 1 Sep 2021 15:45:01 +0000 (11:45 -0400)] 
Rename `urcu_assert()` to `urcu_assert_debug()`

This is done in preparation for the addition of the `urcu_posix_assert()`
macro that will replace the vanilla `assert()` in the project.

We must continue to expose the `urcu_assert()` macro in the `urcu/debug.h`
file as it's used by at least one external project (LTTng-UST).

Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I02f237450a35b57e37718c87a0596a5a14468f58

3 years agocleanup: spelling fixes in comments
Michael Jeanson [Thu, 29 Jul 2021 19:49:55 +0000 (15:49 -0400)] 
cleanup: spelling fixes in comments

Change-Id: I22ae33365d77abeb5f7051882e9d0fa807e38f6f
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 years agoMake temporary variable in _rcu_dereference non-const
Simon Marchi [Fri, 30 Jul 2021 03:06:11 +0000 (23:06 -0400)] 
Make temporary variable in _rcu_dereference non-const

When building the lttng-tools project with Ubuntu's gcc 11, I get the
following error:

      CC       agent.lo
    In file included from /tmp/lttng/include/urcu/arch.h:25,
                     from /tmp/lttng/include/urcu/uatomic.h:23,
                     from /home/simark/src/lttng-tools/src/bin/lttng-sessiond/agent.c:11:
    /home/simark/src/lttng-tools/src/bin/lttng-sessiond/agent.c: In function ‘agent_update’:
    /tmp/lttng/include/urcu/static/pointer.h:96:33: error: argument 2 of ‘__atomic_load’ discards ‘const’ qualifier [-Werror=incompatible-pointer-types]
       96 |                                 __atomic_load(&(p), &_________p1, __ATOMIC_CONSUME);    \
          |                                 ^~~~~~~~~~~~~
    /tmp/lttng/include/urcu/compiler.h:69:70: note: in definition of macro ‘caa_container_of’
       69 |                 const __typeof__(((type *) NULL)->member) * __ptr = (ptr); \
          |                                                                      ^~~
    /tmp/lttng/include/urcu/rculist.h:87:20: note: in expansion of macro ‘cds_list_entry’
       87 |         for (pos = cds_list_entry(rcu_dereference((head)->next), __typeof__(*(pos)), member); \
          |                    ^~~~~~~~~~~~~~
    /tmp/lttng/include/urcu/pointer.h:47:33: note: in expansion of macro ‘_rcu_dereference’
       47 | #define rcu_dereference         _rcu_dereference
          |                                 ^~~~~~~~~~~~~~~~
    /tmp/lttng/include/urcu/rculist.h:87:35: note: in expansion of macro ‘rcu_dereference’
       87 |         for (pos = cds_list_entry(rcu_dereference((head)->next), __typeof__(*(pos)), member); \
          |                                   ^~~~~~~~~~~~~~~
    /home/simark/src/lttng-tools/src/bin/lttng-sessiond/agent.c:1551:9: note: in expansion of macro ‘cds_list_for_each_entry_rcu’
     1551 |         cds_list_for_each_entry_rcu(ctx, &agt->app_ctx_list, list_node) {
          |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~

This is because the pointer passed to _rcu_dereference is const (the
pointer itself is const, IIUC, not necessarily the data it points to),
so the temporary _________p1 is also declared as const.  We therefore
can't pass a non-const pointer to it to a function that modifies it.

I applied the trick found here [1] with success to get rid of the
constness of the variable.  With this change, lttng-tools compiles
successfully with gcc 11.

There may be other spots in the headers where this would be needed, but
it is hard to spot them.  I think we would need to write some test file
that pass const pointers to all macros of the API and see if they
compile.

[1] https://stackoverflow.com/a/18067745

Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: Ib43efa7674ecea99cec1c3fffae86829b44a97e5

3 years agoFix: x86 and s390: uatomic __hp() macro C++ support
Mathieu Desnoyers [Wed, 16 Jun 2021 14:03:48 +0000 (10:03 -0400)] 
Fix: x86 and s390: uatomic __hp() macro C++ support

C++ does not allow defining types in cast. Therefore, define the types
with typedef and use them in the __hp() macro.

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

This page took 0.05092 seconds and 4 git commands to generate.