From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: <8cdf39c7acd3dea54d564e218a675229@swtch.com> To: 9fans@cse.psu.edu From: "Russ Cox" Date: Thu, 23 Mar 2006 19:43:46 -0500 MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Subject: [9fans] new system calls - semacquire, semrelease Topicbox-Message-UUID: 1eeaa022-ead1-11e9-9d60-3106f5b1d025 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 #include 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.