#include #include #include #include #include #include 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); } }