projects
/
urcu.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
qsbr: Add write+read thread support to 32-bit QSBR
[urcu.git]
/
urcu-qsbr.c
diff --git
a/urcu-qsbr.c
b/urcu-qsbr.c
index a86f6e94d5ae13eb24e5d34610a3d9c5954373b4..3b9a054b40b1bc61f29768bf5d4085d62a8b7bd9 100644
(file)
--- a/
urcu-qsbr.c
+++ b/
urcu-qsbr.c
@@
-135,12
+135,24
@@
static void switch_next_urcu_qparity(void)
void synchronize_rcu(void)
{
void synchronize_rcu(void)
{
+ unsigned long was_online;
+
+ was_online = rcu_reader_qs_gp;
+
/* All threads should read qparity before accessing data structure
* where new ptr points to.
*/
/* Write new ptr before changing the qparity */
smp_mb();
/* All threads should read qparity before accessing data structure
* where new ptr points to.
*/
/* Write new ptr before changing the qparity */
smp_mb();
+ /*
+ * Mark the writer thread offline to make sure we don't wait for
+ * our own quiescent state. This allows using synchronize_rcu() in
+ * threads registered as readers.
+ */
+ if (was_online)
+ STORE_SHARED(rcu_reader_qs_gp, 0);
+
internal_urcu_lock();
switch_next_urcu_qparity(); /* 0 -> 1 */
internal_urcu_lock();
switch_next_urcu_qparity(); /* 0 -> 1 */
@@
-183,9
+195,12
@@
void synchronize_rcu(void)
internal_urcu_unlock();
internal_urcu_unlock();
- /* Finish waiting for reader threads before letting the old ptr being
+ /*
+ * Finish waiting for reader threads before letting the old ptr being
* freed.
*/
* freed.
*/
+ if (was_online)
+ _STORE_SHARED(rcu_reader_qs_gp, LOAD_SHARED(urcu_gp_ctr));
smp_mb();
}
#else /* !(BITS_PER_LONG < 64) */
smp_mb();
}
#else /* !(BITS_PER_LONG < 64) */
This page took
0.023641 seconds
and
4
git commands to generate.