@@ -86,8 +86,9 @@ struct set_st {
86
86
CACHE_PAD (0 );
87
87
osi_set_cmp_func cmpf ;
88
88
CACHE_PAD (1 );
89
- node_t head ;
89
+ node_t * tail ;
90
90
CACHE_PAD (2 );
91
+ node_t head ;
91
92
};
92
93
93
94
/*
@@ -179,6 +180,7 @@ strong_search_predecessors(osi_set_t * l, setkey_t k, sh_node_pt * pa,
179
180
y = get_unmarked_ref (y_next );
180
181
}
181
182
183
+ if (y == l -> tail ) break ;
182
184
READ_FIELD (y_k , y -> k );
183
185
if (compare_keys (l , y_k , k ) >= 0 )
184
186
break ;
@@ -220,6 +222,7 @@ weak_search_predecessors(osi_set_t * l, setkey_t k, sh_node_pt * pa,
220
222
READ_FIELD (x_next , x -> next [i ]);
221
223
x_next = get_unmarked_ref (x_next );
222
224
225
+ if (x_next == l -> tail ) break ;
223
226
READ_FIELD (x_next_k , x_next -> k );
224
227
if (compare_keys (l , x_next_k , k ) >= 0 )
225
228
break ;
@@ -285,7 +288,9 @@ do_full_delete(ptst_t * ptst, osi_set_t * l, sh_node_pt x, int level)
285
288
RMB ();
286
289
while (i > 0 ) {
287
290
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 ;
289
294
n = get_unmarked_ref (n -> next [i ]);
290
295
RMB (); /* we don't want refs to @x to "disappear" */
291
296
}
@@ -335,9 +340,13 @@ osi_cas_skip_alloc(osi_set_cmp_func cmpf)
335
340
{
336
341
osi_set_t * l ;
337
342
node_t * n ;
343
+ char * cp ;
338
344
int i ;
339
345
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 );
341
350
memset (n , 0 , sizeof (* n ) + (NUM_LEVELS - 1 ) * sizeof (node_t * ));
342
351
n -> k = SENTINEL_KEYMAX ;
343
352
@@ -348,7 +357,7 @@ osi_cas_skip_alloc(osi_set_cmp_func cmpf)
348
357
*/
349
358
memset (n -> next , 0xfe , NUM_LEVELS * sizeof (node_t * ));
350
359
351
- l = malloc ( sizeof ( * l ) + ( NUM_LEVELS - 1 ) * sizeof ( node_t * )) ;
360
+ l -> tail = n ;
352
361
l -> cmpf = cmpf ;
353
362
l -> head .k = SENTINEL_KEYMIN ;
354
363
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
376
385
retry :
377
386
ov = NULL ;
378
387
379
- if (compare_keys (l , succ -> k , k ) == 0 ) {
388
+ if (succ != l -> tail && compare_keys (l , succ -> k , k ) == 0 ) {
380
389
// if (new && new == succ) {
381
390
// printf("%p already added: %p %p\n", pthread_self(), preds[0], succs[0]);
382
391
// }
@@ -446,12 +455,13 @@ osi_cas_skip_update(gc_global_t *gc_global, osi_set_t * l, setkey_t k, setval_t
446
455
}
447
456
448
457
/* 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 ) {
450
459
goto new_world_view ;
451
460
}
452
461
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 ));
455
465
456
466
/* Replumb predecessor's forward pointer. */
457
467
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)
489
499
ptst = critical_enter (gc_global );
490
500
491
501
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 )
493
503
goto out ;
494
504
495
505
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)
542
552
ptst = critical_enter (gc_global );
543
553
544
554
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 )
546
556
READ_FIELD (v , x -> v );
547
557
548
558
critical_exit (ptst );
0 commit comments