!9 update to 0.12.1

Merge pull request !9 from 靳智敏/master
This commit is contained in:
openeuler-ci-bot 2020-07-21 20:10:22 +08:00 committed by Gitee
commit 686ce7ab03
14 changed files with 5 additions and 735 deletions

View File

@ -1,58 +0,0 @@
From 136211f67b5ba804fd0e02603bcef61ac47dbc16 Mon Sep 17 00:00:00 2001
From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Date: Sun, 9 Dec 2018 06:31:57 -0500
Subject: [PATCH 06/15] Cleanup: workqueue: update comments referring to
call-rcu
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
---
src/workqueue.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/src/workqueue.c b/src/workqueue.c
index 8561a7a..db0c63a 100644
--- a/src/workqueue.c
+++ b/src/workqueue.c
@@ -37,7 +37,6 @@
#include "compat-getcpu.h"
#include "urcu/wfcqueue.h"
-#include "urcu-call-rcu.h"
#include "urcu-pointer.h"
#include "urcu/list.h"
#include "urcu/futex.h"
@@ -55,10 +54,9 @@
struct urcu_workqueue {
/*
* We do not align head on a different cache-line than tail
- * mainly because call_rcu callback-invocation threads use
- * batching ("splice") to get an entire list of callbacks, which
- * effectively empties the queue, and requires to touch the tail
- * anyway.
+ * mainly because workqueue threads use batching ("splice") to
+ * get an entire list of callbacks, which effectively empties
+ * the queue, and requires to touch the tail anyway.
*/
struct cds_wfcq_tail cbs_tail;
struct cds_wfcq_head cbs_head;
@@ -244,7 +242,7 @@ static void *workqueue_thread(void *arg)
uatomic_dec(&workqueue->futex);
/*
* Decrement futex before reading
- * call_rcu list.
+ * urcu_work list.
*/
cmm_smp_mb();
} else {
@@ -258,7 +256,7 @@ static void *workqueue_thread(void *arg)
}
if (!rt) {
/*
- * Read call_rcu list before write futex.
+ * Read urcu_work list before write futex.
*/
cmm_smp_mb();
uatomic_set(&workqueue->futex, 0);
--
2.19.1

View File

@ -1,48 +0,0 @@
From b197ce865b0de8c475f3ddeadeae3a66b15ace21 Mon Sep 17 00:00:00 2001
From: Michael Jeanson <mjeanson@efficios.com>
Date: Fri, 23 Nov 2018 15:27:04 -0500
Subject: [PATCH 01/15] Fix: compat_futex_noasync on Cygwin
The futex_noasync compat code uses a weak symbol to share state across
different shared object which is not possible on Windows with the
Portable Executable format. Use the async compat code for both cases.
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
---
include/urcu/futex.h | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/include/urcu/futex.h b/include/urcu/futex.h
index 0486ff6..753df62 100644
--- a/include/urcu/futex.h
+++ b/include/urcu/futex.h
@@ -102,6 +102,25 @@ static inline int futex_async(int32_t *uaddr, int op, int32_t val,
return ret;
}
+#elif defined(__CYGWIN__)
+
+/*
+ * The futex_noasync compat code uses a weak symbol to share state across
+ * different shared object which is not possible on Windows with the
+ * Portable Executable format. Use the async compat code for both cases.
+ */
+static inline int futex_noasync(int32_t *uaddr, int op, int32_t val,
+ const struct timespec *timeout, int32_t *uaddr2, int32_t val3)
+{
+ return compat_futex_async(uaddr, op, val, timeout, uaddr2, val3);
+}
+
+static inline int futex_async(int32_t *uaddr, int op, int32_t val,
+ const struct timespec *timeout, int32_t *uaddr2, int32_t val3)
+{
+ return compat_futex_async(uaddr, op, val, timeout, uaddr2, val3);
+}
+
#else
static inline int futex_noasync(int32_t *uaddr, int op, int32_t val,
--
2.19.1

View File

@ -1,49 +0,0 @@
From 79eca0929fc50a668a15937b5bf4d1cb97049de8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=
<jeremie.galarneau@efficios.com>
Date: Fri, 7 Dec 2018 17:06:38 -0500
Subject: [PATCH 09/15] Fix: don't wait after completion of a work queue job
batch
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
As indicated in the previous patch of this series, waiting on
completion of a job batch from the work queue artificially increases
the latency of the work queue.
The previous patch removed the wait that is performed when the
work queue is observed to be empty and was observed as the cause of a
performance problem.
It is likely that waiting when the queue is observed to be non-empty
is similarly unintended. Note that I have not observed such a problem
myself.
If a workqueue user even need the explicit delay for batching (e.g. if
a call-rcu implementation would ever use the workqueue worker thread),
it can add it within the worker_before_wait_fct callback received as
argument from workqueue creation.
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
---
src/workqueue.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/workqueue.c b/src/workqueue.c
index 0b1a9ea..39d0e07 100644
--- a/src/workqueue.c
+++ b/src/workqueue.c
@@ -244,8 +244,6 @@ static void *workqueue_thread(void *arg)
* urcu_work list.
*/
cmm_smp_mb();
- } else {
- (void) poll(NULL, 0, 10);
}
} else {
(void) poll(NULL, 0, 10);
--
2.19.1

View File

@ -1,56 +0,0 @@
From d3e42beb106479eae7c234bb0aeacce92661ca7a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=
<jeremie.galarneau@efficios.com>
Date: Fri, 7 Dec 2018 17:06:37 -0500
Subject: [PATCH 08/15] Fix: don't wait after completion of job batch if work
queue is empty
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On completion of a batch of jobs from the work queue, a wait of 10
ms (using poll()) is performed if there is no work present in the
work queue before waiting on its futex.
The work queue thread's structure is inspired by the call-rcu thread.
In the context of the call-rcu thread, my understanding is that the
intention is to ensure that the thread does not continuously wake-up
to process a single queued item. This is fine as an application should
not wait for a call-rcu job to be executed (or at least I don't see a
use-case for that).
In the context of the work queue, waiting for more work to be available
artificially slows down the execution of work on which an application
may wait.
I have observed a case where LTTng's session daemon's shutdown is
takes around 4 seconds as a large number of cds_lfht objects are
destroyed. Removing the wait reduces the duration of this phase of the
shut-down to almost ~10ms.
If a workqueue user even need the explicit delay for batching (e.g. if
a call-rcu implementation would ever use the workqueue worker thread),
it can add it within the worker_before_wait_fct callback received as
argument from workqueue creation.
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
---
src/workqueue.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/workqueue.c b/src/workqueue.c
index 6707ffe..0b1a9ea 100644
--- a/src/workqueue.c
+++ b/src/workqueue.c
@@ -238,7 +238,6 @@ static void *workqueue_thread(void *arg)
if (cds_wfcq_empty(&workqueue->cbs_head,
&workqueue->cbs_tail)) {
futex_wait(&workqueue->futex);
- (void) poll(NULL, 0, 10);
uatomic_dec(&workqueue->futex);
/*
* Decrement futex before reading
--
2.19.1

View File

@ -1,45 +0,0 @@
From 0aa1fccd3aff5f5a7717c166f7bfbe864d041f23 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=
<jeremie.galarneau@efficios.com>
Date: Fri, 7 Dec 2018 17:06:36 -0500
Subject: [PATCH 05/15] Fix: mixup between URCU_WORKQUEUE_RT and
URCU_CALL_RCU_RT
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The work queue implementation is derived from the call-rcu thread. A
number of references seem to have been left in place when adapting the
code for its new purpose.
The URCU_CALL_RCU_RT flag is used by wake_worker_thread() while the
rest of the workqueue.c code uses URCU_WORKQUEUE_RT to determine if
the work queue was configured in real-time mode. Both flags are defined
to the same value (0x1) and the current internal user of the
work queue (lfht) never specifies any flags.
In practice, this does not cause any problem, but this mixup should
be fixed nevertheless.
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
---
src/workqueue.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/workqueue.c b/src/workqueue.c
index 17ea835..8561a7a 100644
--- a/src/workqueue.c
+++ b/src/workqueue.c
@@ -309,7 +309,7 @@ struct urcu_workqueue *urcu_workqueue_create(unsigned long flags,
static void wake_worker_thread(struct urcu_workqueue *workqueue)
{
- if (!(_CMM_LOAD_SHARED(workqueue->flags) & URCU_CALL_RCU_RT))
+ if (!(_CMM_LOAD_SHARED(workqueue->flags) & URCU_WORKQUEUE_RT))
futex_wake_up(&workqueue->futex);
}
--
2.19.1

View File

@ -1,48 +0,0 @@
From 803e59362b6d94edff3a36f47a9da3e8dca4bde2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=
<jeremie.galarneau@efficios.com>
Date: Fri, 7 Dec 2018 17:06:39 -0500
Subject: [PATCH 10/15] Fix: only wait if work queue is empty in real-time mode
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Unconditionally waiting for 10 ms after the completion of every batch
of jobs of the work queue in real-time mode appears to be a behaviour
inherited from the call-rcu thread.
While this is a fair trade-off in the context of call-rcu, it is less
evident that it is desirable in the context of a general-purpose
work queue. Waiting when work is available artificially degrades the
latency characteristics of the work queue.
If a workqueue user even need the explicit delay for batching (e.g. if
a call-rcu implementation would ever use the workqueue worker thread),
it can add it within the worker_before_wait_fct callback received as
argument from workqueue creation.
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
---
src/workqueue.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/workqueue.c b/src/workqueue.c
index 39d0e07..14957a0 100644
--- a/src/workqueue.c
+++ b/src/workqueue.c
@@ -246,7 +246,10 @@ static void *workqueue_thread(void *arg)
cmm_smp_mb();
}
} else {
- (void) poll(NULL, 0, 10);
+ if (cds_wfcq_empty(&workqueue->cbs_head,
+ &workqueue->cbs_tail)) {
+ (void) poll(NULL, 0, 10);
+ }
}
if (workqueue->worker_after_wake_up_fct)
workqueue->worker_after_wake_up_fct(workqueue, workqueue->priv);
--
2.19.1

View File

@ -1,224 +0,0 @@
From eec2f6a5c353f28bb74e4a3f96a3da5a50f25574 Mon Sep 17 00:00:00 2001
From: Michael Jeanson <mjeanson@efficios.com>
Date: Fri, 23 Nov 2018 16:47:18 -0500
Subject: [PATCH 02/15] Fix: pthread_rwlock initialization on Cygwin
On Cygwin the PTHREAD_RWLOCK_INITIALIZER macro is not
sufficient to get a properly initialized pthread_rwlock_t
struct. Use the pthread_rwlock_init function instead which
should work on all platforms.
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
---
tests/benchmark/test_rwlock.c | 51 ++++++++++++++++++++++++----
tests/benchmark/test_rwlock_timing.c | 50 +++++++++++++++++++++++----
2 files changed, 88 insertions(+), 13 deletions(-)
diff --git a/tests/benchmark/test_rwlock.c b/tests/benchmark/test_rwlock.c
index 4448597..f95e4e1 100644
--- a/tests/benchmark/test_rwlock.c
+++ b/tests/benchmark/test_rwlock.c
@@ -48,7 +48,11 @@ struct test_array {
int a;
};
-pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER;
+/*
+ * static rwlock initializer is broken on Cygwin. Use runtime
+ * initialization.
+ */
+pthread_rwlock_t lock;
static volatile int test_go, test_stop;
@@ -173,14 +177,25 @@ void *thr_reader(void *_count)
}
for (;;) {
- int a;
+ int a, ret;
+
+ ret = pthread_rwlock_rdlock(&lock);
+ if (ret) {
+ fprintf(stderr, "reader pthread_rwlock_rdlock: %s\n", strerror(ret));
+ abort();
+ }
- pthread_rwlock_rdlock(&lock);
a = test_array.a;
assert(a == 8);
if (caa_unlikely(rduration))
loop_sleep(rduration);
- pthread_rwlock_unlock(&lock);
+
+ ret = pthread_rwlock_unlock(&lock);
+ if (ret) {
+ fprintf(stderr, "reader pthread_rwlock_unlock: %s\n", strerror(ret));
+ abort();
+ }
+
URCU_TLS(nr_reads)++;
if (caa_unlikely(!test_duration_read()))
break;
@@ -208,12 +223,25 @@ void *thr_writer(void *_count)
cmm_smp_mb();
for (;;) {
- pthread_rwlock_wrlock(&lock);
+ int ret;
+
+ ret = pthread_rwlock_wrlock(&lock);
+ if (ret) {
+ fprintf(stderr, "writer pthread_rwlock_wrlock: %s\n", strerror(ret));
+ abort();
+ }
+
test_array.a = 0;
test_array.a = 8;
if (caa_unlikely(wduration))
loop_sleep(wduration);
- pthread_rwlock_unlock(&lock);
+
+ ret = pthread_rwlock_unlock(&lock);
+ if (ret) {
+ fprintf(stderr, "writer pthread_rwlock_unlock: %s\n", strerror(ret));
+ abort();
+ }
+
URCU_TLS(nr_writes)++;
if (caa_unlikely(!test_duration_write()))
break;
@@ -321,6 +349,12 @@ int main(int argc, char **argv)
printf_verbose("thread %-6s, tid %lu\n",
"main", urcu_get_thread_id());
+ err = pthread_rwlock_init(&lock, NULL);
+ if (err != 0) {
+ fprintf(stderr, "pthread_rwlock_init: (%d) %s\n", err, strerror(err));
+ exit(1);
+ }
+
tid_reader = calloc(nr_readers, sizeof(*tid_reader));
tid_writer = calloc(nr_writers, sizeof(*tid_writer));
count_reader = calloc(nr_readers, sizeof(*count_reader));
@@ -371,6 +405,11 @@ int main(int argc, char **argv)
nr_writers, wdelay, tot_reads, tot_writes,
tot_reads + tot_writes);
+ err = pthread_rwlock_destroy(&lock);
+ if (err != 0) {
+ fprintf(stderr, "pthread_rwlock_destroy: (%d) %s\n", err, strerror(err));
+ exit(1);
+ }
free(tid_reader);
free(tid_writer);
free(count_reader);
diff --git a/tests/benchmark/test_rwlock_timing.c b/tests/benchmark/test_rwlock_timing.c
index a52da38..bc51c45 100644
--- a/tests/benchmark/test_rwlock_timing.c
+++ b/tests/benchmark/test_rwlock_timing.c
@@ -42,7 +42,11 @@ struct test_array {
int a;
};
-pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER;
+/*
+ * static rwlock initializer is broken on Cygwin. Use runtime
+ * initialization.
+ */
+pthread_rwlock_t lock;
static struct test_array test_array = { 8 };
@@ -65,7 +69,7 @@ static caa_cycles_t __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *writer_time;
void *thr_reader(void *arg)
{
- int i, j;
+ int i, j, ret;
caa_cycles_t time1, time2;
printf("thread_begin %s, tid %lu\n",
@@ -75,9 +79,19 @@ void *thr_reader(void *arg)
time1 = caa_get_cycles();
for (i = 0; i < OUTER_READ_LOOP; i++) {
for (j = 0; j < INNER_READ_LOOP; j++) {
- pthread_rwlock_rdlock(&lock);
+ ret = pthread_rwlock_rdlock(&lock);
+ if (ret) {
+ fprintf(stderr, "reader pthread_rwlock_rdlock: %s\n", strerror(ret));
+ abort();
+ }
+
assert(test_array.a == 8);
- pthread_rwlock_unlock(&lock);
+
+ ret = pthread_rwlock_unlock(&lock);
+ if (ret) {
+ fprintf(stderr, "reader pthread_rwlock_unlock: %s\n", strerror(ret));
+ abort();
+ }
}
}
time2 = caa_get_cycles();
@@ -93,7 +107,7 @@ void *thr_reader(void *arg)
void *thr_writer(void *arg)
{
- int i, j;
+ int i, j, ret;
caa_cycles_t time1, time2;
printf("thread_begin %s, tid %lu\n",
@@ -103,9 +117,20 @@ void *thr_writer(void *arg)
for (i = 0; i < OUTER_WRITE_LOOP; i++) {
for (j = 0; j < INNER_WRITE_LOOP; j++) {
time1 = caa_get_cycles();
- pthread_rwlock_wrlock(&lock);
+ ret = pthread_rwlock_wrlock(&lock);
+ if (ret) {
+ fprintf(stderr, "writer pthread_rwlock_wrlock: %s\n", strerror(ret));
+ abort();
+ }
+
test_array.a = 8;
- pthread_rwlock_unlock(&lock);
+
+ ret = pthread_rwlock_unlock(&lock);
+ if (ret) {
+ fprintf(stderr, "writer pthread_rwlock_unlock: %s\n", strerror(ret));
+ abort();
+ }
+
time2 = caa_get_cycles();
writer_time[(unsigned long)arg] += time2 - time1;
usleep(1);
@@ -133,6 +158,12 @@ int main(int argc, char **argv)
num_read = atoi(argv[1]);
num_write = atoi(argv[2]);
+ err = pthread_rwlock_init(&lock, NULL);
+ if (err != 0) {
+ fprintf(stderr, "pthread_rwlock_init: (%d) %s\n", err, strerror(err));
+ exit(1);
+ }
+
reader_time = calloc(num_read, sizeof(*reader_time));
writer_time = calloc(num_write, sizeof(*writer_time));
tid_reader = calloc(num_read, sizeof(*tid_reader));
@@ -173,6 +204,11 @@ int main(int argc, char **argv)
printf("Time per write : %g cycles\n",
(double)tot_wtime / ((double)NR_WRITE * (double)WRITE_LOOP));
+ err = pthread_rwlock_destroy(&lock);
+ if (err != 0) {
+ fprintf(stderr, "pthread_rwlock_destroy: (%d) %s\n", err, strerror(err));
+ exit(1);
+ }
free(reader_time);
free(writer_time);
free(tid_reader);
--
2.19.1

View File

@ -1,41 +0,0 @@
From f3a942e30e3a217cfbf987d5e6bec1d89c394963 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Thu, 25 Jun 2020 07:20:38 +0800
Subject: [PATCH] fix-make-test-error
---
tests/Makefile.am | 1 -
tests/benchmark/Makefile.am | 4 +---
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 03f3f29..7e91a71 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -8,4 +8,3 @@ long_bench:
cd benchmark && $(MAKE) $(AM_MAKEFLAGS) long_bench
regtest:
cd regression && $(MAKE) $(AM_MAKEFLAGS) regtest
- cd benchmark && $(MAKE) $(AM_MAKEFLAGS) regtest
diff --git a/tests/benchmark/Makefile.am b/tests/benchmark/Makefile.am
index 216d013..35e2db6 100644
--- a/tests/benchmark/Makefile.am
+++ b/tests/benchmark/Makefile.am
@@ -226,7 +226,7 @@ clean-local:
done; \
fi
-.PHONY: short_bench long_bench regtest
+.PHONY: short_bench long_bench
short_bench:
./run.sh short_bench_tests
@@ -234,5 +234,3 @@ short_bench:
long_bench:
./run.sh long_bench_tests
-regtest:
- ./run.sh regression_tests
--
2.23.0

View File

@ -1,42 +0,0 @@
From 9e19a6b0d350ffb70e9f29d8eea371c6b7ffad72 Mon Sep 17 00:00:00 2001
From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Date: Sun, 9 Dec 2018 06:37:09 -0500
Subject: [PATCH 07/15] Fix: workqueue: struct urcu_work vs rcu_head mixup
The workqueue code was derived from call-rcu, and its API
expects a struct urcu_work for work items, but it internally iterates
over struct rcu_head.
This is not an issue at runtime because both structures have the
exact same layout and content, but it is a type mixup nevertheless.
Use the right type in the implementation.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
---
src/workqueue.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/workqueue.c b/src/workqueue.c
index db0c63a..6707ffe 100644
--- a/src/workqueue.c
+++ b/src/workqueue.c
@@ -221,11 +221,11 @@ static void *workqueue_thread(void *arg)
cbcount = 0;
__cds_wfcq_for_each_blocking_safe(&cbs_tmp_head,
&cbs_tmp_tail, cbs, cbs_tmp_n) {
- struct rcu_head *rhp;
+ struct urcu_work *uwp;
- rhp = caa_container_of(cbs,
- struct rcu_head, next);
- rhp->func(rhp);
+ uwp = caa_container_of(cbs,
+ struct urcu_work, next);
+ uwp->func(uwp);
cbcount++;
}
uatomic_sub(&workqueue->qlen, cbcount);
--
2.19.1

View File

@ -1,52 +0,0 @@
From 6c249cd8c0a48370bac8511216c166e98104d699 Mon Sep 17 00:00:00 2001
From: Michael Jeanson <mjeanson@efficios.com>
Date: Fri, 23 Nov 2018 15:27:07 -0500
Subject: [PATCH 04/15] test_rwlock: Add per-thread count to verbose output
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
---
tests/benchmark/test_rwlock.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/tests/benchmark/test_rwlock.c b/tests/benchmark/test_rwlock.c
index f95e4e1..827c117 100644
--- a/tests/benchmark/test_rwlock.c
+++ b/tests/benchmark/test_rwlock.c
@@ -202,8 +202,9 @@ void *thr_reader(void *_count)
}
*count = URCU_TLS(nr_reads);
- printf_verbose("thread_end %s, tid %lu\n",
- "reader", urcu_get_thread_id());
+
+ printf_verbose("thread_end %s, tid %lu, count %llu\n",
+ "reader", urcu_get_thread_id(), *count);
return ((void*)1);
}
@@ -248,10 +249,10 @@ void *thr_writer(void *_count)
if (caa_unlikely(wdelay))
loop_sleep(wdelay);
}
-
- printf_verbose("thread_end %s, tid %lu\n",
- "writer", urcu_get_thread_id());
*count = URCU_TLS(nr_writes);
+
+ printf_verbose("thread_end %s, tid %lu, count %llu\n",
+ "writer", urcu_get_thread_id(), *count);
return ((void*)2);
}
@@ -345,6 +346,7 @@ int main(int argc, char **argv)
printf_verbose("running test for %lu seconds, %u readers, %u writers.\n",
duration, nr_readers, nr_writers);
printf_verbose("Writer delay : %lu loops.\n", wdelay);
+ printf_verbose("Writer duration : %lu loops.\n", wduration);
printf_verbose("Reader duration : %lu loops.\n", rduration);
printf_verbose("thread %-6s, tid %lu\n",
"main", urcu_get_thread_id());
--
2.19.1

View File

@ -1,57 +0,0 @@
From 11dcfc5e044f55941ffd3f1155bbda51ed05aff7 Mon Sep 17 00:00:00 2001
From: hewenliang <hewenliang4@huawei.com>
Date: Mon, 12 Aug 2019 22:30:20 +0000
Subject: [PATCH] urcu: fix deadlock issue using SIG_RCU
reason:
1.use a seperate thread(cds_lfht_workqueue) to handle hash table auto resize,
and this thread block all signal at initialization.
2.While in urcu-signal flavor, call_rcu_thread will send SIGRCU signal to all
the registed thread to make them do cmm_smp_mb.
3.Based on above, call_rcu_thread and workqueue thread will trapped into a dead
loop: where call_rcu_thread hold the rcu_registry_lock to waiting all the registed
thread to do cmm_smp_mb, while workqueue thread nerver do cmm_smp_mb and waiting to
get rcu_registry_lock to unregiter from rcu.
so we should not block SIGRCU in workqueue thread to avoid the dead lock.
Signed-off-by: hewenliang <hewenliang4@huawei.com>
---
src/rculfhash.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/rculfhash.c b/src/rculfhash.c
index fed33e4..fc3d610 100644
--- a/src/rculfhash.c
+++ b/src/rculfhash.c
@@ -273,6 +273,7 @@
#include <urcu/uatomic.h>
#include <urcu/compiler.h>
#include <urcu/rculfhash.h>
+#include <urcu.h>
#include <rculfhash-internal.h>
#include <stdio.h>
#include <pthread.h>
@@ -2112,7 +2113,7 @@ static void cds_lfht_worker_init(struct urcu_workqueue *workqueue,
{
int ret;
sigset_t mask;
-
+ sigset_t set;
/* Block signal for entire process, so only our thread processes it. */
ret = sigfillset(&mask);
if (ret)
@@ -2120,6 +2121,11 @@ static void cds_lfht_worker_init(struct urcu_workqueue *workqueue,
ret = pthread_sigmask(SIG_BLOCK, &mask, NULL);
if (ret)
urcu_die(ret);
+ sigemptyset(&set);
+ sigaddset(&set, SIGRCU);
+ ret = pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+ if (ret)
+ urcu_die(ret);
}
static void cds_lfht_init_worker(const struct rcu_flavor_struct *flavor)
--
2.19.1

Binary file not shown.

Binary file not shown.

View File

@ -1,24 +1,11 @@
Name: userspace-rcu
Version: 0.10.1
Release: 10
Version: 0.12.1
Release: 1
Summary: Userspace read-copy-update library
License: LGPLv2+
URL: http://liburcu.org
Source0: http://lttng.org/files/urcu/%{name}-%{version}.tar.bz2
Patch6000: fix-compat_futex_noasync-on-Cygwin.patch
Patch6001: fix-pthread_rwlock-initialization-on-Cygwin.patch
Patch6002: test_rwlock-Add-per-thread-count-to-verbose-output.patch
Patch6003: fix-mixup-between-URCU_WORKQUEUE_RT-and-URCU_CALL_RC.patch
Patch6004: cleanup-workqueue-update-comments-referring-to-call-.patch
Patch6005: fix-workqueue-struct-urcu_work-vs-rcu_head-mixup.patch
Patch6006: fix-don-t-wait-after-completion-of-job-batch-if-work.patch
Patch6007: fix-don-t-wait-after-completion-of-a-work-queue-job-.patch
Patch6008: fix-only-wait-if-work-queue-is-empty-in-real-time-mo.patch
Patch6009: fix-regtest-without-bench.patch
Patch9000: urcu-fix-deadlock-issue-using-SIG_RCU.patch
BuildRequires: pkgconfig perl-Test-Harness autoconf automake libtool
%description
@ -77,6 +64,9 @@ make check
%changelog
* Thu Jul 21 2020 jinzhimin <jinzhimin2@huawei.com> - 0.12.1-1
- upgrade to 0.12.1
* Thu Jun 29 2020 xinghe <xinghe1@huawei.com> - 0.10.1-10
- Type:bugfix
- ID:NA