Skip to content

Commit

Permalink
Revert a65df18.
Browse files Browse the repository at this point in the history
For some reason I was thinking that g_freelist is an atomic list
when it is not.  It's only ever accessed by the main thread,
and the whole reason that g_gc_list exists is so that can be
the case.
  • Loading branch information
niklata committed Jun 4, 2024
1 parent cd8b81f commit 8f2cb1a
Showing 1 changed file with 13 additions and 10 deletions.
23 changes: 13 additions & 10 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@
// struct thread is allocated in blocks
#define THREAD_BLOCK_SIZE 64

// Atomically: assigns ASSIGN = TOP and then sets TOP = NEW_TOP.
#define LIST_EXCHANGE_TOP(TOP, ASSIGN, NEW_TOP) do { for (;;) { \
(ASSIGN) = (TOP); \
if (LIKELY(atomic_compare_exchange_strong(&(TOP), &(ASSIGN), (NEW_TOP)))) break; \
}} while (0)

struct client {
union sockaddr_union addr;
int fd;
Expand Down Expand Up @@ -116,7 +122,7 @@ static pthread_mutex_t auth_ips_mtx;
static union sockaddr_union bind_addr;

static _Atomic (struct thread *) g_gc_list;
// These are only ever accessed on the main listening thread.
// This is only ever accessed on the main listening thread.
static struct thread *g_freelist;

enum authmethod {
Expand Down Expand Up @@ -206,12 +212,6 @@ static int bindtoip(int fd, union sockaddr_union *bindaddr) {
return bind(fd, (struct sockaddr *)bindaddr, sz);
}

// Atomically: assigns ASSIGN = TOP and then sets TOP = NEW_TOP.
#define LIST_EXCHANGE_TOP(TOP, ASSIGN, NEW_TOP) do { for (;;) { \
(ASSIGN) = (TOP); \
if (LIKELY(atomic_compare_exchange_strong(&(TOP), &(ASSIGN), (NEW_TOP)))) break; \
}} while (0)

static struct thread *grow_struct_thread(void)
{
struct thread *t;
Expand All @@ -221,13 +221,15 @@ static struct thread *grow_struct_thread(void)
size_t i = 1;
for (; i < THREAD_BLOCK_SIZE - 1; ++i)
t[i].gc_next = t + i + 1;
LIST_EXCHANGE_TOP(g_freelist, t[i].gc_next, t + 1);
t[i].gc_next = g_freelist;
g_freelist = t + 1;
return t;
}

static void free_struct_thread(struct thread *t)
{
LIST_EXCHANGE_TOP(g_freelist, t->gc_next, t);
t->gc_next = g_freelist;
g_freelist = t;
}

static void gc_threads(void) {
Expand Down Expand Up @@ -1020,7 +1022,8 @@ int main(int argc, char** argv) {

struct thread *ct;
if (g_freelist) {
LIST_EXCHANGE_TOP(g_freelist, ct, ct->gc_next);
ct = g_freelist;
g_freelist = ct->gc_next;
} else {
ct = grow_struct_thread();
if (UNLIKELY(!ct)) goto oom1;
Expand Down

0 comments on commit 8f2cb1a

Please sign in to comment.