xref: /freebsd-14.2/lib/libc/sys/_umtx_op.2 (revision 91ebf7d7)
1.\" Copyright (c) 2016 The FreeBSD Foundation, Inc.
2.\" All rights reserved.
3.\"
4.\" This documentation was written by
5.\" Konstantin Belousov <[email protected]> under sponsorship
6.\" from the FreeBSD Foundation.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\"    notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\"    notice, this list of conditions and the following disclaimer in the
15.\"    documentation and/or other materials provided with the distribution.
16.\"
17.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
18.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
21.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27.\" SUCH DAMAGE.
28.\"
29.\" $FreeBSD$
30.\"
31.Dd May 29, 2016
32.Dt _UMTX_OP 2
33.Os
34.Sh NAME
35.Nm _umtx_op
36.Nd interface for implementation of userspace threading synchronization primitives
37.Sh LIBRARY
38.Lb libc
39.Sh SYNOPSIS
40.In sys/types.h
41.In sys/umtx.h
42.Ft int
43.Fn _umtx_op "void *obj" "int op" "u_long val" "void *uaddr" "void *uaddr2"
44.Sh DESCRIPTION
45The
46.Fn _umtx_op
47system call provides kernel support for userspace implementation of
48the threading synchronization primitives.
49The
50.Lb libthr
51uses the syscall to implement
52.St -p1003.1-2001
53pthread locks, like mutexes, condition variables and so on.
54.Ss STRUCTURES
55The operations, performed by the
56.Fn _umtx_op
57syscall, operate on userspace objects which are described
58by the following structures.
59Reserved fields and paddings are omitted.
60All objects require ABI-mandated alignment, but this is not currently
61enforced consistently on all architectures.
62.Pp
63The following flags are defined for flag fields of all structures:
64.Bl -tag -width "Dv USYNC_PROCESS_SHARED"
65.It Dv USYNC_PROCESS_SHARED
66Allow selection of the process-shared sleep queue for the thread sleep
67container, when the lock ownership cannot be granted immediately,
68and the operation must sleep.
69The process-shared or process-private sleep queue is selected based on
70the attributes of the memory mapping which contains the first byte of
71the structure, see
72.Xr mmap 2 .
73Otherwise, if the flag is not specified, the process-private sleep queue
74is selected regardless of the memory mapping attributes, as an optimization.
75.Pp
76See the
77.Sx SLEEP QUEUES
78subsection below for more details on sleep queues.
79.El
80.Pp
81.Bl -hang -offset indent
82.It Sy Mutex
83.Bd -literal
84struct umutex {
85	volatile lwpid_t m_owner;
86	uint32_t         m_flags;
87	uint32_t         m_ceilings[2];
88	uintptr_t        m_rb_lnk;
89};
90.Ed
91.Pp
92The
93.Dv m_owner
94field is the actual lock.
95It contains either the thread identifier of the lock owner in the
96locked state, or zero when the lock is unowned.
97The highest bit set indicates that there is contention on the lock.
98The constants are defined for special values:
99.Bl -tag -width "Dv UMUTEX_RB_OWNERDEAD"
100.It Dv UMUTEX_UNOWNED
101Zero, the value stored in the unowned lock.
102.It Dv UMUTEX_CONTESTED
103The contenion indicator.
104.It Dv UMUTEX_RB_OWNERDEAD
105A thread owning the robust mutex terminated.
106The mutex is in unlocked state.
107.It Dv UMUTEX_RB_NOTRECOV
108The robust mutex is in a non-recoverable state.
109It cannot be locked until reinitialized.
110.El
111.Pp
112The
113.Dv m_flags
114field may contain the following umutex-specific flags, in addition to
115the common flags:
116.Bl -tag -width "Dv UMUTEX_NONCONSISTENT"
117.It Dv UMUTEX_PRIO_INHERIT
118Mutex implements
119.Em Priority Inheritance
120protocol.
121.It Dv UMUTEX_PRIO_PROTECT
122Mutex implements
123.Em Priority Protection
124protocol.
125.It Dv UMUTEX_ROBUST
126Mutex is robust, as described in the
127.Sx ROBUST UMUTEXES
128section below.
129.It Dv UMUTEX_NONCONSISTENT
130Robust mutex is in a transient non-consistent state.
131Not used by kernel.
132.El
133.Pp
134In the manual page, mutexes not having
135.Dv UMUTEX_PRIO_INHERIT
136and
137.Dv UMUTEX_PRIO_PROTECT
138flags set, are called normal mutexes.
139Each type of mutex, i.e. normal mutexes, priority-inherited mutexes,
140and priority-protected mutexes, have a separate sleep queue associated
141with the given key.
142.Pp
143For priority protected mutexes, the
144.Dv m_ceilings
145array contains priority ceiling values.
146The
147.Dv m_ceilings[0]
148is the ceiling value for the mutex, as specified by
149.St -p1003.1-2008
150for the
151.Em Priority Protected
152mutex protocol.
153The
154.Dv m_ceilings[1]
155is used only for the unlock of a priority protected mutex, when
156unlock is done in an order other than the reversed lock order.
157In this case,
158.Dv m_ceilings[1]
159must contain the ceiling value for the last locked priority protected
160mutex, for proper priority reassignment.
161If, instead, the unlocking mutex was the last priority propagated
162mutex locked by the thread,
163.Dv m_ceilings[1]
164should contain \-1.
165This is required because kernel does not maintain the ordered lock list.
166.It Sy Condition variable
167.Bd -literal
168struct ucond {
169	volatile uint32_t c_has_waiters;
170	uint32_t          c_flags;
171	uint32_t          c_clockid;
172};
173.Ed
174.Pp
175A non-zero
176.Dv c_has_waiters
177value indicates that there are in-kernel waiters for the condition,
178executing the
179.Dv UMTX_OP_CV_WAIT
180request.
181.Pp
182The
183.Dv c_flags
184field contains flags.
185Only the common flags, i.e.
186.Dv USYNC_PROCESS_SHARED ,
187are defined for ucond.
188.Pp
189The
190.Dv c_clockid
191member provides the clock identifier to use for timeout, when the
192.Dv UMTX_OP_CV_WAIT
193request has both the
194.Dv CVWAIT_CLOCKID
195flag and the timeout specified.
196Valid clock identifiers are subset of the valid clock ids for the
197.Xr clock_gettime 2
198syscall, namely,
199.Dv CLOCK_REALTIME ,
200.Dv CLOCK_VIRTUAL ,
201.Dv CLOCK_PROF ,
202.Dv CLOCK_MONOTONIC ,
203.Dv CLOCK_UPTIME ,
204.Dv CLOCK_UPTIME_PRECISE ,
205.Dv CLOCK_UPTIME_FAST ,
206.Dv CLOCK_REALTIME_PRECISE ,
207.Dv CLOCK_REALTIME_FAST ,
208.Dv CLOCK_MONOTONIC_PRECISE ,
209.Dv CLOCK_MONOTONIC_FAST ,
210and
211.Dv CLOCK_SECOND
212are allowed.
213.It Sy Reader/writer lock
214.Bd -literal
215struct urwlock {
216	volatile int32_t rw_state;
217	uint32_t         rw_flags;
218	uint32_t         rw_blocked_readers;
219	uint32_t         rw_blocked_writers;
220};
221.Ed
222.Pp
223The
224.Dv rw_state
225field is the actual lock.
226It contains both the flags and counter of the read locks which were
227granted.
228Names of the
229.Dv rw_state
230bits are following:
231.Bl -tag -width "Dv URWLOCK_WRITE_WAITERS"
232.It Dv URWLOCK_WRITE_OWNER
233Write lock was granted.
234.It Dv URWLOCK_WRITE_WAITERS
235There are write lock waiters.
236.It Dv URWLOCK_READ_WAITERS
237There are read lock waiters.
238.It Dv URWLOCK_READER_COUNT(c)
239Returns the count of currently granted read locks.
240.El
241.Pp
242At any given time there may be only one thread to which the writer lock
243is granted on the
244.Vt struct rwlock ,
245and no threads are granted read lock.
246Or, at the given time, up to
247.Dv URWLOCK_MAX_READERS
248threads may be granted the read lock simultaneously, but write lock is
249not granted to any thread.
250.Pp
251The following flags for the
252.Dv rw_flags
253member of
254.Vt struct urwlock
255are defined, in addition to the common flags:
256.Bl -tag -width "Dv URWLOCK_PREFER_READER"
257.It Dv URWLOCK_PREFER_READER
258If specified, immediately grant read lock requests when
259.Dv urwlock
260is already read-locked, even in presence of unsatisfied write
261lock requests.
262By default, if there is a write lock waiter, further read requests are
263not granted, to prevent unfair write lock waiter starvation.
264.El
265.Pp
266The
267.Dv rw_blocked_readers
268and
269.Dv rw_blocked_writers
270members contain the count of threads which are sleeping in kernel,
271waiting for the associated request type to be granted.
272The fields are used by kernel to update the
273.Dv URWLOCK_READ_WAITERS
274and
275.Dv URWLOCK_WRITE_WAITERS
276flags of the
277.Dv rw_state
278lock after requesting thread was woken up.
279.It Sy Semaphore
280.Bd -literal
281struct _usem2 {
282	volatile uint32_t _count;
283	uint32_t          _flags;
284};
285.Ed
286.Pp
287The
288.Dv _count
289word represents a counting semaphore.
290A non-zero value indicates an unlocked (posted) semaphore, while zero
291represents the locked state.
292The maximal supported semaphore count is
293.Dv USEM_MAX_COUNT .
294.Pp
295The
296.Dv _count
297word, besides the counter of posts (unlocks), also contains the
298.Dv USEM_HAS_WAITERS
299bit, which indicates that locked semaphore has waiting threads.
300.Pp
301The
302.Dv USEM_COUNT()
303macro, applied to the
304.Dv _count
305word, returns the current semaphore counter, i.e. the number of posts
306issued on the semaphore.
307.Pp
308The following bits for the
309.Dv _flags
310member of
311.Vt struct _usem2
312are defined, in addition to the common flags:
313.Bl -tag -width "Dv USEM_NAMED"
314.It Dv USEM_NAMED
315Flag is ignored by kernel.
316.El
317.It Sy Timeout parameter
318.Bd -literal
319struct _umtx_time {
320	struct timespec _timeout;
321	uint32_t        _flags;
322	uint32_t        _clockid;
323};
324.Ed
325.Pp
326Several
327.Fn _umtx_op
328operations allow the blocking time to be limited, failing the request
329if it cannot be satisfied in the specified time period.
330The timeout is specified by passing either the address of
331.Vt struct timespec ,
332or its extended variant,
333.Vt struct _umtx_time ,
334as the
335.Fa uaddr2
336argument of
337.Fn _umtx_op .
338They are distinguished by the
339.Fa uaddr
340value, which must be equal to the size of the structure pointed to by
341.Fa uaddr2 ,
342casted to
343.Vt uintptr_t .
344.Pp
345The
346.Dv _timeout
347member specifies the time when the timeout should occur.
348Legal values for clock identifier
349.Dv _clockid
350are shared with the
351.Fa clock_id
352argument to the
353.Xr clock_gettime 2
354function,
355and use the same underlying clocks.
356The specified clock is used to obtain the current time value.
357Interval counting is always performed by the monotonic wall clock.
358.Pp
359The
360.Dv _flags
361argument allows the following flags to further define the timeout behaviour:
362.Bl -tag -width "It Dv UMTX_ABSTIME"
363.It Dv UMTX_ABSTIME
364The
365.Dv _timeout
366value is the absolute time.
367The thread will be unblocked and the request failed when specified
368clock value is equal or exceeds the
369.Dv _timeout.
370.Pp
371If the flag is absent, the timeout value is relative, that is the amount
372of time, measured by the monotonic wall clock from the moment of the request
373start.
374.El
375.El
376.Ss SLEEP QUEUES
377.Pp
378When a locking request cannot be immediately satisfied, the thread is
379typically put to
380.Em sleep ,
381which is a non-runnable state terminated by the
382.Em wake
383operation.
384Lock operations include a
385.Em try
386variant which returns an error rather than sleeping if the lock cannot
387be obtained.
388Also,
389.Fn _umtx_op
390provides requests which explicitly put the thread to sleep.
391.Pp
392Wakes need to know which threads to make runnable, so sleeping threads
393are grouped into containers called
394.Em sleep queues .
395A sleep queue is identified by a key, which for
396.Fn _umtx_op
397is defined as the physical address of some variable.
398Note that the
399.Em physical
400address is used, which means that same variable mapped multiple
401times will give one key value.
402This mechanism enables the construction of
403.Em process-shared
404locks.
405.Pp
406A related attribute of the key is shareability.
407Some requests always interpret keys as private for the current process,
408creating sleep queues with the scope of the current process even if
409the memory is shared.
410Others either select the shareability automatically from the
411mapping attributes, or take additional input as the
412.Dv USYNC_PROCESS_SHARED
413common flag.
414This is done as optimization, allowing the lock scope to be limited
415regardless of the kind of backing memory.
416.Pp
417Only the address of the start byte of the variable specified as key is
418important for determining corresponding sleep queue.
419The size of the variable does not matter, so e.g. sleep on the same
420address interpeted as
421.Vt uint32_t
422and
423.Vt long
424on a little-endian 64-bit platform would collide.
425.Pp
426The last attribute of the key is the object type.
427The sleep queue to which a sleeping thread is assigned is an individual
428one for simple wait requests, mutexes, rwlocks, condvars and other
429primitives, even when the physical address of the key is same.
430.Pp
431When waking up a limited number of threads from a given sleep queue,
432the highest priority threads that have been blocked for the longest on
433the queue are selected.
434.Ss ROBUST UMUTEXES
435The
436.Em robust umutexes
437are provided as a substrate for a userspace library to implement
438.Tn POSIX
439robust mutexes.
440A robust umutex must have the
441.Dv UMUTEX_ROBUST
442flag set.
443.Pp
444On thread termination, the kernel walks two lists of mutexes.
445The two lists head addresses must be provided by a prior call to
446.Dv UMTX_OP_ROBUST_LISTS
447request.
448The lists are singly-linked.
449The link to next element is provided by the
450.Dv m_rb_lnk
451member of the
452.Vt struct umutex .
453.Pp
454Robust list processing is aborted if the kernel finds a mutex
455with any of the following conditions:
456.Bl -dash -offset indent -compact
457.It
458the
459.Dv UMUTEX_ROBUST
460flag is not set
461.It
462not owned by the current thread, except when the mutex is pointed to
463by the
464.Dv robust_inactive
465member of the
466.Vt struct umtx_robust_lists_params ,
467registered for the current thread
468.It
469the combination of mutex flags is invalid
470.It
471read of the umutex memory faults
472.It
473the list length limit described in
474.Xr libthr 3
475is reached.
476.El
477.Pp
478Every mutex in both lists is unlocked as if the
479.Dv UMTX_OP_MUTEX_UNLOCK
480request is performed on it, but instead of the
481.Dv UMUTEX_UNOWNED
482value, the
483.Dv m_owner
484field is written with the
485.Dv UMUTEX_RB_OWNERDEAD
486value.
487When a mutex in the
488.Dv UMUTEX_RB_OWNERDEAD
489state is locked by kernel due to the
490.Dv UMTX_OP_MUTEX_TRYLOCK
491and
492.Dv UMTX_OP_MUTEX_LOCK
493requests, the lock is granted and
494.Er EOWNERDEAD
495error is returned.
496.Pp
497Also, the kernel handles the
498.Dv UMUTEX_RB_NOTRECOV
499value of
500.Dv the m_owner
501field specially, always returning the
502.Er ENOTRECOVERABLE
503error for lock attempts, without granting the lock.
504.Ss OPERATIONS
505The following operations, requested by the
506.Fa op
507argument to the function, are implemented:
508.Bl -tag -width "It Dv UMTX_OP_WAIT_UINT_PRIVATE"
509.It Dv UMTX_OP_WAIT
510Wait.
511The arguments for the request are:
512.Bl -tag -width "It Fa obj"
513.It Fa obj
514Pointer to a variable of type
515.Vt long .
516.It Fa val
517Current value of the
518.Dv *obj .
519.El
520.Pp
521The current value of the variable pointed to by the
522.Fa obj
523argument is compared with the
524.Fa val .
525If they are equal, the requesting thread is put to interruptible sleep
526until woken up or the optionally specified timeout expires.
527.Pp
528The comparison and sleep are atomic.
529In other words, if another thread writes a new value to
530.Dv *obj
531and then issues
532.Dv UMTX_OP_WAKE ,
533the request is guaranteed to not miss the wakeup,
534which might otherwise happen between comparison and blocking.
535.Pp
536The physical address of memory where the
537.Fa *obj
538variable is located, is used as a key to index sleeping threads.
539.Pp
540The read of the current value of the
541.Dv *obj
542variable is not guarded by barriers.
543In particular, it is the user's duty to ensure the lock acquire
544and release memory semantics, if the
545.Dv UMTX_OP_WAIT
546and
547.Dv UMTX_OP_WAKE
548requests are used as a substrate for implementing a simple lock.
549.Pp
550The request is not restartable.
551An unblocked signal delivered during the wait always results in sleep
552interruption and
553.Er EINTR
554error.
555.Pp
556Optionally, a timeout for the request may be specified.
557.It Dv UMTX_OP_WAKE
558Wake the threads possibly sleeping due to
559.Dv UMTX_OP_WAIT .
560The arguments for the request are:
561.Bl -tag -width "It Fa obj"
562.It Fa obj
563Pointer to a variable, used as a key to find sleeping threads.
564.It Fa val
565Up to
566.Fa val
567threads are woken up by this request.
568Specify
569.Dv INT_MAX
570to wake up all waiters.
571.El
572.It Dv UMTX_OP_MUTEX_TRYLOCK
573Try to lock umutex.
574The arguments to the request are:
575.Bl -tag -width "It Fa obj"
576.It Fa obj
577Pointer to the umutex.
578.El
579.Pp
580Operates same as the
581.Dv UMTX_OP_MUTEX_LOCK
582request, but returns
583.Er EBUSY
584instead of sleeping if the lock cannot be obtained immediately.
585.It Dv UMTX_OP_MUTEX_LOCK
586Lock umutex.
587The arguments to the request are:
588.Bl -tag -width "It Fa obj"
589.It Fa obj
590Pointer to the umutex.
591.El
592.Pp
593Locking is performed by writing the current thread id into the
594.Dv m_owner
595word of the
596.Vt struct umutex .
597The write is atomic, preserves the
598.Dv UMUTEX_CONTESTED
599contention indicator, and provides the acquire barrier for
600lock entrance semantic.
601.Pp
602If the lock cannot be obtained immediately because another thread owns
603the lock, the current thread is put to sleep, with
604.Dv UMUTEX_CONTESTED
605bit set before.
606Upon wake up, the lock conditions are re-tested.
607.Pp
608The request adheres to the priority protection or inheritance protocol
609of the mutex, specified by the
610.Dv UMUTEX_PRIO_PROTECT
611or
612.Dv UMUTEX_PRIO_INHERIT
613flag, respectively.
614.Pp
615Optionally, a timeout for the request may be specified.
616.Pp
617A request with a timeout specified is not restartable.
618An unblocked signal delivered during the wait always results in sleep
619interruption and
620.Er EINTR
621error.
622A request without timeout specified is always restarted after return
623from a signal handler.
624.It Dv UMTX_OP_MUTEX_UNLOCK
625Unlock umutex.
626The arguments to the request are:
627.Bl -tag -width "It Fa obj"
628.It Fa obj
629Pointer to the umutex.
630.El
631.Pp
632Unlocks the mutex, by writing
633.Dv UMUTEX_UNOWNED
634(zero) value into
635.Dv m_owner
636word of the
637.Vt struct umutex .
638The write is done with a release barrier, to provide lock leave semantic.
639.Pp
640If there are threads sleeping in the sleep queue associated with the
641umutex, one thread is woken up.
642If more than one thread sleeps in the sleep queue, the
643.Dv UMUTEX_CONTESTED
644bit is set together with the write of the
645.Dv UMUTEX_UNOWNED
646value into
647.Dv m_owner .
648.Pp
649The request adheres to the priority protection or inheritance protocol
650of the mutex, specified by the
651.Dv UMUTEX_PRIO_PROTECT
652or
653.Dv UMUTEX_PRIO_INHERIT
654flag, respectively.
655See description of the
656.Dv m_ceilings
657member of the
658.Vt struct umutex
659structure for additional details of the request operation on the
660priority protected protocol mutex.
661.It Dv UMTX_OP_SET_CEILING
662Set ceiling for the priority protected umutex.
663The arguments to the request are:
664.Bl -tag -width "It Fa obj"
665.It Fa obj
666Pointer to the umutex.
667.It Fa val
668New ceiling value.
669.It Fa uaddr
670Address of a variable of type
671.Vt uint32_t .
672If not
673.Dv NULL
674and the update was successful, the previous ceiling value is
675written to the location pointed to by
676.Fa uaddr .
677.El
678.Pp
679The request locks the umutex pointed to by the
680.Fa obj
681parameter, waiting for the lock if not immediately available.
682After the lock is obtained, the new ceiling value
683.Fa val
684is written to the
685.Dv m_ceilings[0]
686member of the
687.Vt struct umutex,
688after which the umutex is unlocked.
689.Pp
690The locking does not adhere to the priority protect protocol,
691to conform to the
692.Tn POSIX
693requirements for the
694.Xr pthread_mutex_setprioceiling 3
695interface.
696.It Dv UMTX_OP_CV_WAIT
697Wait for a condition.
698The arguments to the request are:
699.Bl -tag -width "It Fa uaddr2"
700.It Fa obj
701Pointer to the
702.Vt struct ucond .
703.It Fa val
704Request flags, see below.
705.It Fa uaddr
706Pointer to the umutex.
707.It Fa uaddr2
708Optional pointer to a
709.Vt struct timespec
710for timeout specification.
711.El
712.Pp
713The request must be issued by the thread owning the mutex pointed to
714by the
715.Fa uaddr
716argument.
717The
718.Dv c_hash_waiters
719member of the
720.Vt struct ucond ,
721pointed to by the
722.Fa obj
723argument, is set to an arbitrary non-zero value, after which the
724.Fa uaddr
725mutex is unlocked (following the appropriate protocol), and
726the current thread is put to sleep on the sleep queue keyed by
727the
728.Fa obj
729argument.
730The operations are performed atomically.
731It is guaranteed to not miss a wakeup from
732.Dv UMTX_OP_CV_SIGNAL
733or
734.Dv UMTX_OP_CV_BROADCAST
735sent between mutex unlock and putting the current thread on the sleep queue.
736.Pp
737Upon wakeup, if the timeout expired and no other threads are sleeping in
738the same sleep queue, the
739.Dv c_hash_waiters
740member is cleared.
741After wakeup, the
742.Fa uaddr
743umutex is not relocked.
744.Pp
745The following flags are defined:
746.Bl -tag -width "Dv CVWAIT_CLOCKID"
747.It Dv CVWAIT_ABSTIME
748Timeout is absolute.
749.It Dv CVWAIT_CLOCKID
750Clockid is provided.
751.El
752.Pp
753Optionally, a timeout for the request may be specified.
754Unlike other requests, the timeout value is specified directly by a
755.Vt struct timespec ,
756pointed to by the
757.Fa uaddr2
758argument.
759If the
760.Dv CVWAIT_CLOCKID
761flag is provided, the timeout uses the clock from the
762.Dv c_clockid
763member of the
764.Vt struct ucond ,
765pointed to by
766.Fa obj
767argument.
768Otherwise,
769.Dv CLOCK_REALTIME
770is used, regardless of the clock identifier possibly specified in the
771.Vt struct _umtx_time .
772If the
773.Dv CVWAIT_ABSTIME
774flag is supplied, the timeout specifies absolute time value, otherwise
775it denotes a relative time interval.
776.Pp
777The request is not restartable.
778An unblocked signal delivered during
779the wait always results in sleep interruption and
780.Er EINTR
781error.
782.It Dv UMTX_OP_CV_SIGNAL
783Wake up one condition waiter.
784The arguments to the request are:
785.Bl -tag -width "It Fa obj"
786.It Fa obj
787Pointer to
788.Vt struct ucond .
789.El
790.Pp
791The request wakes up at most one thread sleeping on the sleep queue keyed
792by the
793.Fa obj
794argument.
795If the woken up thread was the last on the sleep queue, the
796.Dv c_has_waiters
797member of the
798.Vt struct ucond
799is cleared.
800.It Dv UMTX_OP_CV_BROADCAST
801Wake up all condition waiters.
802The arguments to the request are:
803.Bl -tag -width "It Fa obj"
804.It Fa obj
805Pointer to
806.Vt struct ucond .
807.El
808.Pp
809The request wakes up all threads sleeping on the sleep queue keyed by the
810.Fa obj
811argument.
812The
813.Dv c_has_waiters
814member of the
815.Vt struct ucond
816is cleared.
817.It Dv UMTX_OP_WAIT_UINT
818Same as
819.Dv UMTX_OP_WAIT ,
820but the type of the variable pointed to by
821.Fa obj
822is
823.Vt u_int ,
824i.e. 32-bit integer.
825.It Dv UMTX_OP_RW_RDLOCK
826Read-lock a
827.Vt struct rwlock
828lock.
829The arguments to the request are:
830.Bl -tag -width "It Fa obj"
831.It Fa obj
832Pointer to the lock (of type
833.Vt struct rwlock )
834to be read-locked.
835.It Fa val
836Additional flags to augment locking behaviour.
837The valid flags in the
838.Fa val
839argument are:
840.Bl -tag -width "It Dv URWLOCK_PREFER_READER"
841.It Dv URWLOCK_PREFER_READER
842.El
843.El
844.Pp
845The request obtains the read lock on the specified
846.Vt struct rwlock
847by incrementing the count of readers in the
848.Dv rw_state
849word of the structure.
850If the
851.Dv URWLOCK_WRITE_OWNER
852bit is set in the word
853.Dv rw_state ,
854the lock was granted to a writer which has not yet relinquished
855its ownership.
856In this case the current thread is put to sleep until it makes sense to
857retry.
858.Pp
859If the
860.Dv URWLOCK_PREFER_READER
861flag is set either in the
862.Dv rw_flags
863word of the structure, or in the
864.Fa val
865argument of the request, the presence of the threads trying to obtain
866the write lock on the same structure does not prevent the current thread
867from trying to obtain the read lock.
868Otherwise, if the flag is not set, and the
869.Dv URWLOCK_WRITE_WAITERS
870flag is set in
871.Dv rw_state ,
872the current thread does not attempt to obtain read-lock.
873Instead it sets the
874.Dv URWLOCK_READ_WAITERS
875in the
876.Dv rw_state
877word and puts itself to sleep on corresponding sleep queue.
878Upon wakeup, the locking conditions are re-evaluated.
879.Pp
880Optionally, a timeout for the request may be specified.
881.Pp
882The request is not restartable.
883An unblocked signal delivered during the wait always results in sleep
884interruption and
885.Er EINTR
886error.
887.It Dv UMTX_OP_RW_WRLOCK
888Write-lock a
889.Vt struct rwlock
890lock.
891The arguments to the request are:
892.Bl -tag -width "It Fa obj"
893.It Fa obj
894Pointer to the lock (of type
895.Vt struct rwlock )
896to be write-locked.
897.El
898.Pp
899The request obtains a write lock on the specified
900.Vt struct rwlock ,
901by setting the
902.Dv URWLOCK_WRITE_OWNER
903bit in the
904.Dv rw_state
905word of the structure.
906If there is already a write lock owner, as indicated by the
907.Dv URWLOCK_WRITE_OWNER
908bit being set, or there are read lock owners, as indicated
909by the read-lock counter, the current thread does not attempt to
910obtain the write-lock.
911Instead it sets the
912.Dv URWLOCK_WRITE_WAITERS
913in the
914.Dv rw_state
915word and puts itself to sleep on corresponding sleep queue.
916Upon wakeup, the locking conditions are re-evaluated.
917.Pp
918Optionally, a timeout for the request may be specified.
919.Pp
920The request is not restartable.
921An unblocked signal delivered during the wait always results in sleep
922interruption and
923.Er EINTR
924error.
925.It Dv UMTX_OP_RW_UNLOCK
926Unlock rwlock.
927The arguments to the request are:
928.Bl -tag -width "It Fa obj"
929.It Fa obj
930Pointer to the lock (of type
931.Vt struct rwlock )
932to be unlocked.
933.El
934.Pp
935The unlock type (read or write) is determined by the
936current lock state.
937Note that the
938.Vt struct rwlock
939does not save information about the identity of the thread which
940acquired the lock.
941.Pp
942If there are pending writers after the unlock, and the
943.Dv URWLOCK_PREFER_READER
944flag is not set in the
945.Dv rw_flags
946member of the
947.Fa *obj
948structure, one writer is woken up, selected as described in the
949.Sx SLEEP QUEUES
950subsection.
951If the
952.Dv URWLOCK_PREFER_READER
953flag is set, a pending writer is woken up only if there is
954no pending readers.
955.Pp
956If there are no pending writers, or, in the case that the
957.Dv URWLOCK_PREFER_READER
958flag is set, then all pending readers are woken up by unlock.
959.It Dv UMTX_OP_WAIT_UINT_PRIVATE
960Same as
961.Dv UMTX_OP_WAIT_UINT ,
962but unconditionally select the process-private sleep queue.
963.It Dv UMTX_OP_WAKE_PRIVATE
964Same as
965.Dv UMTX_OP_WAKE ,
966but unconditionally select the process-private sleep queue.
967.It Dv UMTX_OP_MUTEX_WAIT
968Wait for mutex availability.
969The arguments to the request are:
970.Bl -tag -width "It Fa obj"
971.It Fa obj
972Address of the mutex.
973.El
974.Pp
975Similarly to the
976.Dv UMTX_OP_MUTEX_LOCK ,
977put the requesting thread to sleep if the mutex lock cannot be obtained
978immediately.
979The
980.Dv UMUTEX_CONTESTED
981bit is set in the
982.Dv m_owner
983word of the mutex to indicate that there is a waiter, before the thread
984is added to the sleep queue.
985Unlike the
986.Dv UMTX_OP_MUTEX_LOCK
987request, the lock is not obtained.
988.Pp
989The operation is not implemented for priority protected and
990priority inherited protocol mutexes.
991.Pp
992Optionally, a timeout for the request may be specified.
993.Pp
994.Pp
995A request with a timeout specified is not restartable.
996An unblocked signal delivered during the wait always results in sleep
997interruption and
998.Er EINTR
999error.
1000A request without a timeout automatically restarts if the signal disposition
1001requested restart via the
1002.Dv SA_RESTART
1003flag in
1004.Vt struct sigaction
1005member
1006.Dv sa_flags .
1007.It Dv UMTX_OP_NWAKE_PRIVATE
1008Wake up a batch of sleeping threads.
1009The arguments to the request are:
1010.Bl -tag -width "It Fa obj"
1011.It Fa obj
1012Pointer to the array of pointers.
1013.It Fa val
1014Number of elements in the array pointed to by
1015.Fa obj .
1016.El
1017.Pp
1018For each element in the array pointed to by
1019.Fa obj ,
1020wakes up all threads waiting on the
1021.Em private
1022sleep queue with the key
1023being the byte addressed by the array element.
1024.It Dv UMTX_OP_MUTEX_WAKE
1025Check if a normal umutex is unlocked and wake up a waiter.
1026The arguments for the request are:
1027.Bl -tag -width "It Fa obj"
1028.It Fa obj
1029Pointer to the umutex.
1030.El
1031.Pp
1032If the
1033.Dv m_owner
1034word of the mutex pointed to by the
1035.Fa obj
1036argument indicates unowned mutex, which has its contention indicator bit
1037.Dv UMUTEX_CONTESTED
1038set, clear the bit and wake up one waiter in the sleep queue associated
1039with the byte addressed by the
1040.Fa obj ,
1041if any.
1042Only normal mutexes are supported by the request.
1043The sleep queue is always one for a normal mutex type.
1044.Pp
1045This request is deprecated in favor of
1046.Dv UMTX_OP_MUTEX_WAKE2
1047since mutexes using it cannot synchronize their own destruction.
1048That is, the
1049.Dv m_owner
1050word has already been set to
1051.Dv UMUTEX_UNOWNED
1052when this request is made,
1053so that another thread can lock, unlock and destroy the mutex
1054(if no other thread uses the mutex afterwards).
1055Clearing the
1056.Dv UMUTEX_CONTESTED
1057bit may then modify freed memory.
1058.It Dv UMTX_OP_MUTEX_WAKE2
1059Check if a umutex is unlocked and wake up a waiter.
1060The arguments for the request are:
1061.Bl -tag -width "It Fa obj"
1062.It Fa obj
1063Pointer to the umutex.
1064.It Fa val
1065The umutex flags.
1066.El
1067.Pp
1068The request does not read the
1069.Dv m_flags
1070member of the
1071.Vt struct umutex ;
1072instead, the
1073.Fa val
1074argument supplies flag information, in particular, to determine the
1075sleep queue where the waiters are found for wake up.
1076.Pp
1077If the mutex is unowned, one waiter is woken up.
1078.Pp
1079If the mutex memory cannot be accessed, all waiters are woken up.
1080.Pp
1081If there is more than one waiter on the sleep queue, or there is only
1082one waiter but the mutex is owned by a thread, the
1083.Dv UMUTEX_CONTESTED
1084bit is set in the
1085.Dv m_owner
1086word of the
1087.Vt struct umutex .
1088.It Dv UMTX_OP_SEM2_WAIT
1089Wait until semaphore is available.
1090The arguments to the request are:
1091.Bl -tag -width "It Fa obj"
1092.It Fa obj
1093Pointer to the semaphore (of type
1094.Vt struct _usem2 ) .
1095.El
1096Put the requesting thread onto a sleep queue if the semaphore counter
1097is zero.
1098If the thread is put to sleep, the
1099.Dv USEM_HAS_WAITERS
1100bit is set in the
1101.Dv _count
1102word to indicate waiters.
1103The function returns either due to
1104.Dv _count
1105indicating the semaphore is available (non-zero count due to post),
1106or due to a wakeup.
1107The return does not guarantee that the semaphore is available,
1108nor does it consume the semaphore lock on successful return.
1109.Pp
1110Optionally, a timeout for the request may be specified.
1111.Pp
1112A request with non-absolute timeout value is not restartable.
1113An unblocked signal delivered during such wait results in sleep
1114interruption and
1115.Er EINTR
1116error.
1117.It Dv UMTX_OP_SEM2_WAKE
1118Wake up waiters on semaphore lock.
1119The arguments to the request are:
1120.Bl -tag -width "It Fa obj"
1121.It Fa obj
1122Pointer to the semaphore (of type
1123.Vt struct _usem2 ) .
1124.El
1125.Pp
1126The request wakes up one waiter for the semaphore lock.
1127The function does not increment the semaphore lock count.
1128If the
1129.Dv USEM_HAS_WAITERS
1130bit was set in the
1131.Dv _count
1132word, and the last sleeping thread was woken up, the bit is cleared.
1133.It Dv UMTX_OP_SHM
1134Manage anonymous
1135.Tn POSIX
1136shared memory objects (see
1137.Xr shm_open 2 ) ,
1138which can be attached to a byte of physical memory, mapped into the
1139process address space.
1140The objects are used to implement process-shared locks in
1141.Dv libthr .
1142.Pp
1143The
1144.Fa val
1145argument specifies the sub-request of the
1146.Dv UMTX_OP_SHM
1147request:
1148.Bl -tag -width "Dv UMTX_SHM_DESTROY"
1149.It Dv UMTX_SHM_CREAT
1150Creates the anonymous shared memory object, which can be looked up
1151with the specified key
1152.Fa uaddr.
1153If the object associated with the
1154.Fa uaddr
1155key already exists, it is returned instead of creating a new object.
1156The object's size is one page.
1157On success, the file descriptor referencing the object is returned.
1158The descriptor can be used for mapping the object using
1159.Xr mmap 2 ,
1160or for other shared memory operations.
1161.It Dv UMTX_SHM_LOOKUP
1162Same as
1163.Dv UMTX_SHM_CREATE
1164request, but if there is no shared memory object associated with
1165the specified key
1166.Fa uaddr ,
1167an error is returned, and no new object is created.
1168.It Dv UMTX_SHM_DESTROY
1169De-associate the shared object with the specified key
1170.Fa uaddr.
1171The object is destroyed after the last open file descriptor is closed
1172and the last mapping for it is destroyed.
1173.It Dv UMTX_SHM_ALIVE
1174Checks whether there is a live shared object associated with the
1175supplied key
1176.Fa uaddr .
1177Returns zero if there is, and an error otherwise.
1178This request is an optimization of the
1179.Dv UMTX_SHM_LOOKUP
1180request.
1181It is cheaper when only the liveness of the associated object is asked
1182for, since no file descriptor is installed in the process fd table
1183on success.
1184.El
1185.Pp
1186The
1187.Fa uaddr
1188argument specifies the virtual address, which backing physical memory
1189byte identity is used as a key for the anonymous shared object
1190creation or lookup.
1191.It Dv UMTX_OP_ROBUST_LISTS
1192Register the list heads for the current thread's robust mutex lists.
1193The arguments to the request are:
1194.Bl -tag -width "It Fa obj"
1195.It Fa val
1196Size of the structure passed in the
1197.Fa uaddr
1198argument.
1199.It Fa uaddr
1200Pointer to the structure of type
1201.Vt struct umtx_robust_lists_params .
1202.El
1203.Pp
1204The structure is defined as
1205.Bd -literal
1206struct umtx_robust_lists_params {
1207	uintptr_t	robust_list_offset;
1208	uintptr_t	robust_priv_list_offset;
1209	uintptr_t	robust_inact_offset;
1210};
1211.Ed
1212.Pp
1213The
1214.Dv robust_list_offset
1215member contains address of the first element in the list of locked
1216robust shared mutexes.
1217The
1218.Dv robust_priv_list_offset
1219member contains address of the first element in the list of locked
1220robust private mutexes.
1221The private and shared robust locked lists are split to allow fast
1222termination of the shared list on fork, in the child.
1223.Pp
1224The
1225.Dv robust_inact_offset
1226contains a pointer to the mutex which might be locked in nearby future,
1227or might have been just unlocked.
1228It is typically set by the lock or unlock mutex implementation code
1229around the whole operation, since lists can be only changed race-free
1230when the thread owns the mutex.
1231The kernel inspects the
1232.Dv robust_inact_offset
1233in addition to walking the shared and private lists.
1234Also, the mutex pointed to by
1235.Dv robust_inact_offset
1236is handled more loosely at the thread termination time,
1237than other mutexes on the list.
1238That mutex is allowed to be not owned by the current thread,
1239in which case list processing is continued.
1240See
1241.Sx ROBUST UMUTEXES
1242subsection for details.
1243.El
1244.Sh RETURN VALUES
1245If successful,
1246all requests, except
1247.Dv UMTX_SHM_CREAT
1248and
1249.Dv UMTX_SHM_LOOKUP
1250sub-requests of the
1251.Dv UMTX_OP_SHM
1252request, will return zero.
1253The
1254.Dv UMTX_SHM_CREAT
1255and
1256.Dv UMTX_SHM_LOOKUP
1257return a shared memory file descriptor on success.
1258On error \-1 is returned, and the
1259.Va errno
1260variable is set to indicate the error.
1261.Sh ERRORS
1262The
1263.Fn _umtx_op
1264operations will return the following errors:
1265.Bl -tag -width "Bq Er ENOTRECOVERABLE"
1266.It Bq Er EFAULT
1267One of the arguments point to invalid memory.
1268.It Bq Er EINVAL
1269The clock identifier, specified for the
1270.Vt struct _umtx_time
1271timeout parameter, or in the
1272.Dv c_clockid
1273member of
1274.Vt struct ucond,
1275is invalid.
1276.It Bq Er EINVAL
1277The type of the mutex, encoded by the
1278.Dv m_flags
1279member of
1280.Vt struct umutex ,
1281is invalid.
1282.It Bq Er EINVAL
1283The
1284.Dv m_owner
1285member of the
1286.Vt struct umutex
1287has changed the lock owner thread identifier during unlock.
1288.It Bq Er EINVAL
1289The
1290.Dv timeout.tv_sec
1291or
1292.Dv timeout.tv_nsec
1293member of
1294.Vt struct _umtx_time
1295is less than zero, or
1296.Dv timeout.tv_nsec
1297is greater than 1000000000.
1298.It Bq Er EINVAL
1299The
1300.Fa op
1301argument specifies invalid operation.
1302.It Bq Er EINVAL
1303The
1304.Fa uaddr
1305argument for the
1306.Dv UMTX_OP_SHM
1307request specifies invalid operation.
1308.It Bq Er EINVAL
1309The
1310.Dv UMTX_OP_SET_CEILING
1311request specifies non priority protected mutex.
1312.It Bq Er EINVAL
1313The new ceiling value for the
1314.Dv UMTX_OP_SET_CEILING
1315request, or one or more of the values read from the
1316.Dv m_ceilings
1317array during lock or unlock operations, is greater than
1318.Dv RTP_PRIO_MAX .
1319.It Bq Er EPERM
1320Unlock attempted on an object not owned by the current thread.
1321.It Bq Er EOWNERDEAD
1322The lock was requested on an umutex where the
1323.Dv m_owner
1324field was set to the
1325.Dv UMUTEX_RB_OWNERDEAD
1326value, indicating terminated robust mutex.
1327The lock was granted to the caller, so this error in fact
1328indicates success with additional conditions.
1329.It Bq Er ENOTRECOVERABLE
1330The lock was requested on an umutex which
1331.Dv m_owner
1332field is equal to the
1333.Dv UMUTEX_RB_NOTRECOV
1334value, indicating abandoned robust mutex after termination.
1335The lock was not granted to the caller.
1336.It Bq Er ENOTTY
1337The shared memory object, associated with the address passed to the
1338.Dv UMTX_SHM_ALIVE
1339sub-request of
1340.Dv UMTX_OP_SHM
1341request, was destroyed.
1342.It Bq Er ESRCH
1343For the
1344.Dv UMTX_SHM_LOOKUP ,
1345.Dv UMTX_SHM_DESTROY ,
1346and
1347.Dv UMTX_SHM_ALIVE
1348sub-requests of the
1349.Dv UMTX_OP_SHM
1350request, there is no shared memory object associated with the provided key.
1351.It Bq Er ENOMEM
1352The
1353.Dv UMTX_SHM_CREAT
1354sub-request of the
1355.Dv UMTX_OP_SHM
1356request cannot be satisfied, because allocation of the shared memory object
1357would exceed the
1358.Dv RLIMIT_UMTXP
1359resource limit, see
1360.Xr setrlimit 2 .
1361.It Bq Er EAGAIN
1362The maximum number of readers
1363.Dv ( URWLOCK_MAX_READERS )
1364were already granted ownership of the given
1365.Vt struct rwlock
1366for read.
1367.It Bq Er EBUSY
1368A try mutex lock operation was not able to obtain the lock.
1369.It Bq Er ETIMEDOUT
1370The request specified a timeout in the
1371.Fa uaddr
1372and
1373.Fa uaddr2
1374arguments, and timed out before obtaining the lock or being woken up.
1375.It Bq Er EINTR
1376A signal was delivered during wait, for a non-restartable operation.
1377Operations with timeouts are typically non-restartable, but timeouts
1378specified in absolute time may be restartable.
1379.It Bq Er ERESTART
1380A signal was delivered during wait, for a restartable operation.
1381Mutex lock requests without timeout specified are restartable.
1382The error is not returned to userspace code since restart
1383is handled by usual adjustment of the instruction counter.
1384.El
1385.Sh BUGS
1386A window between a unlocking robust mutex and resetting the pointer in the
1387.Dv robust_inact_offset
1388member of the registered
1389.Vt struct umtx_robust_lists_params
1390allows another thread to destroy the mutex, thus making the kernel inspect
1391freed or reused memory.
1392The
1393.Li libthr
1394implementation is only vulnerable to this race when operating on
1395a shared mutex.
1396A possible fix for the current implementation is to strengthen the checks
1397for shared mutexes before terminating them, in particular, verifying
1398that the mutex memory is mapped from a shared memory object allocated
1399by the
1400.Dv UMTX_OP_SHM
1401request.
1402This is not done because it is believed that the race is adequately
1403covered by other consistency checks, while adding the check would
1404prevent alternative implementations of
1405.Li libpthread .
1406.Sh SEE ALSO
1407.Xr clock_gettime 2 ,
1408.Xr mmap 2 ,
1409.Xr shm_open 2 ,
1410.Xr setrlimit 2 ,
1411.Xr sigaction 2 ,
1412.Xr thr_exit 2 ,
1413.Xr thr_kill 2 ,
1414.Xr thr_kill2 2 ,
1415.Xr thr_new 2 ,
1416.Xr thr_self 2 ,
1417.Xr thr_set_name 2 ,
1418.Xr signal 3
1419.Sh STANDARDS
1420The
1421.Fn _umtx_op
1422system call is non-standard and is used by the
1423.Lb libthr
1424to implement
1425.St -p1003.1-2001
1426.Xr pthread 3
1427functionality.
1428