I want to use anonymous semaphores in shared memory to synchronise multiple processes.
While multiple POSIX operating systems provide anonymous semaphores (through sem_init
and associated functions), macOS doesn't support them.
I discovered that the Mach semaphores are available on macOS, but in semaphore_create
, I see no equivalent to to the pshared
parameter of sem_init
and I have a hard time finding documentation indicating that Mach/XNU semaphores can actually be used for synchronising processes and not just threads. Is it possible?
Here is how I am using the semaphores currently (note that sema
is a structure that contains different kinds of semaphores depending on the target OS, for instance it contains a sem_t
semaphore on Linux):
For initialising the semaphore:
task_t task = current_task();
semaphore_create(task, &sema->semaphore, SYNC_POLICY_FIFO, value)
For waiting on it:
semaphore_wait(sema->semaphore);
For waiting on it with a timeout (equivalent functionality to sem_timedwait
on Linux):
mach_timespec_t time;
time.tv_sec = seconds;
time.tv_nsec = useconds;
semaphore_timedwait(sema->semaphore, time);
For signalling it:
semaphore_signal(sema->semaphore);
All of the above code examples are actually contained in corresponding functions that allow to provide an OS agnostic API, the test calls I'm doing on these functions on Linux work as expected, but on macOS the process waiting on the semaphore is never signaled from the other process.
What am I doing wrong?
Edit
I found this in the docs:
Semaphores can be used any place where mutexes can occur. This precludes their use in interrupt handlers or within the context of the scheduler, and makes it strongly discouraged in the VM system.
What does the "context of the scheduler" refer to exactly? Would it be if you was writing your own scheduler or does this refer to any interaction with the scheduler (eg: processes).
In all cases, am I right that VM means that it shouldn't be used with processes that make use of the virtual memory, in other terms... all user processes?
Mach semaphores can be used across processes, but it requires moving their port handles with mach_msg to another process, and it's a bit of a pain.
But - why go there, when you have not POSIX semaphores, but Sys V ones? sem_init may not be available, but Sys V semaphores are fully supported.
Specifically you're looking at the following sys calls:
sem_open takes a semaphore path on the filesystem, creating a named semaphore which will have visibility in your other process as well. sem_wait, etc..