4

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?

halfer
  • 19,824
  • 17
  • 99
  • 186
Pop Flamingo
  • 3,023
  • 2
  • 26
  • 64
  • **Disclaimer:** I've never actually used Mach semaphores, but I've worked with macOS's Mach primitives quite a bit. **Question/suggestion:** I notice that in user space, `semaphore_t` is yet another `mach_port_t` typedef, so my assumption would be that to share semaphores between processes, you need to send the semaphore port from the process which created it to the process which shares it using Mach messaging. (`mach_msg`) Is that how you're sharing access to the semaphore? It won't work if you're just transmitting the literal integer value, each process has a private port name table. – pmdj Dec 06 '20 at 10:45
  • Thank you ! No I wasn't using `mach_msg` thanks for the suggestion! – Pop Flamingo Dec 07 '20 at 09:20

1 Answers1

1

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:

  • semsys
  • semctl
  • semget
  • semop : on top of which you have sem_post(2) and a few other sem_* operations
  • sem_unlink
  • sem_close

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..

Technologeeks
  • 7,674
  • 25
  • 36