mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-12 14:09:12 +00:00
Clean up more code
The *NSYNC linked list API is good enough that it deserves to be part of the C libray, so this change writes an improved version of it which uses that offsetof() trick from the Linux Kernel. We vendor all of the *NSYNC tests in third_party which helped confirm the needed refactoring is safe This change also deletes more old code that didn't pan out. My goal here is to work towards a vision where the Cosmopolitan core libraries become less experimental and more focused on curation. This better reflects the current level of quality we've managed to achieve.
This commit is contained in:
parent
88612a2cd7
commit
0a24b4fc3c
268 changed files with 632 additions and 8688 deletions
2
third_party/nsync/mem/array.c
vendored
2
third_party/nsync/mem/array.c
vendored
|
@ -39,7 +39,7 @@ void a_ensure_ (void *v, int delta, int sz) {
|
|||
} else {
|
||||
na = realloc (a->a_, nmax*sz);
|
||||
}
|
||||
memset (omax *sz + (char *)na, 0, (nmax - omax) * sz);
|
||||
bzero (omax *sz + (char *)na, (nmax - omax) * sz);
|
||||
a->a_ = (void **) na;
|
||||
a->h_.max_ = nmax;
|
||||
}
|
||||
|
|
18
third_party/nsync/mem/nsync_counter.c
vendored
18
third_party/nsync/mem/nsync_counter.c
vendored
|
@ -15,13 +15,13 @@
|
|||
│ See the License for the specific language governing permissions and │
|
||||
│ limitations under the License. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/dll.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/nsync/atomic.h"
|
||||
#include "third_party/nsync/atomic.internal.h"
|
||||
#include "third_party/nsync/common.internal.h"
|
||||
#include "third_party/nsync/counter.h"
|
||||
#include "third_party/nsync/dll.h"
|
||||
#include "third_party/nsync/mu_semaphore.h"
|
||||
#include "third_party/nsync/races.internal.h"
|
||||
#include "third_party/nsync/wait_s.internal.h"
|
||||
|
@ -38,13 +38,13 @@ struct nsync_counter_s_ {
|
|||
nsync_atomic_uint32_ waited; /* wait has been called */
|
||||
nsync_mu counter_mu; /* protects fields below except reads of "value" */
|
||||
nsync_atomic_uint32_ value; /* value of counter */
|
||||
struct nsync_dll_element_s_ *waiters; /* list of waiters */
|
||||
struct Dll *waiters; /* list of waiters */
|
||||
};
|
||||
|
||||
nsync_counter nsync_counter_new (uint32_t value) {
|
||||
nsync_counter c = (nsync_counter) malloc (sizeof (*c));
|
||||
if (c != NULL) {
|
||||
memset ((void *) c, 0, sizeof (*c));
|
||||
bzero ((void *) c, sizeof (*c));
|
||||
ATM_STORE (&c->value, value);
|
||||
}
|
||||
return (c);
|
||||
|
@ -52,7 +52,7 @@ nsync_counter nsync_counter_new (uint32_t value) {
|
|||
|
||||
void nsync_counter_free (nsync_counter c) {
|
||||
nsync_mu_lock (&c->counter_mu);
|
||||
ASSERT (nsync_dll_is_empty_ (c->waiters));
|
||||
ASSERT (dll_is_empty (c->waiters));
|
||||
nsync_mu_unlock (&c->counter_mu);
|
||||
free (c);
|
||||
}
|
||||
|
@ -77,10 +77,10 @@ uint32_t nsync_counter_add (nsync_counter c, int32_t delta) {
|
|||
ASSERT (value < value - delta); /* Crash on overflow. */
|
||||
}
|
||||
if (value == 0) {
|
||||
nsync_dll_element_ *p;
|
||||
while ((p = nsync_dll_first_ (c->waiters)) != NULL) {
|
||||
struct Dll *p;
|
||||
while ((p = dll_first (c->waiters)) != NULL) {
|
||||
struct nsync_waiter_s *nw = DLL_NSYNC_WAITER (p);
|
||||
c->waiters = nsync_dll_remove_ (c->waiters, p);
|
||||
dll_remove (&c->waiters, p);
|
||||
ATM_STORE_REL (&nw->waiting, 0);
|
||||
nsync_mu_semaphore_v (nw->sem);
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ static int counter_enqueue (void *v, struct nsync_waiter_s *nw) {
|
|||
nsync_mu_lock (&c->counter_mu);
|
||||
value = ATM_LOAD_ACQ (&c->value);
|
||||
if (value != 0) {
|
||||
c->waiters = nsync_dll_make_last_in_list_ (c->waiters, &nw->q);
|
||||
dll_make_last (&c->waiters, &nw->q);
|
||||
ATM_STORE (&nw->waiting, 1);
|
||||
} else {
|
||||
ATM_STORE (&nw->waiting, 0);
|
||||
|
@ -142,7 +142,7 @@ static int counter_dequeue (void *v, struct nsync_waiter_s *nw) {
|
|||
nsync_mu_lock (&c->counter_mu);
|
||||
value = ATM_LOAD_ACQ (&c->value);
|
||||
if (ATM_LOAD_ACQ (&nw->waiting) != 0) {
|
||||
c->waiters = nsync_dll_remove_ (c->waiters, &nw->q);
|
||||
dll_remove (&c->waiters, &nw->q);
|
||||
ATM_STORE (&nw->waiting, 0);
|
||||
}
|
||||
nsync_mu_unlock (&c->counter_mu);
|
||||
|
|
89
third_party/nsync/mem/nsync_cv.c
vendored
89
third_party/nsync/mem/nsync_cv.c
vendored
|
@ -16,12 +16,12 @@
|
|||
│ limitations under the License. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/cp.internal.h"
|
||||
#include "libc/intrin/dll.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "third_party/nsync/atomic.internal.h"
|
||||
#include "third_party/nsync/common.internal.h"
|
||||
#include "third_party/nsync/cv.h"
|
||||
#include "third_party/nsync/dll.h"
|
||||
#include "third_party/nsync/races.internal.h"
|
||||
#include "third_party/nsync/wait_s.internal.h"
|
||||
#include "third_party/nsync/waiter.h"
|
||||
|
@ -38,7 +38,7 @@ https://github.com/google/nsync\"");
|
|||
|
||||
/* Initialize *cv. */
|
||||
void nsync_cv_init (nsync_cv *cv) {
|
||||
memset ((void *) cv, 0, sizeof (*cv));
|
||||
bzero ((void *) cv, sizeof (*cv));
|
||||
}
|
||||
|
||||
/* Wake the cv waiters in the circular list pointed to by
|
||||
|
@ -46,10 +46,10 @@ void nsync_cv_init (nsync_cv *cv) {
|
|||
nsync_mu, the "wakeup" may consist of transferring the waiters to the nsync_mu's
|
||||
queue. Requires that every waiter is associated with the same mutex.
|
||||
all_readers indicates whether all the waiters on the list are readers. */
|
||||
static void wake_waiters (nsync_dll_list_ to_wake_list, int all_readers) {
|
||||
nsync_dll_element_ *p = NULL;
|
||||
nsync_dll_element_ *next = NULL;
|
||||
nsync_dll_element_ *first_waiter = nsync_dll_first_ (to_wake_list);
|
||||
static void wake_waiters (struct Dll *to_wake_list, int all_readers) {
|
||||
struct Dll *p = NULL;
|
||||
struct Dll *next = NULL;
|
||||
struct Dll *first_waiter = dll_first (to_wake_list);
|
||||
struct nsync_waiter_s *first_nw = DLL_NSYNC_WAITER (first_waiter);
|
||||
waiter *first_w = NULL;
|
||||
nsync_mu *pmu = NULL;
|
||||
|
@ -71,7 +71,7 @@ static void wake_waiters (nsync_dll_list_ to_wake_list, int all_readers) {
|
|||
*/
|
||||
uint32_t old_mu_word = ATM_LOAD (&pmu->word);
|
||||
int first_cant_acquire = ((old_mu_word & first_w->l_type->zero_to_acquire) != 0);
|
||||
next = nsync_dll_next_ (to_wake_list, first_waiter);
|
||||
next = dll_next (to_wake_list, first_waiter);
|
||||
if ((old_mu_word&MU_ANY_LOCK) != 0 &&
|
||||
(old_mu_word&MU_SPINLOCK) == 0 &&
|
||||
(first_cant_acquire || (next != NULL && !all_readers)) &&
|
||||
|
@ -88,8 +88,8 @@ static void wake_waiters (nsync_dll_list_ to_wake_list, int all_readers) {
|
|||
int woke_areader = 0;
|
||||
/* Transfer the first waiter iff it can't acquire *pmu. */
|
||||
if (first_cant_acquire) {
|
||||
to_wake_list = nsync_dll_remove_ (to_wake_list, first_waiter);
|
||||
pmu->waiters = nsync_dll_make_last_in_list_ (pmu->waiters, first_waiter);
|
||||
dll_remove (&to_wake_list, first_waiter);
|
||||
dll_make_last (&pmu->waiters, first_waiter);
|
||||
/* tell nsync_cv_wait_with_deadline() that we
|
||||
moved the waiter to *pmu's queue. */
|
||||
first_w->cv_mu = NULL;
|
||||
|
@ -107,7 +107,7 @@ static void wake_waiters (nsync_dll_list_ to_wake_list, int all_readers) {
|
|||
if ((p_nw->flags & NSYNC_WAITER_FLAG_MUCV) != 0) {
|
||||
p_w = DLL_WAITER (p);
|
||||
}
|
||||
next = nsync_dll_next_ (to_wake_list, p);
|
||||
next = dll_next (to_wake_list, p);
|
||||
p_is_writer = (p_w != NULL &&
|
||||
DLL_WAITER (p)->l_type == nsync_writer_type_);
|
||||
/* We transfer this element if any of:
|
||||
|
@ -117,8 +117,8 @@ static void wake_waiters (nsync_dll_list_ to_wake_list, int all_readers) {
|
|||
if (p_w == NULL) {
|
||||
/* wake non-native waiter */
|
||||
} else if (first_cant_acquire || first_is_writer || p_is_writer) {
|
||||
to_wake_list = nsync_dll_remove_ (to_wake_list, p);
|
||||
pmu->waiters = nsync_dll_make_last_in_list_ (pmu->waiters, p);
|
||||
dll_remove (&to_wake_list, p);
|
||||
dll_make_last (&pmu->waiters, p);
|
||||
/* tell nsync_cv_wait_with_deadline()
|
||||
that we moved the waiter to *pmu's
|
||||
queue. */
|
||||
|
@ -147,10 +147,10 @@ static void wake_waiters (nsync_dll_list_ to_wake_list, int all_readers) {
|
|||
}
|
||||
|
||||
/* Wake any waiters we didn't manage to enqueue on the mu. */
|
||||
for (p = nsync_dll_first_ (to_wake_list); p != NULL; p = next) {
|
||||
for (p = dll_first (to_wake_list); p != NULL; p = next) {
|
||||
struct nsync_waiter_s *p_nw = DLL_NSYNC_WAITER (p);
|
||||
next = nsync_dll_next_ (to_wake_list, p);
|
||||
to_wake_list = nsync_dll_remove_ (to_wake_list, p);
|
||||
next = dll_next (to_wake_list, p);
|
||||
dll_remove (&to_wake_list, p);
|
||||
/* Wake the waiter. */
|
||||
ATM_STORE_REL (&p_nw->waiting, 0); /* release store */
|
||||
nsync_mu_semaphore_v (p_nw->sem);
|
||||
|
@ -239,7 +239,7 @@ int nsync_cv_wait_with_deadline_generic (nsync_cv *pcv, void *pmu,
|
|||
|
||||
/* acquire spinlock, set non-empty */
|
||||
old_word = nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, CV_SPINLOCK|CV_NON_EMPTY, 0);
|
||||
pcv->waiters = nsync_dll_make_last_in_list_ (pcv->waiters, &w->nw.q);
|
||||
dll_make_last (&pcv->waiters, &w->nw.q);
|
||||
remove_count = ATM_LOAD (&w->remove_count);
|
||||
/* Release the spin lock. */
|
||||
ATM_STORE_REL (&pcv->word, old_word|CV_NON_EMPTY); /* release store */
|
||||
|
@ -277,12 +277,11 @@ int nsync_cv_wait_with_deadline_generic (nsync_cv *pcv, void *pmu,
|
|||
queue, and declare a
|
||||
timeout/cancellation. */
|
||||
outcome = sem_outcome;
|
||||
pcv->waiters = nsync_dll_remove_ (pcv->waiters,
|
||||
&w->nw.q);
|
||||
dll_remove (&pcv->waiters, &w->nw.q);
|
||||
do {
|
||||
old_value = ATM_LOAD (&w->remove_count);
|
||||
} while (!ATM_CAS (&w->remove_count, old_value, old_value+1));
|
||||
if (nsync_dll_is_empty_ (pcv->waiters)) {
|
||||
if (dll_is_empty (pcv->waiters)) {
|
||||
old_word &= ~(CV_NON_EMPTY);
|
||||
}
|
||||
ATM_STORE_REL (&w->nw.waiting, 0); /* release store */
|
||||
|
@ -328,27 +327,26 @@ int nsync_cv_wait_with_deadline_generic (nsync_cv *pcv, void *pmu,
|
|||
void nsync_cv_signal (nsync_cv *pcv) {
|
||||
IGNORE_RACES_START ();
|
||||
if ((ATM_LOAD_ACQ (&pcv->word) & CV_NON_EMPTY) != 0) { /* acquire load */
|
||||
nsync_dll_list_ to_wake_list = NULL; /* waiters that we will wake */
|
||||
struct Dll *to_wake_list = NULL; /* waiters that we will wake */
|
||||
int all_readers = 0;
|
||||
/* acquire spinlock */
|
||||
uint32_t old_word = nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK,
|
||||
CV_SPINLOCK, 0);
|
||||
if (!nsync_dll_is_empty_ (pcv->waiters)) {
|
||||
if (!dll_is_empty (pcv->waiters)) {
|
||||
/* Point to first waiter that enqueued itself, and
|
||||
detach it from all others. */
|
||||
struct nsync_waiter_s *first_nw;
|
||||
nsync_dll_element_ *first = nsync_dll_first_ (pcv->waiters);
|
||||
pcv->waiters = nsync_dll_remove_ (pcv->waiters, first);
|
||||
struct Dll *first = dll_first (pcv->waiters);
|
||||
dll_remove (&pcv->waiters, first);
|
||||
first_nw = DLL_NSYNC_WAITER (first);
|
||||
if ((first_nw->flags & NSYNC_WAITER_FLAG_MUCV) != 0) {
|
||||
uint32_t old_value;
|
||||
do {
|
||||
old_value =
|
||||
ATM_LOAD (&DLL_WAITER (first)->remove_count);
|
||||
old_value = ATM_LOAD (&DLL_WAITER (first)->remove_count);
|
||||
} while (!ATM_CAS (&DLL_WAITER (first)->remove_count,
|
||||
old_value, old_value+1));
|
||||
}
|
||||
to_wake_list = nsync_dll_make_last_in_list_ (to_wake_list, first);
|
||||
dll_make_last (&to_wake_list, first);
|
||||
if ((first_nw->flags & NSYNC_WAITER_FLAG_MUCV) != 0 &&
|
||||
DLL_WAITER (first)->l_type == nsync_reader_type_) {
|
||||
int woke_writer;
|
||||
|
@ -363,14 +361,14 @@ void nsync_cv_signal (nsync_cv *pcv) {
|
|||
the condition; the client is expecting only one writer to be
|
||||
able make use of the wakeup, or he would have called
|
||||
nsync_cv_broadcast(). */
|
||||
nsync_dll_element_ *p = NULL;
|
||||
nsync_dll_element_ *next = NULL;
|
||||
struct Dll *p = NULL;
|
||||
struct Dll *next = NULL;
|
||||
all_readers = 1;
|
||||
woke_writer = 0;
|
||||
for (p = nsync_dll_first_ (pcv->waiters); p != NULL; p = next) {
|
||||
for (p = dll_first (pcv->waiters); p != NULL; p = next) {
|
||||
struct nsync_waiter_s *p_nw = DLL_NSYNC_WAITER (p);
|
||||
int should_wake;
|
||||
next = nsync_dll_next_ (pcv->waiters, p);
|
||||
next = dll_next (pcv->waiters, p);
|
||||
should_wake = 0;
|
||||
if ((p_nw->flags & NSYNC_WAITER_FLAG_MUCV) != 0 &&
|
||||
DLL_WAITER (p)->l_type == nsync_reader_type_) {
|
||||
|
@ -381,7 +379,7 @@ void nsync_cv_signal (nsync_cv *pcv) {
|
|||
should_wake = 1;
|
||||
}
|
||||
if (should_wake) {
|
||||
pcv->waiters = nsync_dll_remove_ (pcv->waiters, p);
|
||||
dll_remove (&pcv->waiters, p);
|
||||
if ((p_nw->flags & NSYNC_WAITER_FLAG_MUCV) != 0) {
|
||||
uint32_t old_value;
|
||||
do {
|
||||
|
@ -390,18 +388,17 @@ void nsync_cv_signal (nsync_cv *pcv) {
|
|||
} while (!ATM_CAS (&DLL_WAITER (p)->remove_count,
|
||||
old_value, old_value+1));
|
||||
}
|
||||
to_wake_list = nsync_dll_make_last_in_list_ (
|
||||
to_wake_list, p);
|
||||
dll_make_last (&to_wake_list, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nsync_dll_is_empty_ (pcv->waiters)) {
|
||||
if (dll_is_empty (pcv->waiters)) {
|
||||
old_word &= ~(CV_NON_EMPTY);
|
||||
}
|
||||
}
|
||||
/* Release spinlock. */
|
||||
ATM_STORE_REL (&pcv->word, old_word); /* release store */
|
||||
if (!nsync_dll_is_empty_ (to_wake_list)) {
|
||||
if (!dll_is_empty (to_wake_list)) {
|
||||
wake_waiters (to_wake_list, all_readers);
|
||||
}
|
||||
}
|
||||
|
@ -412,22 +409,22 @@ void nsync_cv_signal (nsync_cv *pcv) {
|
|||
void nsync_cv_broadcast (nsync_cv *pcv) {
|
||||
IGNORE_RACES_START ();
|
||||
if ((ATM_LOAD_ACQ (&pcv->word) & CV_NON_EMPTY) != 0) { /* acquire load */
|
||||
nsync_dll_element_ *p;
|
||||
nsync_dll_element_ *next;
|
||||
struct Dll *p;
|
||||
struct Dll *next;
|
||||
int all_readers;
|
||||
nsync_dll_list_ to_wake_list = NULL; /* waiters that we will wake */
|
||||
struct Dll *to_wake_list = NULL; /* waiters that we will wake */
|
||||
/* acquire spinlock */
|
||||
nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, CV_SPINLOCK, 0);
|
||||
p = NULL;
|
||||
next = NULL;
|
||||
all_readers = 1;
|
||||
/* Wake entire waiter list, which we leave empty. */
|
||||
for (p = nsync_dll_first_ (pcv->waiters); p != NULL; p = next) {
|
||||
for (p = dll_first (pcv->waiters); p != NULL; p = next) {
|
||||
struct nsync_waiter_s *p_nw = DLL_NSYNC_WAITER (p);
|
||||
next = nsync_dll_next_ (pcv->waiters, p);
|
||||
next = dll_next (pcv->waiters, p);
|
||||
all_readers = all_readers && (p_nw->flags & NSYNC_WAITER_FLAG_MUCV) != 0 &&
|
||||
(DLL_WAITER (p)->l_type == nsync_reader_type_);
|
||||
pcv->waiters = nsync_dll_remove_ (pcv->waiters, p);
|
||||
dll_remove (&pcv->waiters, p);
|
||||
if ((p_nw->flags & NSYNC_WAITER_FLAG_MUCV) != 0) {
|
||||
uint32_t old_value;
|
||||
do {
|
||||
|
@ -435,11 +432,11 @@ void nsync_cv_broadcast (nsync_cv *pcv) {
|
|||
} while (!ATM_CAS (&DLL_WAITER (p)->remove_count,
|
||||
old_value, old_value+1));
|
||||
}
|
||||
to_wake_list = nsync_dll_make_last_in_list_ (to_wake_list, p);
|
||||
dll_make_last (&to_wake_list, p);
|
||||
}
|
||||
/* Release spinlock and mark queue empty. */
|
||||
ATM_STORE_REL (&pcv->word, 0); /* release store */
|
||||
if (!nsync_dll_is_empty_ (to_wake_list)) { /* Wake them. */
|
||||
if (!dll_is_empty (to_wake_list)) { /* Wake them. */
|
||||
wake_waiters (to_wake_list, all_readers);
|
||||
}
|
||||
}
|
||||
|
@ -477,7 +474,7 @@ static int cv_enqueue (void *v, struct nsync_waiter_s *nw) {
|
|||
nsync_cv *pcv = (nsync_cv *) v;
|
||||
/* acquire spinlock */
|
||||
uint32_t old_word = nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, CV_SPINLOCK, 0);
|
||||
pcv->waiters = nsync_dll_make_last_in_list_ (pcv->waiters, &nw->q);
|
||||
dll_make_last (&pcv->waiters, &nw->q);
|
||||
ATM_STORE (&nw->waiting, 1);
|
||||
/* Release spinlock. */
|
||||
ATM_STORE_REL (&pcv->word, old_word | CV_NON_EMPTY); /* release store */
|
||||
|
@ -490,11 +487,11 @@ static int cv_dequeue (void *v, struct nsync_waiter_s *nw) {
|
|||
/* acquire spinlock */
|
||||
uint32_t old_word = nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, CV_SPINLOCK, 0);
|
||||
if (ATM_LOAD_ACQ (&nw->waiting) != 0) {
|
||||
pcv->waiters = nsync_dll_remove_ (pcv->waiters, &nw->q);
|
||||
dll_remove (&pcv->waiters, &nw->q);
|
||||
ATM_STORE (&nw->waiting, 0);
|
||||
was_queued = 1;
|
||||
}
|
||||
if (nsync_dll_is_empty_ (pcv->waiters)) {
|
||||
if (dll_is_empty (pcv->waiters)) {
|
||||
old_word &= ~(CV_NON_EMPTY);
|
||||
}
|
||||
/* Release spinlock. */
|
||||
|
|
10
third_party/nsync/mem/nsync_debug.c
vendored
10
third_party/nsync/mem/nsync_debug.c
vendored
|
@ -15,9 +15,9 @@
|
|||
│ See the License for the specific language governing permissions and │
|
||||
│ limitations under the License. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/dll.h"
|
||||
#include "third_party/nsync/atomic.h"
|
||||
#include "third_party/nsync/common.internal.h"
|
||||
#include "third_party/nsync/dll.h"
|
||||
#include "third_party/nsync/mu_semaphore.h"
|
||||
#include "third_party/nsync/races.internal.h"
|
||||
#include "third_party/nsync/wait_s.internal.h"
|
||||
|
@ -142,9 +142,9 @@ static void emit_word (struct emit_buf *b, const struct bit_name *name, uint32_t
|
|||
}
|
||||
|
||||
/* Emit the waiter queue *q to *b. */
|
||||
static void emit_waiters (struct emit_buf *b, nsync_dll_list_ list) {
|
||||
nsync_dll_element_ *p = nsync_dll_first_ (list);
|
||||
nsync_dll_element_ *next;
|
||||
static void emit_waiters (struct emit_buf *b, struct Dll *list) {
|
||||
struct Dll *p = dll_first (list);
|
||||
struct Dll *next;
|
||||
if (p != NULL) {
|
||||
emit_print (b, "\nwaiters =\n");
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ static void emit_waiters (struct emit_buf *b, nsync_dll_list_ list) {
|
|||
emit_print (b, "bad WAITER_TAG %i",
|
||||
(uintptr_t) w->tag);
|
||||
} else {
|
||||
next = nsync_dll_next_ (list, p);
|
||||
next = dll_next (list, p);
|
||||
if (nw->tag != NSYNC_WAITER_TAG) {
|
||||
emit_print (b, " bad WAITER_TAG %i",
|
||||
(uintptr_t) nw->tag);
|
||||
|
|
12
third_party/nsync/mem/nsync_mu_wait.c
vendored
12
third_party/nsync/mem/nsync_mu_wait.c
vendored
|
@ -16,9 +16,9 @@
|
|||
│ limitations under the License. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/blockcancel.internal.h"
|
||||
#include "libc/intrin/dll.h"
|
||||
#include "third_party/nsync/atomic.h"
|
||||
#include "third_party/nsync/common.internal.h"
|
||||
#include "third_party/nsync/dll.h"
|
||||
#include "third_party/nsync/mu_semaphore.h"
|
||||
#include "third_party/nsync/races.internal.h"
|
||||
#include "third_party/nsync/wait_s.internal.h"
|
||||
|
@ -203,18 +203,16 @@ int nsync_mu_wait_with_deadline (nsync_mu *mu,
|
|||
had_waiters = ((old_word & (MU_DESIG_WAKER | MU_WAITING)) == MU_WAITING);
|
||||
/* Queue the waiter. */
|
||||
if (first_wait) {
|
||||
nsync_maybe_merge_conditions_ (nsync_dll_last_ (mu->waiters),
|
||||
nsync_maybe_merge_conditions_ (dll_last (mu->waiters),
|
||||
&w->nw.q);
|
||||
/* first wait goes to end of queue */
|
||||
mu->waiters = nsync_dll_make_last_in_list_ (mu->waiters,
|
||||
&w->nw.q);
|
||||
dll_make_last (&mu->waiters, &w->nw.q);
|
||||
first_wait = 0;
|
||||
} else {
|
||||
nsync_maybe_merge_conditions_ (&w->nw.q,
|
||||
nsync_dll_first_ (mu->waiters));
|
||||
dll_first (mu->waiters));
|
||||
/* subsequent waits go to front of queue */
|
||||
mu->waiters = nsync_dll_make_first_in_list_ (mu->waiters,
|
||||
&w->nw.q);
|
||||
dll_make_first (&mu->waiters, &w->nw.q);
|
||||
}
|
||||
/* Release spinlock and *mu. */
|
||||
do {
|
||||
|
|
55
third_party/nsync/mem/nsync_note.c
vendored
55
third_party/nsync/mem/nsync_note.c
vendored
|
@ -15,11 +15,11 @@
|
|||
│ See the License for the specific language governing permissions and │
|
||||
│ limitations under the License. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/dll.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/nsync/atomic.h"
|
||||
#include "third_party/nsync/common.internal.h"
|
||||
#include "third_party/nsync/dll.h"
|
||||
#include "third_party/nsync/mu_semaphore.h"
|
||||
#include "third_party/nsync/mu_wait.h"
|
||||
#include "third_party/nsync/races.internal.h"
|
||||
|
@ -64,12 +64,12 @@ static void set_expiry_time (nsync_note n, nsync_time t) {
|
|||
n->expiry_time_valid = 1;
|
||||
}
|
||||
|
||||
/* Return a pointer to the note containing nsync_dll_element_ *e. */
|
||||
#define DLL_NOTE(e) ((nsync_note)((e)->container))
|
||||
/* Return a pointer to the note containing struct Dll *e. */
|
||||
#define DLL_NOTE(e) DLL_CONTAINER(struct nsync_note_s_, parent_child_link, e)
|
||||
|
||||
/* Return whether n->children is empty. Assumes n->note_mu held. */
|
||||
static int no_children (const void *v) {
|
||||
return (nsync_dll_is_empty_ (((nsync_note)v)->children));
|
||||
return (dll_is_empty (((nsync_note)v)->children));
|
||||
}
|
||||
|
||||
#define WAIT_FOR_NO_CHILDREN(pred_, n_) nsync_mu_wait (&(n_)->note_mu, &pred_, (n_), NULL)
|
||||
|
@ -91,18 +91,18 @@ static void note_notify_child (nsync_note n, nsync_note parent) {
|
|||
nsync_time t;
|
||||
t = NOTIFIED_TIME (n);
|
||||
if (nsync_time_cmp (t, nsync_time_zero) > 0) {
|
||||
nsync_dll_element_ *p;
|
||||
nsync_dll_element_ *next;
|
||||
struct Dll *p;
|
||||
struct Dll *next;
|
||||
ATM_STORE_REL (&n->notified, 1);
|
||||
while ((p = nsync_dll_first_ (n->waiters)) != NULL) {
|
||||
while ((p = dll_first (n->waiters)) != NULL) {
|
||||
struct nsync_waiter_s *nw = DLL_NSYNC_WAITER (p);
|
||||
n->waiters = nsync_dll_remove_ (n->waiters, p);
|
||||
dll_remove (&n->waiters, p);
|
||||
ATM_STORE_REL (&nw->waiting, 0);
|
||||
nsync_mu_semaphore_v (nw->sem);
|
||||
}
|
||||
for (p = nsync_dll_first_ (n->children); p != NULL; p = next) {
|
||||
for (p = dll_first (n->children); p != NULL; p = next) {
|
||||
nsync_note child = DLL_NOTE (p);
|
||||
next = nsync_dll_next_ (n->children, p);
|
||||
next = dll_next (n->children, p);
|
||||
nsync_mu_lock (&child->note_mu);
|
||||
if (child->disconnecting == 0) {
|
||||
note_notify_child (child, n);
|
||||
|
@ -111,8 +111,7 @@ static void note_notify_child (nsync_note n, nsync_note parent) {
|
|||
}
|
||||
WAIT_FOR_NO_CHILDREN (no_children, n);
|
||||
if (parent != NULL) {
|
||||
parent->children = nsync_dll_remove_ (parent->children,
|
||||
&n->parent_child_link);
|
||||
dll_remove (&parent->children, &n->parent_child_link);
|
||||
WAKEUP_NO_CHILDREN (parent);
|
||||
n->parent = NULL;
|
||||
}
|
||||
|
@ -178,8 +177,8 @@ nsync_note nsync_note_new (nsync_note parent,
|
|||
nsync_time abs_deadline) {
|
||||
nsync_note n = (nsync_note) malloc (sizeof (*n));
|
||||
if (n != NULL) {
|
||||
memset ((void *) n, 0, sizeof (*n));
|
||||
nsync_dll_init_ (&n->parent_child_link, n);
|
||||
bzero (n, sizeof (*n));
|
||||
dll_init (&n->parent_child_link);
|
||||
set_expiry_time (n, abs_deadline);
|
||||
if (!nsync_note_is_notified (n) && parent != NULL) {
|
||||
nsync_time parent_time;
|
||||
|
@ -190,8 +189,8 @@ nsync_note nsync_note_new (nsync_note parent,
|
|||
}
|
||||
if (nsync_time_cmp (parent_time, nsync_time_zero) > 0) {
|
||||
n->parent = parent;
|
||||
parent->children = nsync_dll_make_last_in_list_ (parent->children,
|
||||
&n->parent_child_link);
|
||||
dll_make_last (&parent->children,
|
||||
&n->parent_child_link);
|
||||
}
|
||||
nsync_mu_unlock (&parent->note_mu);
|
||||
}
|
||||
|
@ -201,28 +200,27 @@ nsync_note nsync_note_new (nsync_note parent,
|
|||
|
||||
void nsync_note_free (nsync_note n) {
|
||||
nsync_note parent;
|
||||
nsync_dll_element_ *p;
|
||||
nsync_dll_element_ *next;
|
||||
struct Dll *p;
|
||||
struct Dll *next;
|
||||
nsync_mu_lock (&n->note_mu);
|
||||
n->disconnecting++;
|
||||
ASSERT (nsync_dll_is_empty_ (n->waiters));
|
||||
ASSERT (dll_is_empty (n->waiters));
|
||||
parent = n->parent;
|
||||
if (parent != NULL && !nsync_mu_trylock (&parent->note_mu)) {
|
||||
nsync_mu_unlock (&n->note_mu);
|
||||
nsync_mu_lock (&parent->note_mu);
|
||||
nsync_mu_lock (&n->note_mu);
|
||||
}
|
||||
for (p = nsync_dll_first_ (n->children); p != NULL; p = next) {
|
||||
for (p = dll_first (n->children); p != NULL; p = next) {
|
||||
nsync_note child = DLL_NOTE (p);
|
||||
next = nsync_dll_next_ (n->children, p);
|
||||
next = dll_next (n->children, p);
|
||||
nsync_mu_lock (&child->note_mu);
|
||||
if (child->disconnecting == 0) {
|
||||
n->children = nsync_dll_remove_ (n->children,
|
||||
&child->parent_child_link);
|
||||
dll_remove (&n->children, &child->parent_child_link);
|
||||
if (parent != NULL) {
|
||||
child->parent = parent;
|
||||
parent->children = nsync_dll_make_last_in_list_ (
|
||||
parent->children, &child->parent_child_link);
|
||||
dll_make_last (&parent->children,
|
||||
&child->parent_child_link);
|
||||
} else {
|
||||
child->parent = NULL;
|
||||
}
|
||||
|
@ -231,8 +229,7 @@ void nsync_note_free (nsync_note n) {
|
|||
}
|
||||
WAIT_FOR_NO_CHILDREN (no_children, n);
|
||||
if (parent != NULL) {
|
||||
parent->children = nsync_dll_remove_ (parent->children,
|
||||
&n->parent_child_link);
|
||||
dll_remove (&parent->children, &n->parent_child_link);
|
||||
WAKEUP_NO_CHILDREN (parent);
|
||||
n->parent = NULL;
|
||||
nsync_mu_unlock (&parent->note_mu);
|
||||
|
@ -273,7 +270,7 @@ static int note_enqueue (void *v, struct nsync_waiter_s *nw) {
|
|||
nsync_mu_lock (&n->note_mu);
|
||||
ntime = NOTIFIED_TIME (n);
|
||||
if (nsync_time_cmp (ntime, nsync_time_zero) > 0) {
|
||||
n->waiters = nsync_dll_make_last_in_list_ (n->waiters, &nw->q);
|
||||
dll_make_last (&n->waiters, &nw->q);
|
||||
ATM_STORE (&nw->waiting, 1);
|
||||
waiting = 1;
|
||||
} else {
|
||||
|
@ -292,7 +289,7 @@ static int note_dequeue (void *v, struct nsync_waiter_s *nw) {
|
|||
nsync_mu_lock (&n->note_mu);
|
||||
ntime = NOTIFIED_TIME (n);
|
||||
if (nsync_time_cmp (ntime, nsync_time_zero) > 0) {
|
||||
n->waiters = nsync_dll_remove_ (n->waiters, &nw->q);
|
||||
dll_remove (&n->waiters, &nw->q);
|
||||
ATM_STORE (&nw->waiting, 0);
|
||||
was_queued = 1;
|
||||
}
|
||||
|
|
1
third_party/nsync/mem/nsync_once.c
vendored
1
third_party/nsync/mem/nsync_once.c
vendored
|
@ -18,7 +18,6 @@
|
|||
#include "third_party/nsync/atomic.h"
|
||||
#include "third_party/nsync/atomic.internal.h"
|
||||
#include "third_party/nsync/common.internal.h"
|
||||
#include "third_party/nsync/dll.h"
|
||||
#include "third_party/nsync/mu_semaphore.h"
|
||||
#include "third_party/nsync/once.h"
|
||||
#include "third_party/nsync/races.internal.h"
|
||||
|
|
10
third_party/nsync/mem/nsync_sem_wait.c
vendored
10
third_party/nsync/mem/nsync_sem_wait.c
vendored
|
@ -16,11 +16,11 @@
|
|||
│ limitations under the License. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/dll.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "third_party/nsync/atomic.h"
|
||||
#include "third_party/nsync/atomic.internal.h"
|
||||
#include "third_party/nsync/common.internal.h"
|
||||
#include "third_party/nsync/dll.h"
|
||||
#include "third_party/nsync/mu_semaphore.h"
|
||||
#include "third_party/nsync/wait_s.internal.h"
|
||||
|
||||
|
@ -47,7 +47,7 @@ int nsync_sem_wait_with_cancel_ (waiter *w, nsync_time abs_deadline,
|
|||
struct nsync_waiter_s nw;
|
||||
nw.tag = NSYNC_WAITER_TAG;
|
||||
nw.sem = &w->sem;
|
||||
nsync_dll_init_ (&nw.q, &nw);
|
||||
dll_init (&nw.q);
|
||||
ATM_STORE (&nw.waiting, 1);
|
||||
nw.flags = 0;
|
||||
nsync_mu_lock (&cancel_note->note_mu);
|
||||
|
@ -55,8 +55,7 @@ int nsync_sem_wait_with_cancel_ (waiter *w, nsync_time abs_deadline,
|
|||
if (nsync_time_cmp (cancel_time, nsync_time_zero) > 0) {
|
||||
nsync_time local_abs_deadline;
|
||||
int deadline_is_nearer = 0;
|
||||
cancel_note->waiters = nsync_dll_make_last_in_list_ (
|
||||
cancel_note->waiters, &nw.q);
|
||||
dll_make_last (&cancel_note->waiters, &nw.q);
|
||||
local_abs_deadline = cancel_time;
|
||||
if (nsync_time_cmp (abs_deadline, cancel_time) < 0) {
|
||||
local_abs_deadline = abs_deadline;
|
||||
|
@ -73,8 +72,7 @@ int nsync_sem_wait_with_cancel_ (waiter *w, nsync_time abs_deadline,
|
|||
cancel_time = NOTIFIED_TIME (cancel_note);
|
||||
if (nsync_time_cmp (cancel_time,
|
||||
nsync_time_zero) > 0) {
|
||||
cancel_note->waiters = nsync_dll_remove_ (
|
||||
cancel_note->waiters, &nw.q);
|
||||
dll_remove (&cancel_note->waiters, &nw.q);
|
||||
}
|
||||
}
|
||||
nsync_mu_unlock (&cancel_note->note_mu);
|
||||
|
|
3
third_party/nsync/mem/nsync_wait.c
vendored
3
third_party/nsync/mem/nsync_wait.c
vendored
|
@ -20,7 +20,6 @@
|
|||
#include "third_party/nsync/atomic.h"
|
||||
#include "third_party/nsync/atomic.internal.h"
|
||||
#include "third_party/nsync/common.internal.h"
|
||||
#include "third_party/nsync/dll.h"
|
||||
#include "third_party/nsync/mu_semaphore.h"
|
||||
#include "third_party/nsync/races.internal.h"
|
||||
#include "third_party/nsync/wait_s.internal.h"
|
||||
|
@ -58,7 +57,7 @@ int nsync_wait_n (void *mu, void (*lock) (void *), void (*unlock) (void *),
|
|||
for (i = 0; i != count && enqueued; i++) {
|
||||
nw[i].tag = NSYNC_WAITER_TAG;
|
||||
nw[i].sem = &w->sem;
|
||||
nsync_dll_init_ (&nw[i].q, &nw[i]);
|
||||
dll_init (&nw[i].q);
|
||||
ATM_STORE (&nw[i].waiting, 0);
|
||||
nw[i].flags = 0;
|
||||
enqueued = (*waitable[i]->funcs->enqueue) (waitable[i]->v, &nw[i]);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue