From c4849aeaae0391d9d30ac019684c333889fc06ad Mon Sep 17 00:00:00 2001 From: Samy Al Bahra Date: Sat, 14 Dec 2013 18:33:05 -0500 Subject: [PATCH] ck_epoch: Remove redundant e + 2 observation. This inefficiency was introduced in the overhaul of the ck_epoch API. Synchronize is executed with respect to e. At e + 1, references can only exist to objects logically deleted at e or e + 1. At e + 2, however, references can only exist to objects logically deleted at e + 1 and e + 2. In the case that a thread observes an out of date epoch value, an increment to the global epoch would fail as the active bit is ordered with respect to the memory barrier in synchronize. In the case that a protected section begins after the memory barrier, then it is guaranteed to not acquire the hazardous reference. This does not change granularity of deferral lists, however. There is still a requirement of 3 deferral lists on the fast path (4 in ck_epoch for fast path purposes) as at any moment, any given deferral list for value e can contain references to objects with active references from both e and e - 1. --- src/ck_epoch.c | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/src/ck_epoch.c b/src/ck_epoch.c index 51016e5..e3f09ae 100644 --- a/src/ck_epoch.c +++ b/src/ck_epoch.c @@ -337,7 +337,7 @@ ck_epoch_synchronize(struct ck_epoch *global, struct ck_epoch_record *record) * we are at a grace period. */ if (active == false) - goto leave; + break; /* * Increment current epoch. CAS semantics are used to eliminate @@ -364,34 +364,10 @@ reload: * generation. We can actually avoid an addtional scan step * at this point. */ - goto leave; - } - } - - /* - * At this point, we are at e + 2. If all threads have observed - * this epoch value, then no threads are at e + 1 and no references - * could exist to the snapshot of e observed at the time this - * function was called. - */ - while (cr = ck_epoch_scan(global, cr, delta, &active), cr != NULL) { - ck_pr_stall(); - - /* - * If the epoch value was changed from underneath us then - * our epoch must have been observed at some point. - * - * If all threads have gone inactive, we are also at a grace - * period as any reads succeeding this call to synchronize - * will imply a full memory barrier (logically deleted objects - * will not be visible). - */ - epoch = ck_pr_load_uint(&global->epoch); - if ((epoch != delta) | (active == false)) break; + } } -leave: record->epoch = delta; return; }