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