13 #ifndef __PROCESS_SEMAPHORE_HPP__ 14 #define __PROCESS_SEMAPHORE_HPP__ 17 #include <mach/mach.h> 21 #include <semaphore.h> 39 semaphore_create(mach_task_self(), &semaphore, SYNC_POLICY_FIFO, 0));
46 CHECK_EQ(KERN_SUCCESS, semaphore_destroy(mach_task_self(), semaphore));
53 CHECK_EQ(KERN_SUCCESS, semaphore_wait(semaphore));
58 CHECK_EQ(KERN_SUCCESS, semaphore_signal(semaphore));
62 semaphore_t semaphore;
70 semaphore = CHECK_NOTNULL(CreateSemaphore(
nullptr, 0, LONG_MAX,
nullptr));
77 CHECK(CloseHandle(semaphore));
84 CHECK_EQ(WAIT_OBJECT_0, WaitForSingleObject(semaphore, INFINITE));
89 CHECK(ReleaseSemaphore(semaphore, 1,
nullptr));
101 PCHECK(sem_init(&semaphore, 0, 0) == 0);
108 PCHECK(sem_destroy(&semaphore) == 0);
115 int result = sem_wait(&semaphore);
117 while (result != 0 && errno == EINTR) {
118 result = sem_wait(&semaphore);
126 PCHECK(sem_post(&semaphore) == 0);
147 waiters.fetch_add(1);
149 if (!comissioned.load()) {
150 waiters.fetch_sub(1);
156 waiters.fetch_sub(1);
161 comissioned.store(
false);
168 for (
size_t i = waiters.load(); i > 0; i--) {
175 return !comissioned.load();
186 std::atomic<bool> comissioned = ATOMIC_VAR_INIT(
true);
187 std::atomic<size_t> waiters = ATOMIC_VAR_INIT(0);
240 #define _semaphore_ \ 241 (__semaphore__ == nullptr ? __semaphore__ = new KernelSemaphore() \ 253 for (
size_t i = 0; i < semaphores.size(); i++) {
254 semaphores[i] =
nullptr;
267 while (waiters.load() > 0 && count.load() > 0) {
268 for (
size_t i = 0; i < semaphores.size(); i++) {
272 if (waiters.load() == 0 || count.load() == 0) {
286 if (semaphore !=
nullptr) {
287 if (!semaphores[i].compare_exchange_strong(semaphore,
nullptr)) {
298 waiters.fetch_sub(1);
311 size_t old = count.load();
314 if (!count.compare_exchange_strong(old, old - 1)) {
321 waiters.fetch_add(1);
326 if (!comissioned.load()) {
327 waiters.fetch_sub(1);
333 for (
size_t i = 0; i < semaphores.size(); i++) {
338 if (semaphore ==
nullptr) {
347 if ((old = count.load()) > 0) {
348 waiters.fetch_sub(1);
351 if (semaphores[i].compare_exchange_strong(semaphore,
_semaphore_)) {
377 comissioned.store(
false);
384 for (
size_t i = waiters.load(); i > 0; i--) {
391 return !comissioned.load();
396 return semaphores.size();
401 static constexpr
size_t THREADS = 128;
404 std::atomic<bool> comissioned = ATOMIC_VAR_INIT(
true);
408 std::atomic<size_t> count = ATOMIC_VAR_INIT(0);
411 std::atomic<size_t> waiters = ATOMIC_VAR_INIT(0);
415 std::array<std::atomic<KernelSemaphore*>, THREADS> semaphores;
418 #endif // __PROCESS_SEMAPHORE_HPP__ size_t capacity() const
Definition: semaphore.hpp:394
bool decomissioned() const
Definition: semaphore.hpp:389
void signal()
Definition: semaphore.hpp:258
KernelSemaphore()
Definition: semaphore.hpp:99
void decomission()
Definition: semaphore.hpp:159
bool decomissioned() const
Definition: semaphore.hpp:173
DecomissionableLastInFirstOutFixedSizeSemaphore()
Definition: semaphore.hpp:251
size_t capacity() const
Definition: semaphore.hpp:178
constexpr Handle HANDLE
Definition: ingress.hpp:37
void signal()
Definition: semaphore.hpp:124
void wait()
Definition: semaphore.hpp:142
Definition: semaphore.hpp:244
~KernelSemaphore()
Definition: semaphore.hpp:106
KernelSemaphore & operator=(const KernelSemaphore &other)=delete
void wait()
Definition: semaphore.hpp:308
Definition: semaphore.hpp:96
thread_local KernelSemaphore * __semaphore__
Definition: semaphore.hpp:235
#define _semaphore_
Definition: semaphore.hpp:240
void wait()
Definition: semaphore.hpp:113
Definition: semaphore.hpp:139
void decomission()
Definition: semaphore.hpp:375