Skip to content

Commit b04e607

Browse files
author
Marcus Watts
committed
Reduce sentinel comparisons
1 parent ad64174 commit b04e607

File tree

2 files changed

+22
-10
lines changed

2 files changed

+22
-10
lines changed

Diff for: skip_adt_test.c

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ harness_ulong_comp(const void *lhs, const void *rhs)
5454
l = (harness_ulong_t *) lhs;
5555
r = (harness_ulong_t *) rhs;
5656

57+
#if 0
5758
/* todo: move to wrapper macro outside
5859
* cmpf */
5960

@@ -67,6 +68,7 @@ harness_ulong_comp(const void *lhs, const void *rhs)
6768
if (rhs == SENTINEL_KEYMIN)
6869
return (1);
6970
/* end todo */
71+
#endif
7072

7173
if (l->key == r->key)
7274
return (0);

Diff for: skip_cas_adt.c

+20-10
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,9 @@ struct set_st {
8686
CACHE_PAD(0);
8787
osi_set_cmp_func cmpf;
8888
CACHE_PAD(1);
89-
node_t head;
89+
node_t *tail;
9090
CACHE_PAD(2);
91+
node_t head;
9192
};
9293

9394
/*
@@ -179,6 +180,7 @@ strong_search_predecessors(osi_set_t * l, setkey_t k, sh_node_pt * pa,
179180
y = get_unmarked_ref(y_next);
180181
}
181182

183+
if (y == l->tail) break;
182184
READ_FIELD(y_k, y->k);
183185
if (compare_keys(l, y_k, k) >= 0)
184186
break;
@@ -220,6 +222,7 @@ weak_search_predecessors(osi_set_t * l, setkey_t k, sh_node_pt * pa,
220222
READ_FIELD(x_next, x->next[i]);
221223
x_next = get_unmarked_ref(x_next);
222224

225+
if (x_next == l->tail) break;
223226
READ_FIELD(x_next_k, x_next->k);
224227
if (compare_keys(l, x_next_k, k) >= 0)
225228
break;
@@ -285,7 +288,9 @@ do_full_delete(ptst_t * ptst, osi_set_t * l, sh_node_pt x, int level)
285288
RMB();
286289
while (i > 0) {
287290
node_t *n = get_unmarked_ref(preds[i]->next[i]);
288-
while (compare_keys(l, n->k, k) < 0) {
291+
for (;;) {
292+
if (n == l->tail) break;
293+
if (compare_keys(l, n->k, k) >= 0) break;
289294
n = get_unmarked_ref(n->next[i]);
290295
RMB(); /* we don't want refs to @x to "disappear" */
291296
}
@@ -335,9 +340,13 @@ osi_cas_skip_alloc(osi_set_cmp_func cmpf)
335340
{
336341
osi_set_t *l;
337342
node_t *n;
343+
char *cp;
338344
int i;
339345

340-
n = malloc(sizeof(*n) + (NUM_LEVELS - 1) * sizeof(node_t *));
346+
cp = malloc(sizeof(*l) + (NUM_LEVELS - 1) * sizeof(node_t *)
347+
+ sizeof(*n) + (NUM_LEVELS - 1) * sizeof(node_t *));
348+
n = (node_t *) (cp + sizeof(*l) + (NUM_LEVELS - 1) * sizeof(node_t *));
349+
l = (osi_set_t *) (cp);
341350
memset(n, 0, sizeof(*n) + (NUM_LEVELS - 1) * sizeof(node_t *));
342351
n->k = SENTINEL_KEYMAX;
343352

@@ -348,7 +357,7 @@ osi_cas_skip_alloc(osi_set_cmp_func cmpf)
348357
*/
349358
memset(n->next, 0xfe, NUM_LEVELS * sizeof(node_t *));
350359

351-
l = malloc(sizeof(*l) + (NUM_LEVELS - 1) * sizeof(node_t *));
360+
l->tail = n;
352361
l->cmpf = cmpf;
353362
l->head.k = SENTINEL_KEYMIN;
354363
l->head.level = NUM_LEVELS;
@@ -376,7 +385,7 @@ osi_cas_skip_update(gc_global_t *gc_global, osi_set_t * l, setkey_t k, setval_t
376385
retry:
377386
ov = NULL;
378387

379-
if (compare_keys(l, succ->k, k) == 0) {
388+
if (succ != l->tail && compare_keys(l, succ->k, k) == 0) {
380389
// if (new && new == succ) {
381390
// printf("%p already added: %p %p\n", pthread_self(), preds[0], succs[0]);
382391
// }
@@ -446,12 +455,13 @@ osi_cas_skip_update(gc_global_t *gc_global, osi_set_t * l, setkey_t k, setval_t
446455
}
447456

448457
/* Ensure we have unique key values at every level. */
449-
if (compare_keys(l, succ->k, k) == 0) {
458+
if (succ != l->tail && compare_keys(l, succ->k, k) == 0) {
450459
goto new_world_view;
451460
}
452461

453-
assert((compare_keys(l, pred->k, k) < 0) &&
454-
(compare_keys(l, succ->k, k) > 0));
462+
assert( pred != l->tail && succ != &l->head &&
463+
( pred == &l->head || compare_keys(l, pred->k, k) < 0) &&
464+
( succ == l->tail || compare_keys(l, succ->k, k) > 0));
455465

456466
/* Replumb predecessor's forward pointer. */
457467
old_next = CASPO(&pred->next[i], succ, new);
@@ -489,7 +499,7 @@ osi_cas_skip_remove(gc_global_t *gc_global, osi_set_t * l, setkey_t k)
489499
ptst = critical_enter(gc_global);
490500

491501
x = weak_search_predecessors(l, k, preds, NULL);
492-
if (compare_keys(l, x->k, k) > 0)
502+
if (x == l->tail || compare_keys(l, x->k, k) > 0)
493503
goto out;
494504

495505
READ_FIELD(level, x->level);
@@ -542,7 +552,7 @@ osi_cas_skip_lookup(gc_global_t *gc_global, osi_set_t * l, setkey_t k)
542552
ptst = critical_enter(gc_global);
543553

544554
x = weak_search_predecessors(l, k, NULL, NULL);
545-
if (compare_keys(l, x->k, k) == 0)
555+
if (x != l->tail && compare_keys(l, x->k, k) == 0)
546556
READ_FIELD(v, x->v);
547557

548558
critical_exit(ptst);

0 commit comments

Comments
 (0)