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

Reply via email to