// unlock of pred can see me in the tail before I fill next
// publish me to previous lock-holder :
- // FIXME: detection miss
+ // FIXME: detection miss, don't think it's necessary
pred->next.store(me, std::mo_release );
// (*2) pred not touched any more
void unlock(guard * I) {
mcs_node * me = &(I->m_node);
- // FIXME: detection miss
+ // FIXME: detection miss, don't think it's necessary
mcs_node * next = me->next.load(std::mo_acquire);
if ( next == NULL )
{
// (*1) catch the race :
rl::linear_backoff bo;
for(;;) {
- // FIXME: detection miss
+ // FIXME: detection miss, don't think it's necessary
next = me->next.load(std::mo_acquire);
if ( next != NULL )
break;
#define acquire memory_order_acquire
#define MAX_FREELIST 4 /* Each thread can own up to MAX_FREELIST free nodes */
-#define INITIAL_FREE 2 /* Each thread starts with INITIAL_FREE free nodes */
+#define INITIAL_FREE 3 /* Each thread starts with INITIAL_FREE free nodes */
#define POISON_IDX 0x666
*/
}
if (!success) {
+ // This routine helps the other enqueue to update the tail
/****FIXME: detected UL ****/
unsigned int ptr = get_ptr(atomic_load_explicit(&q->nodes[get_ptr(tail)].next, acquire));
pointer value = MAKE_POINTER(ptr,
get_count(tail) + 1);
/****FIXME: miss ****/
// Seconde release can be just relaxed
- atomic_compare_exchange_strong_explicit(&q->tail,
+ bool succ = false;
+ succ = atomic_compare_exchange_strong_explicit(&q->tail,
&tail, value, release, relaxed);
+ if (succ) {
+ printf("miss2_enqueue CAS succ\n");
+ }
printf("miss2_enqueue\n");
thrd_yield();
}
}
}
/****FIXME: first UL ****/
- // Seconde release can be just relaxed
+ // Second release can be just relaxed
atomic_compare_exchange_strong_explicit(&q->tail,
&tail,
MAKE_POINTER(node, get_count(tail) + 1),
}
/****FIXME: miss (not reached) ****/
// Seconde release can be just relaxed
- atomic_compare_exchange_strong_explicit(&q->tail,
+ bool succ = false;
+ succ = atomic_compare_exchange_strong_explicit(&q->tail,
&tail,
MAKE_POINTER(get_ptr(next), get_count(tail) + 1),
release, relaxed);
+ if (succ) {
+ printf("miss4_dequeue CAS succ\n");
+ }
printf("miss4_dequeue\n");
thrd_yield();
} else {
}
@DefineFunc:
call_id_t get_id(void *wrapper) {
+ if (wrapper == NULL)
+ return 0;
return ((tag_elem_t*) wrapper)->id;
}
@DefineFunc:
@Commit_point_set: Dequeue_Success_Point | Dequeue_Empty_Point
@ID: get_id(front(__queue))
@Action:
- unsigned int _Old_Val = get_data(front(__queue));
- pop_front(__queue);
+ unsigned int _Old_Val = 0;
+ if (size(__queue) > 0) {
+ _Old_Val = get_data(front(__queue));
+ pop_front(__queue);
+ } else {
+ _Old_Val = 0;
+ }
@Post_check:
_Old_Val == __RET__
@End