Files
net/exec/sync.c
2025-12-20 18:49:21 -08:00

53 lines
1.6 KiB
C

#include <stddef.h>
#include <stdint.h>
#include <stdatomic.h>
#include <exec/list.h>
#include <exec/task.h>
#include <exec/sync.h>
void NewSemaphore(struct Semaphore *semaphore, int count, uint8_t type) {
semaphore->count = count;
semaphore->type = type;
}
void NewMutex(struct Semaphore *semaphore, uint8_t type) {
NewSemaphore(semaphore, 1, type);
}
void Acquire(struct Semaphore *semaphore) {
int expected;
int semtype = (semaphore->type & 3);
//if (!(semaphore->type & SF_NOTRECURSIVE) && semaphore->owner == ThisTask()) return;
if (semtype == SF_CLI) {
InterruptsSaveAndDisable();
} else {
for (;;) {
expected = atomic_load_explicit(&semaphore->count, memory_order_relaxed);
while (expected <= 0) {
if (semtype == SF_BLOCK) {
Block(ThisTask(), &semaphore->count, expected);
} else if ((semaphore->type & 3) == SF_NONE) {
return;
}
expected = atomic_load_explicit(&semaphore->count,
memory_order_relaxed);
}
if (atomic_compare_exchange_weak_explicit(
&semaphore->count, &expected, expected - 1,
memory_order_acquire, memory_order_relaxed)) {
//if (!(semaphore->type & SF_NOTRECURSIVE)) semaphore->owner = ThisTask();
return;
}
}
}
}
void Release(struct Semaphore *semaphore) {
if (semaphore->type == SF_CLI) {
InterruptsRestore();
} else {
atomic_fetch_add_explicit(&semaphore->count, 1, memory_order_release);
}
}