mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 23:18:21 +00:00
pushlock: fix code
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
#include <pushlock.h>
|
#include <pushlock.h>
|
||||||
|
#include <logging.h>
|
||||||
#define DO_CAS(ptr, saved, new) \
|
#define DO_CAS(ptr, saved, new) \
|
||||||
__atomic_compare_exchange_n(ptr, &saved, new, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
|
__atomic_compare_exchange_n(ptr, &saved, new, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
|
||||||
|
|
||||||
bool pushlock_try_acquire_exclusive(pushlock_t *pushlock) {
|
bool pushlock_try_acquire_exclusive(pushlock_t *pushlock) {
|
||||||
pushlock_t saved_value = *pushlock;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
pushlock_t saved_value = *pushlock;
|
||||||
if ((PUSHLOCK_FLAGS_ACQUIRED & saved_value) == 0) {
|
if ((PUSHLOCK_FLAGS_ACQUIRED & saved_value) == 0) {
|
||||||
if (DO_CAS(pushlock, saved_value, saved_value | PUSHLOCK_FLAGS_ACQUIRED | PUSHLOCK_FLAGS_EXCLUSIVE))
|
if (DO_CAS(pushlock, saved_value, saved_value | PUSHLOCK_FLAGS_ACQUIRED | PUSHLOCK_FLAGS_EXCLUSIVE))
|
||||||
return true;
|
return true;
|
||||||
@@ -18,8 +18,8 @@ bool pushlock_try_acquire_exclusive(pushlock_t *pushlock) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pushlock_acquire_exclusive(pushlock_t *pushlock) {
|
void pushlock_acquire_exclusive(pushlock_t *pushlock) {
|
||||||
pushlock_t saved_value = *pushlock;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
pushlock_t saved_value = *pushlock;
|
||||||
if ((PUSHLOCK_FLAGS_ACQUIRED & saved_value) == 0) {
|
if ((PUSHLOCK_FLAGS_ACQUIRED & saved_value) == 0) {
|
||||||
if (DO_CAS(pushlock, saved_value, saved_value | PUSHLOCK_FLAGS_ACQUIRED | PUSHLOCK_FLAGS_EXCLUSIVE))
|
if (DO_CAS(pushlock, saved_value, saved_value | PUSHLOCK_FLAGS_ACQUIRED | PUSHLOCK_FLAGS_EXCLUSIVE))
|
||||||
return;
|
return;
|
||||||
@@ -27,7 +27,6 @@ void pushlock_acquire_exclusive(pushlock_t *pushlock) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pushlock_wait_block_t wait_block;
|
pushlock_wait_block_t wait_block;
|
||||||
SEMAPHORE_INIT(&wait_block.semaphore, 0);
|
SEMAPHORE_INIT(&wait_block.semaphore, 0);
|
||||||
|
|
||||||
@@ -45,8 +44,8 @@ void pushlock_acquire_exclusive(pushlock_t *pushlock) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool pushlock_try_acquire_shared(pushlock_t *pushlock) {
|
bool pushlock_try_acquire_shared(pushlock_t *pushlock) {
|
||||||
pushlock_t saved_value = *pushlock;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
pushlock_t saved_value = *pushlock;
|
||||||
if ((saved_value & PUSHLOCK_FLAGS_ACQUIRED) == 0 || (saved_value & PUSHLOCK_FLAGS_EXCLUSIVE) == 0) {
|
if ((saved_value & PUSHLOCK_FLAGS_ACQUIRED) == 0 || (saved_value & PUSHLOCK_FLAGS_EXCLUSIVE) == 0) {
|
||||||
if (saved_value & PUSHLOCK_FLAGS_CONTENDED) {
|
if (saved_value & PUSHLOCK_FLAGS_CONTENDED) {
|
||||||
// if its contended, we will try to acquire it as an exclusive lock
|
// if its contended, we will try to acquire it as an exclusive lock
|
||||||
@@ -68,8 +67,8 @@ bool pushlock_try_acquire_shared(pushlock_t *pushlock) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pushlock_acquire_shared(pushlock_t *pushlock) {
|
void pushlock_acquire_shared(pushlock_t *pushlock) {
|
||||||
pushlock_t saved_value = *pushlock;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
pushlock_t saved_value = *pushlock;
|
||||||
if ((saved_value & PUSHLOCK_FLAGS_ACQUIRED) == 0 || (saved_value & PUSHLOCK_FLAGS_EXCLUSIVE) == 0) {
|
if ((saved_value & PUSHLOCK_FLAGS_ACQUIRED) == 0 || (saved_value & PUSHLOCK_FLAGS_EXCLUSIVE) == 0) {
|
||||||
if (saved_value & PUSHLOCK_FLAGS_CONTENDED) {
|
if (saved_value & PUSHLOCK_FLAGS_CONTENDED) {
|
||||||
// if its contended, we will try to acquire it as an exclusive lock
|
// if its contended, we will try to acquire it as an exclusive lock
|
||||||
@@ -100,8 +99,12 @@ void pushlock_acquire_shared(pushlock_t *pushlock) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pushlock_release(pushlock_t *pushlock) {
|
void pushlock_release(pushlock_t *pushlock) {
|
||||||
pushlock_t saved_value = *pushlock;
|
pushlock_t saved_value;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
saved_value = *pushlock;
|
||||||
|
#ifdef DEBUG_LOCKS
|
||||||
|
__assert(saved_value & PUSHLOCK_FLAGS_ACQUIRED);
|
||||||
|
#endif
|
||||||
if ((saved_value & PUSHLOCK_FLAGS_CONTENDED) == 0) {
|
if ((saved_value & PUSHLOCK_FLAGS_CONTENDED) == 0) {
|
||||||
if ((saved_value & PUSHLOCK_FLAGS_EXCLUSIVE) == 0 && PUSHLOCK_GET_SHARED_COUNT(saved_value) > 1) {
|
if ((saved_value & PUSHLOCK_FLAGS_EXCLUSIVE) == 0 && PUSHLOCK_GET_SHARED_COUNT(saved_value) > 1) {
|
||||||
// shared lock with 2 or more holders, decrement shared count
|
// shared lock with 2 or more holders, decrement shared count
|
||||||
@@ -123,7 +126,11 @@ void pushlock_release(pushlock_t *pushlock) {
|
|||||||
// last and penultimate ones
|
// last and penultimate ones
|
||||||
bool skip_check = false;
|
bool skip_check = false;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
saved_value = *pushlock;
|
||||||
pushlock_wait_block_t *prev = NULL, *last = PUSHLOCK_GET_POINTER(saved_value);
|
pushlock_wait_block_t *prev = NULL, *last = PUSHLOCK_GET_POINTER(saved_value);
|
||||||
|
#ifdef DEBUG_LOCKS
|
||||||
|
__assert(last);
|
||||||
|
#endif
|
||||||
while (last->next != NULL) {
|
while (last->next != NULL) {
|
||||||
prev = last;
|
prev = last;
|
||||||
last = last->next;
|
last = last->next;
|
||||||
@@ -147,6 +154,7 @@ void pushlock_release(pushlock_t *pushlock) {
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
if (DO_CAS(pushlock, saved_value, (uintptr_t)PUSHLOCK_GET_POINTER(saved_value) | PUSHLOCK_FLAGS_CONTENDED))
|
if (DO_CAS(pushlock, saved_value, (uintptr_t)PUSHLOCK_GET_POINTER(saved_value) | PUSHLOCK_FLAGS_CONTENDED))
|
||||||
break;
|
break;
|
||||||
|
saved_value = *pushlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user