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