- // <hti->scan> might be larger than the size of the table, if some thread stalls while
- // copying. In that case we just wrap around to the begining and make another pass through
- // the table.
- volatile entry_t *e = hti->table + (x & MASK(hti->scale));
+ TRACE("h0", "ht_compare_and_set: help copy. scan is %llu, size is %llu", x, 1<<hti->scale);
+ // Panic if we've been around the array twice and still haven't finished the copy.
+ int panic = (x >= (1 << (hti->scale + 1)));
+ if (!panic) {
+ limit = ENTRIES_PER_COPY_CHUNK;
+
+ // Reserve some entries for this thread to copy. There is a race condition here because the
+ // fetch and add isn't atomic, but that is ok.
+ hti->scan = x + ENTRIES_PER_COPY_CHUNK;
+
+ // <hti->scan> might be larger than the size of the table, if some thread stalls while
+ // copying. In that case we just wrap around to the begining and make another pass through
+ // the table.
+ e = hti->table + (x & MASK(hti->scale));
+ } else {
+ TRACE("h0", "ht_compare_and_set: help copy panic", 0, 0);
+ // scan the whole table
+ limit = (1 << hti->scale);
+ e = hti->table;
+ }