a bit like ...
semnew: fn(n: int): ref Sem;
semacquire: fn(s: ref Sem);
semcanacq: fn(s: ref Sem): int;
semrelease: fn(s: ref Sem);
in ozinferno
On 3/24/06, Russ Cox <[EMAIL PROTECTED]> wrote:
> There are two new system calls today, documented
> in the man page below. As the man page says,
> they are intended as building blocks, not to be used by
> regular programs. The functionality they provide is not
> far from possible to implement with rendezvous(2), but
> the crucial difference is that semrelease has no qlocks
> and thus is guaranteed not to block the calling process*,
> making it suitable to use in real-time processes to wake
> up non-real-time processes. Sape is using this to good
> effect in an internal app.
>
> These semaphores are actually a more convenient building
> block than rendezvous for implementing things like qlock,
> channels, and rsleep/rwakeup. For compatibility with
> older kernels, we're leaving those alone. Maybe in a year
> or two.
>
> See /sys/src/9/port/sysproc.c for more information.
>
> Russ
>
>
> * Of course, semrelease will block if *addr is swapped
> out, but if you're using real-time processes, you're
> not swapping anyway.
>
>
>
> SEMACQUIRE(2) SEMACQUIRE(2)
>
> NAME
> semacquire, semrelease - user level semaphores
>
> SYNOPSIS
> #include <u.h>
> #include <libc.h>
>
> int semacquire(long *addr, int block);
>
> long semrelease(long *addr, long count);
>
> DESCRIPTION
> Semacquire and semrelease facilitate scheduling between pro-
> cesses sharing memory. Processes arrange to share memory by
> using rfork with the RFMEM flag (see fork(2)), segattach(2),
> or thread(2).
>
> The semaphore's value is the integer pointed at by addr.
> Semacquire atomically waits until the semaphore has a posi-
> tive value and then decrements that value. It returns 1 if
> the semaphore was acquired and -1 on error (e.g., if it was
> interrupted). If block is zero and the semaphore is not
> immediately available, semacquire returns 0 instead of wait-
> ing. Semrelease adds count to the semaphore's value and
> returns the new value.
>
> Semacquire and semrelease can be thought of as efficient,
> correct replacements for:
>
> 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 and semrelease are not typi-
> cally 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 and semrelease
> cannot be used to coordinate between threads in a single
> process. Use locks, rendezvous points, or channels instead.
>
> SOURCE
> /sys/src/9/port/sysproc.c
>
> SEE ALSO
> fork(2), lock(2), rendezvous(2), segattach(2), thread(2)
>
> DIAGNOSTICS
> These functions set errstr.
>
>