ck_proxy: Add support for recursive epoch sections.

Note that the global epoch won't tick over until the
parent epoch section has completed.
ck_pring
Samy Al Bahra 14 years ago
parent b5755888fc
commit 0f48b6fe7a

@ -176,7 +176,7 @@ ck_epoch_tick(struct ck_epoch *global, struct ck_epoch_record *record)
c_record == record) c_record == record)
continue; continue;
if (ck_pr_load_uint(&c_record->active) == true && if (ck_pr_load_uint(&c_record->active) != 0 &&
ck_pr_load_uint(&c_record->epoch) != g_epoch) ck_pr_load_uint(&c_record->epoch) != g_epoch)
return; return;
} }
@ -221,9 +221,16 @@ ck_epoch_write_begin(struct ck_epoch_record *record)
{ {
struct ck_epoch *global = record->global; struct ck_epoch *global = record->global;
ck_pr_store_uint(&record->active, 1); ck_pr_store_uint(&record->active, record->active + 1);
ck_pr_fence_store(); ck_pr_fence_store();
/*
* In the case of recursive write sections, avoid ticking
* over global epoch.
*/
if (record->active > 1)
return;
for (;;) { for (;;) {
if (ck_epoch_reclaim(record) == true) if (ck_epoch_reclaim(record) == true)
break; break;
@ -243,11 +250,18 @@ ck_epoch_write_begin(struct ck_epoch_record *record)
CK_CC_INLINE static void CK_CC_INLINE static void
ck_epoch_read_begin(struct ck_epoch_record *record) ck_epoch_read_begin(struct ck_epoch_record *record)
{ {
unsigned int g_epoch = ck_pr_load_uint(&record->global->epoch);
g_epoch &= CK_EPOCH_LENGTH - 1; /*
ck_pr_store_uint(&record->epoch, g_epoch); * Only observe new epoch if thread is not recursing into a read
ck_pr_store_uint(&record->active, 1); * section.
*/
if (record->active == 0) {
unsigned int g_epoch = ck_pr_load_uint(&record->global->epoch);
g_epoch &= CK_EPOCH_LENGTH - 1;
ck_pr_store_uint(&record->epoch, g_epoch);
}
ck_pr_store_uint(&record->active, record->active + 1);
ck_pr_fence_store(); ck_pr_fence_store();
return; return;
} }
@ -257,7 +271,7 @@ ck_epoch_end(struct ck_epoch_record *record)
{ {
ck_pr_fence_store(); ck_pr_fence_store();
ck_pr_store_uint(&record->active, 0); ck_pr_store_uint(&record->active, record->active - 1);
return; return;
} }

Loading…
Cancel
Save