Add syscall primitives for generic userland accessible sleep/wakeup
authorMatthew Dillon <dillon@dragonflybsd.org>
Fri, 14 Jan 2005 02:20:27 +0000 (02:20 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Fri, 14 Jan 2005 02:20:27 +0000 (02:20 +0000)
commitda5fb9ef5952a2e8b0595e74b52640ce80880d08
tree687f71fd149c1a78094339ae87d2c4b1b4ecfdfb
parent79d7ce60d1c978b436b295d808e9e09acb61897d
Add syscall primitives for generic userland accessible sleep/wakeup
functions.  These functions are capable of sleeping and waking up based on
a generic user VM address.  Programs capable of sharing memory are also
capable of interaction through these functions.

Also regenerate our system calls.

umtx_sleep(ptr, matchvalue, timeout)

    If *(int *)ptr (userland pointer) does not match the matchvalue,
    sleep for timeout microseconds.  Access to the contents of *ptr plus
    entering the sleep is interlocked against calls to umtx_wakeup().
    Various error codes are turned depending on what causes the function
    to return.  Note that the timeout may not exceed 1 second.

utmx_wakeup(ptr, count)

    Wakeup at least count processes waiting on the specified userland
    address.  A count of 0 wakes all waiting processes up.  This function
    interlocks against umtx_sleep().

The typical race case showing resolution between two userland processes is
shown below.  A process releasing a contested mutex may adjust the contents
of the pointer after the kernel has tested *ptr in umtx_sleep(), but this does
not matter because the first process will see that the mutex is set to a
contested state and will call wakeup after changing the contents of the
pointer.  Thus, the kernel itself does not have to execute any
compare-and-exchange operations in order to support userland mutexes.

    PROCESS 1 PROCESS 2 ******** RACE#1 ******

    cmp_exg(ptr, FREE, HELD)
. cmp_exg(ptr, HELD, CONTESTED)
. umtx_sleep(ptr, CONTESTED, 0)
. [kernel tests *ptr]     <<<< COMPARE vs
    cmp_exg(CONTESTED, FREE) . <<<< CHANGE
. tsleep(....)
    umtx_wakeup(ptr, 1) .
. .
. .

    PROCESS 1 PROCESS 2 ******** RACE#2 ******

    cmp_exg(ptr, FREE, HELD)
cmp_exg(ptr, HELD, CONTESTED)
umtx_sleep(ptr, CONTESTED, 0)
    cmp_exg(CONTESTED, FREE) <<<< CHANGE vs
    umtx_wakeup(ptr, 1)
[kernel tests *ptr] <<<< COMPARE
[MISMATCH, DO NOT TSLEEP]

These functions are very loosely based on Jeff Roberson's umtx work in
FreeBSD.  These functions are greatly simplified relative to that work in
order to provide a more generic mechanism.

This is precursor work for a port of David Xu's 1:1 userland threading
library.
14 files changed:
include/unistd.h
sys/kern/init_sysent.c
sys/kern/kern_synch.c
sys/kern/kern_umtx.c [new file with mode: 0644]
sys/kern/syscalls.master
sys/sys/param.h
sys/sys/syscall-args
sys/sys/syscall-hide.h
sys/sys/syscall.h
sys/sys/syscall.mk
sys/sys/sysproto.h
sys/sys/systm.h
sys/sys/sysunion.h
sys/sys/thread.h