#include <libc.h>
int semacquire(long *addr, int block);
int tsemacquire(long *addr, ulong ms);
long semrelease(long *addr, long count);
The semaphore's value is the integer pointed at by addr . Semacquire atomically waits until the semaphore has a positive value and then decrements that value. If block is zero and the semaphore is not immediately available, semacquire returns 0 instead of waiting. Tsemacquire only waits ms milliseconds for the semaphore to attain a positive value and, if available in that time, decrements that value. It returns 0 otherwise. Both functions return 1 if the semaphore was acquired and -1 on error (e.g., if they were interrupted). Semrelease adds count to the semaphore's value and returns the new value.
Semacquire (and analogously for tsemacquire ) and semrelease can be thought of as efficient, correct replacements for:
.EX int semacquire(long *addr, int block) { while(*addr == 0){ if(!block) return 0; if(interrupted) return -1; } --*addr; return 1; } int semrelease(long *addr, int count) { return *addr += count; }Like rendezvous (2), semacquire , tsemacquire , and semrelease are not typically used directly. Instead, they are intended to be used to coordinate scheduling in higher-level abstractions such as locks, rendezvous points, and channels (see lock (2) and thread (2)). Also like rendezvous , semacquire , tsemacquire , and semrelease cannot be used to coordinate between threads in a single process. Use locks, rendezvous points, or channels instead.