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: