ck_spinlock: Switch to full semantics across all implementations.

More importantly, trylock previously didn't have full semantics.
ck_pring
Samy Al Bahra 13 years ago
parent e40521d1aa
commit 65ebf86799

@ -191,6 +191,9 @@ ck_spinlock_fas_trylock(struct ck_spinlock_fas *lock)
bool value; bool value;
value = ck_pr_fas_uint(&lock->value, true); value = ck_pr_fas_uint(&lock->value, true);
if (value == false)
ck_pr_fence_memory();
return (!value); return (!value);
} }
@ -210,6 +213,7 @@ ck_spinlock_fas_lock(struct ck_spinlock_fas *lock)
ck_pr_stall(); ck_pr_stall();
} }
ck_pr_fence_memory();
return; return;
} }
@ -221,6 +225,7 @@ ck_spinlock_fas_lock_eb(struct ck_spinlock_fas *lock)
while (ck_pr_fas_uint(&lock->value, true) == true) while (ck_pr_fas_uint(&lock->value, true) == true)
ck_backoff_eb(&backoff); ck_backoff_eb(&backoff);
ck_pr_fence_memory();
return; return;
} }
@ -260,6 +265,9 @@ ck_spinlock_cas_trylock(struct ck_spinlock_cas *lock)
unsigned int value; unsigned int value;
value = ck_pr_fas_uint(&lock->value, true); value = ck_pr_fas_uint(&lock->value, true);
if (value == false)
ck_pr_fence_memory();
return (!value); return (!value);
} }
@ -279,6 +287,7 @@ ck_spinlock_cas_lock(struct ck_spinlock_cas *lock)
ck_pr_stall(); ck_pr_stall();
} }
ck_pr_fence_memory();
return; return;
} }
@ -290,6 +299,7 @@ ck_spinlock_cas_lock_eb(struct ck_spinlock_cas *lock)
while (ck_pr_cas_uint(&lock->value, false, true) == false) while (ck_pr_cas_uint(&lock->value, false, true) == false)
ck_backoff_eb(&backoff); ck_backoff_eb(&backoff);
ck_pr_fence_memory();
return; return;
} }
@ -324,8 +334,12 @@ ck_spinlock_dec_trylock(struct ck_spinlock_dec *lock)
unsigned int value; unsigned int value;
value = ck_pr_fas_uint(&lock->value, 0); value = ck_pr_fas_uint(&lock->value, 0);
ck_pr_fence_store(); if (value == 1) {
return (value == 1); ck_pr_fence_memory();
return true;
}
return false;
} }
CK_CC_INLINE static bool CK_CC_INLINE static bool
@ -347,6 +361,7 @@ ck_spinlock_dec_lock(struct ck_spinlock_dec *lock)
* UINT_MAX lock requests can happen while the lock is held. * UINT_MAX lock requests can happen while the lock is held.
*/ */
ck_pr_dec_uint_zero(&lock->value, &r); ck_pr_dec_uint_zero(&lock->value, &r);
ck_pr_fence_memory();
if (r == true) if (r == true)
break; break;
@ -372,6 +387,7 @@ ck_spinlock_dec_lock_eb(struct ck_spinlock_dec *lock)
ck_backoff_eb(&backoff); ck_backoff_eb(&backoff);
} }
ck_pr_fence_memory();
return; return;
} }
@ -428,6 +444,7 @@ ck_spinlock_ticket_lock(struct ck_spinlock_ticket *ticket)
while (ck_pr_load_uint(&ticket->position) != request) while (ck_pr_load_uint(&ticket->position) != request)
ck_pr_stall(); ck_pr_stall();
ck_pr_fence_memory();
return; return;
} }
@ -457,6 +474,7 @@ ck_spinlock_ticket_lock_pb(struct ck_spinlock_ticket *ticket)
ck_backoff_eb(&backoff); ck_backoff_eb(&backoff);
} }
ck_pr_fence_memory();
return; return;
} }
@ -508,7 +526,12 @@ ck_spinlock_mcs_trylock(struct ck_spinlock_mcs **queue, struct ck_spinlock_mcs *
ck_pr_store_ptr(&node->next, NULL); ck_pr_store_ptr(&node->next, NULL);
ck_pr_fence_store(); ck_pr_fence_store();
return ck_pr_cas_ptr(queue, NULL, node); if (ck_pr_cas_ptr(queue, NULL, node) == true) {
ck_pr_fence_load();
return true;
}
return false;
} }
CK_CC_INLINE static bool CK_CC_INLINE static bool
@ -535,6 +558,7 @@ ck_spinlock_mcs_lock(struct ck_spinlock_mcs **queue, struct ck_spinlock_mcs *nod
* returns NULL, it means the queue was empty. If the queue was empty, * returns NULL, it means the queue was empty. If the queue was empty,
* then the operation is complete. * then the operation is complete.
*/ */
ck_pr_fence_memory();
previous = ck_pr_fas_ptr(queue, node); previous = ck_pr_fas_ptr(queue, node);
if (previous == NULL) if (previous == NULL)
return; return;
@ -560,8 +584,10 @@ ck_spinlock_mcs_unlock(struct ck_spinlock_mcs **queue, struct ck_spinlock_mcs *n
* mark the spinlock queue as empty. * mark the spinlock queue as empty.
*/ */
if (ck_pr_load_ptr(queue) == node && if (ck_pr_load_ptr(queue) == node &&
ck_pr_cas_ptr(queue, node, NULL) == true) ck_pr_cas_ptr(queue, node, NULL) == true) {
ck_pr_fence_memory();
return; return;
}
/* /*
* If the node is not the current tail then a lock operation is * If the node is not the current tail then a lock operation is

Loading…
Cancel
Save