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