2 * Copyright (c) 2004, David Xu <davidxu@freebsd.org>
3 * Copyright (c) 2002, Jeffrey Roberson <jeff@freebsd.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
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.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
31 #include "opt_compat.h"
32 #include <sys/param.h>
33 #include <sys/kernel.h>
34 #include <sys/limits.h>
36 #include <sys/malloc.h>
37 #include <sys/mutex.h>
40 #include <sys/sched.h>
42 #include <sys/sysctl.h>
43 #include <sys/sysent.h>
44 #include <sys/systm.h>
45 #include <sys/sysproto.h>
46 #include <sys/eventhandler.h>
50 #include <vm/vm_param.h>
52 #include <vm/vm_map.h>
53 #include <vm/vm_object.h>
55 #include <machine/cpu.h>
57 #ifdef COMPAT_FREEBSD32
58 #include <compat/freebsd32/freebsd32_proto.h>
62 #define _UMUTEX_WAIT 2
64 /* Priority inheritance mutex info. */
67 struct thread *pi_owner;
72 /* List entry to link umtx holding by thread */
73 TAILQ_ENTRY(umtx_pi) pi_link;
75 /* List entry in hash */
76 TAILQ_ENTRY(umtx_pi) pi_hashlink;
78 /* List for waiters */
79 TAILQ_HEAD(,umtx_q) pi_blocked;
81 /* Identify a userland lock object */
82 struct umtx_key pi_key;
85 /* A userland synchronous object user. */
87 /* Linked list for the hash. */
88 TAILQ_ENTRY(umtx_q) uq_link;
91 struct umtx_key uq_key;
95 #define UQF_UMTXQ 0x0001
97 /* The thread waits on. */
98 struct thread *uq_thread;
101 * Blocked on PI mutex. read can use chain lock
102 * or umtx_lock, write must have both chain lock and
103 * umtx_lock being hold.
105 struct umtx_pi *uq_pi_blocked;
107 /* On blocked list */
108 TAILQ_ENTRY(umtx_q) uq_lockq;
110 /* Thread contending with us */
111 TAILQ_HEAD(,umtx_pi) uq_pi_contested;
113 /* Inherited priority from PP mutex */
114 u_char uq_inherited_pri;
117 TAILQ_HEAD(umtxq_head, umtx_q);
119 /* Userland lock object's wait-queue chain */
121 /* Lock for this chain. */
124 /* List of sleep queues. */
125 struct umtxq_head uc_queue[2];
126 #define UMTX_SHARED_QUEUE 0
127 #define UMTX_EXCLUSIVE_QUEUE 1
132 /* Chain lock waiters */
135 /* All PI in the list */
136 TAILQ_HEAD(,umtx_pi) uc_pi_list;
139 #define UMTXQ_LOCKED_ASSERT(uc) mtx_assert(&(uc)->uc_lock, MA_OWNED)
140 #define UMTXQ_BUSY_ASSERT(uc) KASSERT(&(uc)->uc_busy, ("umtx chain is not busy"))
143 * Don't propagate time-sharing priority, there is a security reason,
144 * a user can simply introduce PI-mutex, let thread A lock the mutex,
145 * and let another thread B block on the mutex, because B is
146 * sleeping, its priority will be boosted, this causes A's priority to
147 * be boosted via priority propagating too and will never be lowered even
148 * if it is using 100%CPU, this is unfair to other processes.
151 #define UPRI(td) (((td)->td_user_pri >= PRI_MIN_TIMESHARE &&\
152 (td)->td_user_pri <= PRI_MAX_TIMESHARE) ?\
153 PRI_MAX_TIMESHARE : (td)->td_user_pri)
155 #define GOLDEN_RATIO_PRIME 2654404609U
156 #define UMTX_CHAINS 128
157 #define UMTX_SHIFTS (__WORD_BIT - 7)
159 #define GET_SHARE(flags) \
160 (((flags) & USYNC_PROCESS_SHARED) == 0 ? THREAD_SHARE : PROCESS_SHARE)
162 #define BUSY_SPINS 200
164 static uma_zone_t umtx_pi_zone;
165 static struct umtxq_chain umtxq_chains[2][UMTX_CHAINS];
166 static MALLOC_DEFINE(M_UMTX, "umtx", "UMTX queue memory");
167 static int umtx_pi_allocated;
169 SYSCTL_NODE(_debug, OID_AUTO, umtx, CTLFLAG_RW, 0, "umtx debug");
170 SYSCTL_INT(_debug_umtx, OID_AUTO, umtx_pi_allocated, CTLFLAG_RD,
171 &umtx_pi_allocated, 0, "Allocated umtx_pi");
173 static void umtxq_sysinit(void *);
174 static void umtxq_hash(struct umtx_key *key);
175 static struct umtxq_chain *umtxq_getchain(struct umtx_key *key);
176 static void umtxq_lock(struct umtx_key *key);
177 static void umtxq_unlock(struct umtx_key *key);
178 static void umtxq_busy(struct umtx_key *key);
179 static void umtxq_unbusy(struct umtx_key *key);
180 static void umtxq_insert_queue(struct umtx_q *uq, int q);
181 static void umtxq_remove_queue(struct umtx_q *uq, int q);
182 static int umtxq_sleep(struct umtx_q *uq, const char *wmesg, int timo);
183 static int umtxq_count(struct umtx_key *key);
184 static struct umtx_pi *umtx_pi_alloc(int);
185 static void umtx_pi_free(struct umtx_pi *pi);
186 static void umtx_pi_adjust_locked(struct thread *td, u_char oldpri);
187 static int do_unlock_pp(struct thread *td, struct umutex *m, uint32_t flags);
188 static void umtx_thread_cleanup(struct thread *td);
189 static void umtx_exec_hook(void *arg __unused, struct proc *p __unused,
190 struct image_params *imgp __unused);
191 SYSINIT(umtx, SI_SUB_EVENTHANDLER+1, SI_ORDER_MIDDLE, umtxq_sysinit, NULL);
193 #define umtxq_signal(key, nwake) umtxq_signal_queue((key), (nwake), UMTX_SHARED_QUEUE)
194 #define umtxq_insert(uq) umtxq_insert_queue((uq), UMTX_SHARED_QUEUE)
195 #define umtxq_remove(uq) umtxq_remove_queue((uq), UMTX_SHARED_QUEUE)
197 static struct mtx umtx_lock;
200 umtxq_sysinit(void *arg __unused)
204 umtx_pi_zone = uma_zcreate("umtx pi", sizeof(struct umtx_pi),
205 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
206 for (i = 0; i < 2; ++i) {
207 for (j = 0; j < UMTX_CHAINS; ++j) {
208 mtx_init(&umtxq_chains[i][j].uc_lock, "umtxql", NULL,
209 MTX_DEF | MTX_DUPOK);
210 TAILQ_INIT(&umtxq_chains[i][j].uc_queue[0]);
211 TAILQ_INIT(&umtxq_chains[i][j].uc_queue[1]);
212 TAILQ_INIT(&umtxq_chains[i][j].uc_pi_list);
213 umtxq_chains[i][j].uc_busy = 0;
214 umtxq_chains[i][j].uc_waiters = 0;
217 mtx_init(&umtx_lock, "umtx lock", NULL, MTX_SPIN);
218 EVENTHANDLER_REGISTER(process_exec, umtx_exec_hook, NULL,
219 EVENTHANDLER_PRI_ANY);
227 uq = malloc(sizeof(struct umtx_q), M_UMTX, M_WAITOK | M_ZERO);
228 TAILQ_INIT(&uq->uq_pi_contested);
229 uq->uq_inherited_pri = PRI_MAX;
234 umtxq_free(struct umtx_q *uq)
240 umtxq_hash(struct umtx_key *key)
242 unsigned n = (uintptr_t)key->info.both.a + key->info.both.b;
243 key->hash = ((n * GOLDEN_RATIO_PRIME) >> UMTX_SHIFTS) % UMTX_CHAINS;
246 static inline struct umtxq_chain *
247 umtxq_getchain(struct umtx_key *key)
249 if (key->type <= TYPE_CV)
250 return (&umtxq_chains[1][key->hash]);
251 return (&umtxq_chains[0][key->hash]);
258 umtxq_lock(struct umtx_key *key)
260 struct umtxq_chain *uc;
262 uc = umtxq_getchain(key);
263 mtx_lock(&uc->uc_lock);
270 umtxq_unlock(struct umtx_key *key)
272 struct umtxq_chain *uc;
274 uc = umtxq_getchain(key);
275 mtx_unlock(&uc->uc_lock);
279 * Set chain to busy state when following operation
280 * may be blocked (kernel mutex can not be used).
283 umtxq_busy(struct umtx_key *key)
285 struct umtxq_chain *uc;
287 uc = umtxq_getchain(key);
288 mtx_assert(&uc->uc_lock, MA_OWNED);
292 int count = BUSY_SPINS;
295 while (uc->uc_busy && --count > 0)
301 while (uc->uc_busy) {
303 msleep(uc, &uc->uc_lock, 0, "umtxqb", 0);
314 umtxq_unbusy(struct umtx_key *key)
316 struct umtxq_chain *uc;
318 uc = umtxq_getchain(key);
319 mtx_assert(&uc->uc_lock, MA_OWNED);
320 KASSERT(uc->uc_busy != 0, ("not busy"));
327 umtxq_insert_queue(struct umtx_q *uq, int q)
329 struct umtxq_chain *uc;
331 uc = umtxq_getchain(&uq->uq_key);
332 UMTXQ_LOCKED_ASSERT(uc);
333 TAILQ_INSERT_TAIL(&uc->uc_queue[q], uq, uq_link);
334 uq->uq_flags |= UQF_UMTXQ;
338 umtxq_remove_queue(struct umtx_q *uq, int q)
340 struct umtxq_chain *uc;
342 uc = umtxq_getchain(&uq->uq_key);
343 UMTXQ_LOCKED_ASSERT(uc);
344 if (uq->uq_flags & UQF_UMTXQ) {
345 TAILQ_REMOVE(&uc->uc_queue[q], uq, uq_link);
346 uq->uq_flags &= ~UQF_UMTXQ;
351 * Check if there are multiple waiters
354 umtxq_count(struct umtx_key *key)
356 struct umtxq_chain *uc;
360 uc = umtxq_getchain(key);
361 UMTXQ_LOCKED_ASSERT(uc);
362 TAILQ_FOREACH(uq, &uc->uc_queue[UMTX_SHARED_QUEUE], uq_link) {
363 if (umtx_key_match(&uq->uq_key, key)) {
372 * Check if there are multiple PI waiters and returns first
376 umtxq_count_pi(struct umtx_key *key, struct umtx_q **first)
378 struct umtxq_chain *uc;
383 uc = umtxq_getchain(key);
384 UMTXQ_LOCKED_ASSERT(uc);
385 TAILQ_FOREACH(uq, &uc->uc_queue[UMTX_SHARED_QUEUE], uq_link) {
386 if (umtx_key_match(&uq->uq_key, key)) {
396 * Wake up threads waiting on an userland object.
400 umtxq_signal_queue(struct umtx_key *key, int n_wake, int q)
402 struct umtxq_chain *uc;
403 struct umtx_q *uq, *next;
407 uc = umtxq_getchain(key);
408 UMTXQ_LOCKED_ASSERT(uc);
409 TAILQ_FOREACH_SAFE(uq, &uc->uc_queue[q], uq_link, next) {
410 if (umtx_key_match(&uq->uq_key, key)) {
411 umtxq_remove_queue(uq, q);
422 * Wake up specified thread.
425 umtxq_signal_thread(struct umtx_q *uq)
427 struct umtxq_chain *uc;
429 uc = umtxq_getchain(&uq->uq_key);
430 UMTXQ_LOCKED_ASSERT(uc);
436 * Put thread into sleep state, before sleeping, check if
437 * thread was removed from umtx queue.
440 umtxq_sleep(struct umtx_q *uq, const char *wmesg, int timo)
442 struct umtxq_chain *uc;
445 uc = umtxq_getchain(&uq->uq_key);
446 UMTXQ_LOCKED_ASSERT(uc);
447 if (!(uq->uq_flags & UQF_UMTXQ))
449 error = msleep(uq, &uc->uc_lock, PCATCH, wmesg, timo);
450 if (error == EWOULDBLOCK)
456 * Convert userspace address into unique logical address.
459 umtx_key_get(void *addr, int type, int share, struct umtx_key *key)
461 struct thread *td = curthread;
463 vm_map_entry_t entry;
469 if (share == THREAD_SHARE) {
471 key->info.private.vs = td->td_proc->p_vmspace;
472 key->info.private.addr = (uintptr_t)addr;
474 MPASS(share == PROCESS_SHARE || share == AUTO_SHARE);
475 map = &td->td_proc->p_vmspace->vm_map;
476 if (vm_map_lookup(&map, (vm_offset_t)addr, VM_PROT_WRITE,
477 &entry, &key->info.shared.object, &pindex, &prot,
478 &wired) != KERN_SUCCESS) {
482 if ((share == PROCESS_SHARE) ||
483 (share == AUTO_SHARE &&
484 VM_INHERIT_SHARE == entry->inheritance)) {
486 key->info.shared.offset = entry->offset + entry->start -
488 vm_object_reference(key->info.shared.object);
491 key->info.private.vs = td->td_proc->p_vmspace;
492 key->info.private.addr = (uintptr_t)addr;
494 vm_map_lookup_done(map, entry);
505 umtx_key_release(struct umtx_key *key)
508 vm_object_deallocate(key->info.shared.object);
512 * Lock a umtx object.
515 _do_lock_umtx(struct thread *td, struct umtx *umtx, u_long id, int timo)
525 * Care must be exercised when dealing with umtx structure. It
526 * can fault on any access.
530 * Try the uncontested case. This should be done in userland.
532 owner = casuword(&umtx->u_owner, UMTX_UNOWNED, id);
534 /* The acquire succeeded. */
535 if (owner == UMTX_UNOWNED)
538 /* The address was invalid. */
542 /* If no one owns it but it is contested try to acquire it. */
543 if (owner == UMTX_CONTESTED) {
544 owner = casuword(&umtx->u_owner,
545 UMTX_CONTESTED, id | UMTX_CONTESTED);
547 if (owner == UMTX_CONTESTED)
550 /* The address was invalid. */
554 /* If this failed the lock has changed, restart. */
559 * If we caught a signal, we have retried and now
565 if ((error = umtx_key_get(umtx, TYPE_SIMPLE_LOCK,
566 AUTO_SHARE, &uq->uq_key)) != 0)
569 umtxq_lock(&uq->uq_key);
570 umtxq_busy(&uq->uq_key);
572 umtxq_unbusy(&uq->uq_key);
573 umtxq_unlock(&uq->uq_key);
576 * Set the contested bit so that a release in user space
577 * knows to use the system call for unlock. If this fails
578 * either some one else has acquired the lock or it has been
581 old = casuword(&umtx->u_owner, owner, owner | UMTX_CONTESTED);
583 /* The address was invalid. */
585 umtxq_lock(&uq->uq_key);
587 umtxq_unlock(&uq->uq_key);
588 umtx_key_release(&uq->uq_key);
593 * We set the contested bit, sleep. Otherwise the lock changed
594 * and we need to retry or we lost a race to the thread
595 * unlocking the umtx.
597 umtxq_lock(&uq->uq_key);
599 error = umtxq_sleep(uq, "umtx", timo);
601 umtxq_unlock(&uq->uq_key);
602 umtx_key_release(&uq->uq_key);
609 * Lock a umtx object.
612 do_lock_umtx(struct thread *td, struct umtx *umtx, u_long id,
613 struct timespec *timeout)
615 struct timespec ts, ts2, ts3;
619 if (timeout == NULL) {
620 error = _do_lock_umtx(td, umtx, id, 0);
621 /* Mutex locking is restarted if it is interrupted. */
626 timespecadd(&ts, timeout);
627 TIMESPEC_TO_TIMEVAL(&tv, timeout);
629 error = _do_lock_umtx(td, umtx, id, tvtohz(&tv));
630 if (error != ETIMEDOUT)
633 if (timespeccmp(&ts2, &ts, >=)) {
638 timespecsub(&ts3, &ts2);
639 TIMESPEC_TO_TIMEVAL(&tv, &ts3);
641 /* Timed-locking is not restarted. */
642 if (error == ERESTART)
649 * Unlock a umtx object.
652 do_unlock_umtx(struct thread *td, struct umtx *umtx, u_long id)
661 * Make sure we own this mtx.
663 owner = fuword(__DEVOLATILE(u_long *, &umtx->u_owner));
667 if ((owner & ~UMTX_CONTESTED) != id)
670 /* This should be done in userland */
671 if ((owner & UMTX_CONTESTED) == 0) {
672 old = casuword(&umtx->u_owner, owner, UMTX_UNOWNED);
680 /* We should only ever be in here for contested locks */
681 if ((error = umtx_key_get(umtx, TYPE_SIMPLE_LOCK, AUTO_SHARE,
687 count = umtxq_count(&key);
691 * When unlocking the umtx, it must be marked as unowned if
692 * there is zero or one thread only waiting for it.
693 * Otherwise, it must be marked as contested.
695 old = casuword(&umtx->u_owner, owner,
696 count <= 1 ? UMTX_UNOWNED : UMTX_CONTESTED);
698 umtxq_signal(&key,1);
701 umtx_key_release(&key);
709 #ifdef COMPAT_FREEBSD32
712 * Lock a umtx object.
715 _do_lock_umtx32(struct thread *td, uint32_t *m, uint32_t id, int timo)
725 * Care must be exercised when dealing with umtx structure. It
726 * can fault on any access.
730 * Try the uncontested case. This should be done in userland.
732 owner = casuword32(m, UMUTEX_UNOWNED, id);
734 /* The acquire succeeded. */
735 if (owner == UMUTEX_UNOWNED)
738 /* The address was invalid. */
742 /* If no one owns it but it is contested try to acquire it. */
743 if (owner == UMUTEX_CONTESTED) {
744 owner = casuword32(m,
745 UMUTEX_CONTESTED, id | UMUTEX_CONTESTED);
746 if (owner == UMUTEX_CONTESTED)
749 /* The address was invalid. */
753 /* If this failed the lock has changed, restart. */
758 * If we caught a signal, we have retried and now
764 if ((error = umtx_key_get(m, TYPE_SIMPLE_LOCK,
765 AUTO_SHARE, &uq->uq_key)) != 0)
768 umtxq_lock(&uq->uq_key);
769 umtxq_busy(&uq->uq_key);
771 umtxq_unbusy(&uq->uq_key);
772 umtxq_unlock(&uq->uq_key);
775 * Set the contested bit so that a release in user space
776 * knows to use the system call for unlock. If this fails
777 * either some one else has acquired the lock or it has been
780 old = casuword32(m, owner, owner | UMUTEX_CONTESTED);
782 /* The address was invalid. */
784 umtxq_lock(&uq->uq_key);
786 umtxq_unlock(&uq->uq_key);
787 umtx_key_release(&uq->uq_key);
792 * We set the contested bit, sleep. Otherwise the lock changed
793 * and we need to retry or we lost a race to the thread
794 * unlocking the umtx.
796 umtxq_lock(&uq->uq_key);
798 error = umtxq_sleep(uq, "umtx", timo);
800 umtxq_unlock(&uq->uq_key);
801 umtx_key_release(&uq->uq_key);
808 * Lock a umtx object.
811 do_lock_umtx32(struct thread *td, void *m, uint32_t id,
812 struct timespec *timeout)
814 struct timespec ts, ts2, ts3;
818 if (timeout == NULL) {
819 error = _do_lock_umtx32(td, m, id, 0);
820 /* Mutex locking is restarted if it is interrupted. */
825 timespecadd(&ts, timeout);
826 TIMESPEC_TO_TIMEVAL(&tv, timeout);
828 error = _do_lock_umtx32(td, m, id, tvtohz(&tv));
829 if (error != ETIMEDOUT)
832 if (timespeccmp(&ts2, &ts, >=)) {
837 timespecsub(&ts3, &ts2);
838 TIMESPEC_TO_TIMEVAL(&tv, &ts3);
840 /* Timed-locking is not restarted. */
841 if (error == ERESTART)
848 * Unlock a umtx object.
851 do_unlock_umtx32(struct thread *td, uint32_t *m, uint32_t id)
860 * Make sure we own this mtx.
866 if ((owner & ~UMUTEX_CONTESTED) != id)
869 /* This should be done in userland */
870 if ((owner & UMUTEX_CONTESTED) == 0) {
871 old = casuword32(m, owner, UMUTEX_UNOWNED);
879 /* We should only ever be in here for contested locks */
880 if ((error = umtx_key_get(m, TYPE_SIMPLE_LOCK, AUTO_SHARE,
886 count = umtxq_count(&key);
890 * When unlocking the umtx, it must be marked as unowned if
891 * there is zero or one thread only waiting for it.
892 * Otherwise, it must be marked as contested.
894 old = casuword32(m, owner,
895 count <= 1 ? UMUTEX_UNOWNED : UMUTEX_CONTESTED);
897 umtxq_signal(&key,1);
900 umtx_key_release(&key);
910 * Fetch and compare value, sleep on the address if value is not changed.
913 do_wait(struct thread *td, void *addr, u_long id,
914 struct timespec *timeout, int compat32, int is_private)
917 struct timespec ts, ts2, ts3;
923 if ((error = umtx_key_get(addr, TYPE_SIMPLE_WAIT,
924 is_private ? THREAD_SHARE : AUTO_SHARE, &uq->uq_key)) != 0)
927 umtxq_lock(&uq->uq_key);
929 umtxq_unlock(&uq->uq_key);
933 tmp = (unsigned int)fuword32(addr);
935 umtxq_lock(&uq->uq_key);
937 umtxq_unlock(&uq->uq_key);
938 } else if (timeout == NULL) {
939 umtxq_lock(&uq->uq_key);
940 error = umtxq_sleep(uq, "uwait", 0);
942 umtxq_unlock(&uq->uq_key);
945 timespecadd(&ts, timeout);
946 TIMESPEC_TO_TIMEVAL(&tv, timeout);
947 umtxq_lock(&uq->uq_key);
949 error = umtxq_sleep(uq, "uwait", tvtohz(&tv));
950 if (!(uq->uq_flags & UQF_UMTXQ))
952 if (error != ETIMEDOUT)
954 umtxq_unlock(&uq->uq_key);
956 if (timespeccmp(&ts2, &ts, >=)) {
958 umtxq_lock(&uq->uq_key);
962 timespecsub(&ts3, &ts2);
963 TIMESPEC_TO_TIMEVAL(&tv, &ts3);
964 umtxq_lock(&uq->uq_key);
967 umtxq_unlock(&uq->uq_key);
969 umtx_key_release(&uq->uq_key);
970 if (error == ERESTART)
976 * Wake up threads sleeping on the specified address.
979 kern_umtx_wake(struct thread *td, void *uaddr, int n_wake, int is_private)
984 if ((ret = umtx_key_get(uaddr, TYPE_SIMPLE_WAIT,
985 is_private ? THREAD_SHARE : AUTO_SHARE, &key)) != 0)
988 ret = umtxq_signal(&key, n_wake);
990 umtx_key_release(&key);
995 * Lock PTHREAD_PRIO_NONE protocol POSIX mutex.
998 _do_lock_normal(struct thread *td, struct umutex *m, uint32_t flags, int timo,
1002 uint32_t owner, old, id;
1009 * Care must be exercised when dealing with umtx structure. It
1010 * can fault on any access.
1013 owner = fuword32(__DEVOLATILE(void *, &m->m_owner));
1014 if (mode == _UMUTEX_WAIT) {
1015 if (owner == UMUTEX_UNOWNED || owner == UMUTEX_CONTESTED)
1019 * Try the uncontested case. This should be done in userland.
1021 owner = casuword32(&m->m_owner, UMUTEX_UNOWNED, id);
1023 /* The acquire succeeded. */
1024 if (owner == UMUTEX_UNOWNED)
1027 /* The address was invalid. */
1031 /* If no one owns it but it is contested try to acquire it. */
1032 if (owner == UMUTEX_CONTESTED) {
1033 owner = casuword32(&m->m_owner,
1034 UMUTEX_CONTESTED, id | UMUTEX_CONTESTED);
1036 if (owner == UMUTEX_CONTESTED)
1039 /* The address was invalid. */
1043 /* If this failed the lock has changed, restart. */
1048 if ((flags & UMUTEX_ERROR_CHECK) != 0 &&
1049 (owner & ~UMUTEX_CONTESTED) == id)
1052 if (mode == _UMUTEX_TRY)
1056 * If we caught a signal, we have retried and now
1062 if ((error = umtx_key_get(m, TYPE_NORMAL_UMUTEX,
1063 GET_SHARE(flags), &uq->uq_key)) != 0)
1066 umtxq_lock(&uq->uq_key);
1067 umtxq_busy(&uq->uq_key);
1069 umtxq_unlock(&uq->uq_key);
1072 * Set the contested bit so that a release in user space
1073 * knows to use the system call for unlock. If this fails
1074 * either some one else has acquired the lock or it has been
1077 old = casuword32(&m->m_owner, owner, owner | UMUTEX_CONTESTED);
1079 /* The address was invalid. */
1081 umtxq_lock(&uq->uq_key);
1083 umtxq_unbusy(&uq->uq_key);
1084 umtxq_unlock(&uq->uq_key);
1085 umtx_key_release(&uq->uq_key);
1090 * We set the contested bit, sleep. Otherwise the lock changed
1091 * and we need to retry or we lost a race to the thread
1092 * unlocking the umtx.
1094 umtxq_lock(&uq->uq_key);
1095 umtxq_unbusy(&uq->uq_key);
1097 error = umtxq_sleep(uq, "umtxn", timo);
1099 umtxq_unlock(&uq->uq_key);
1100 umtx_key_release(&uq->uq_key);
1107 * Lock PTHREAD_PRIO_NONE protocol POSIX mutex.
1110 * Unlock PTHREAD_PRIO_NONE protocol POSIX mutex.
1113 do_unlock_normal(struct thread *td, struct umutex *m, uint32_t flags)
1115 struct umtx_key key;
1116 uint32_t owner, old, id;
1122 * Make sure we own this mtx.
1124 owner = fuword32(__DEVOLATILE(uint32_t *, &m->m_owner));
1128 if ((owner & ~UMUTEX_CONTESTED) != id)
1131 if ((owner & UMUTEX_CONTESTED) == 0) {
1132 old = casuword32(&m->m_owner, owner, UMUTEX_UNOWNED);
1140 /* We should only ever be in here for contested locks */
1141 if ((error = umtx_key_get(m, TYPE_NORMAL_UMUTEX, GET_SHARE(flags),
1147 count = umtxq_count(&key);
1151 * When unlocking the umtx, it must be marked as unowned if
1152 * there is zero or one thread only waiting for it.
1153 * Otherwise, it must be marked as contested.
1155 old = casuword32(&m->m_owner, owner,
1156 count <= 1 ? UMUTEX_UNOWNED : UMUTEX_CONTESTED);
1158 umtxq_signal(&key,1);
1161 umtx_key_release(&key);
1170 * Check if the mutex is available and wake up a waiter,
1171 * only for simple mutex.
1174 do_wake_umutex(struct thread *td, struct umutex *m)
1176 struct umtx_key key;
1182 owner = fuword32(__DEVOLATILE(uint32_t *, &m->m_owner));
1186 if ((owner & ~UMUTEX_CONTESTED) != 0)
1189 flags = fuword32(&m->m_flags);
1191 /* We should only ever be in here for contested locks */
1192 if ((error = umtx_key_get(m, TYPE_NORMAL_UMUTEX, GET_SHARE(flags),
1198 count = umtxq_count(&key);
1202 owner = casuword32(&m->m_owner, UMUTEX_CONTESTED, UMUTEX_UNOWNED);
1205 if (count != 0 && (owner & ~UMUTEX_CONTESTED) == 0)
1206 umtxq_signal(&key, 1);
1209 umtx_key_release(&key);
1213 static inline struct umtx_pi *
1214 umtx_pi_alloc(int flags)
1218 pi = uma_zalloc(umtx_pi_zone, M_ZERO | flags);
1219 TAILQ_INIT(&pi->pi_blocked);
1220 atomic_add_int(&umtx_pi_allocated, 1);
1225 umtx_pi_free(struct umtx_pi *pi)
1227 uma_zfree(umtx_pi_zone, pi);
1228 atomic_add_int(&umtx_pi_allocated, -1);
1232 * Adjust the thread's position on a pi_state after its priority has been
1236 umtx_pi_adjust_thread(struct umtx_pi *pi, struct thread *td)
1238 struct umtx_q *uq, *uq1, *uq2;
1241 mtx_assert(&umtx_lock, MA_OWNED);
1248 * Check if the thread needs to be moved on the blocked chain.
1249 * It needs to be moved if either its priority is lower than
1250 * the previous thread or higher than the next thread.
1252 uq1 = TAILQ_PREV(uq, umtxq_head, uq_lockq);
1253 uq2 = TAILQ_NEXT(uq, uq_lockq);
1254 if ((uq1 != NULL && UPRI(td) < UPRI(uq1->uq_thread)) ||
1255 (uq2 != NULL && UPRI(td) > UPRI(uq2->uq_thread))) {
1257 * Remove thread from blocked chain and determine where
1258 * it should be moved to.
1260 TAILQ_REMOVE(&pi->pi_blocked, uq, uq_lockq);
1261 TAILQ_FOREACH(uq1, &pi->pi_blocked, uq_lockq) {
1262 td1 = uq1->uq_thread;
1263 MPASS(td1->td_proc->p_magic == P_MAGIC);
1264 if (UPRI(td1) > UPRI(td))
1269 TAILQ_INSERT_TAIL(&pi->pi_blocked, uq, uq_lockq);
1271 TAILQ_INSERT_BEFORE(uq1, uq, uq_lockq);
1277 * Propagate priority when a thread is blocked on POSIX
1281 umtx_propagate_priority(struct thread *td)
1287 mtx_assert(&umtx_lock, MA_OWNED);
1290 pi = uq->uq_pi_blocked;
1299 MPASS(td->td_proc != NULL);
1300 MPASS(td->td_proc->p_magic == P_MAGIC);
1302 if (UPRI(td) <= pri)
1306 sched_lend_user_prio(td, pri);
1310 * Pick up the lock that td is blocked on.
1313 pi = uq->uq_pi_blocked;
1314 /* Resort td on the list if needed. */
1315 if (!umtx_pi_adjust_thread(pi, td))
1321 * Unpropagate priority for a PI mutex when a thread blocked on
1322 * it is interrupted by signal or resumed by others.
1325 umtx_unpropagate_priority(struct umtx_pi *pi)
1327 struct umtx_q *uq, *uq_owner;
1328 struct umtx_pi *pi2;
1331 mtx_assert(&umtx_lock, MA_OWNED);
1333 while (pi != NULL && pi->pi_owner != NULL) {
1335 uq_owner = pi->pi_owner->td_umtxq;
1337 TAILQ_FOREACH(pi2, &uq_owner->uq_pi_contested, pi_link) {
1338 uq = TAILQ_FIRST(&pi2->pi_blocked);
1340 if (pri > UPRI(uq->uq_thread))
1341 pri = UPRI(uq->uq_thread);
1345 if (pri > uq_owner->uq_inherited_pri)
1346 pri = uq_owner->uq_inherited_pri;
1347 thread_lock(pi->pi_owner);
1348 oldpri = pi->pi_owner->td_user_pri;
1349 sched_unlend_user_prio(pi->pi_owner, pri);
1350 thread_unlock(pi->pi_owner);
1351 if (uq_owner->uq_pi_blocked != NULL)
1352 umtx_pi_adjust_locked(pi->pi_owner, oldpri);
1353 pi = uq_owner->uq_pi_blocked;
1358 * Insert a PI mutex into owned list.
1361 umtx_pi_setowner(struct umtx_pi *pi, struct thread *owner)
1363 struct umtx_q *uq_owner;
1365 uq_owner = owner->td_umtxq;
1366 mtx_assert(&umtx_lock, MA_OWNED);
1367 if (pi->pi_owner != NULL)
1368 panic("pi_ower != NULL");
1369 pi->pi_owner = owner;
1370 TAILQ_INSERT_TAIL(&uq_owner->uq_pi_contested, pi, pi_link);
1374 * Claim ownership of a PI mutex.
1377 umtx_pi_claim(struct umtx_pi *pi, struct thread *owner)
1379 struct umtx_q *uq, *uq_owner;
1381 uq_owner = owner->td_umtxq;
1382 mtx_lock_spin(&umtx_lock);
1383 if (pi->pi_owner == owner) {
1384 mtx_unlock_spin(&umtx_lock);
1388 if (pi->pi_owner != NULL) {
1390 * userland may have already messed the mutex, sigh.
1392 mtx_unlock_spin(&umtx_lock);
1395 umtx_pi_setowner(pi, owner);
1396 uq = TAILQ_FIRST(&pi->pi_blocked);
1400 pri = UPRI(uq->uq_thread);
1402 if (pri < UPRI(owner))
1403 sched_lend_user_prio(owner, pri);
1404 thread_unlock(owner);
1406 mtx_unlock_spin(&umtx_lock);
1411 umtx_pi_adjust_locked(struct thread *td, u_char oldpri)
1418 * Pick up the lock that td is blocked on.
1420 pi = uq->uq_pi_blocked;
1423 /* Resort the turnstile on the list. */
1424 if (!umtx_pi_adjust_thread(pi, td))
1428 * If our priority was lowered and we are at the head of the
1429 * turnstile, then propagate our new priority up the chain.
1431 if (uq == TAILQ_FIRST(&pi->pi_blocked) && UPRI(td) < oldpri)
1432 umtx_propagate_priority(td);
1436 * Adjust a thread's order position in its blocked PI mutex,
1437 * this may result new priority propagating process.
1440 umtx_pi_adjust(struct thread *td, u_char oldpri)
1446 mtx_lock_spin(&umtx_lock);
1448 * Pick up the lock that td is blocked on.
1450 pi = uq->uq_pi_blocked;
1452 umtx_pi_adjust_locked(td, oldpri);
1453 mtx_unlock_spin(&umtx_lock);
1457 * Sleep on a PI mutex.
1460 umtxq_sleep_pi(struct umtx_q *uq, struct umtx_pi *pi,
1461 uint32_t owner, const char *wmesg, int timo)
1463 struct umtxq_chain *uc;
1464 struct thread *td, *td1;
1470 KASSERT(td == curthread, ("inconsistent uq_thread"));
1471 uc = umtxq_getchain(&uq->uq_key);
1472 UMTXQ_LOCKED_ASSERT(uc);
1473 UMTXQ_BUSY_ASSERT(uc);
1475 mtx_lock_spin(&umtx_lock);
1476 if (pi->pi_owner == NULL) {
1478 * Current, We only support process private PI-mutex,
1479 * non-contended PI-mutexes are locked in userland.
1480 * Process shared PI-mutex should always be initialized
1481 * by kernel and be registered in kernel, locking should
1482 * always be done by kernel to avoid security problems.
1483 * For process private PI-mutex, we can find owner
1484 * thread and boost its priority safely.
1486 mtx_unlock_spin(&umtx_lock);
1488 td1 = thread_find(curproc, owner);
1489 mtx_lock_spin(&umtx_lock);
1490 if (td1 != NULL && pi->pi_owner == NULL) {
1491 uq1 = td1->td_umtxq;
1492 umtx_pi_setowner(pi, td1);
1494 PROC_UNLOCK(curproc);
1497 TAILQ_FOREACH(uq1, &pi->pi_blocked, uq_lockq) {
1498 pri = UPRI(uq1->uq_thread);
1504 TAILQ_INSERT_BEFORE(uq1, uq, uq_lockq);
1506 TAILQ_INSERT_TAIL(&pi->pi_blocked, uq, uq_lockq);
1508 uq->uq_pi_blocked = pi;
1510 td->td_flags |= TDF_UPIBLOCKED;
1512 umtx_propagate_priority(td);
1513 mtx_unlock_spin(&umtx_lock);
1514 umtxq_unbusy(&uq->uq_key);
1516 if (uq->uq_flags & UQF_UMTXQ) {
1517 error = msleep(uq, &uc->uc_lock, PCATCH, wmesg, timo);
1518 if (error == EWOULDBLOCK)
1520 if (uq->uq_flags & UQF_UMTXQ) {
1524 mtx_lock_spin(&umtx_lock);
1525 uq->uq_pi_blocked = NULL;
1527 td->td_flags &= ~TDF_UPIBLOCKED;
1529 TAILQ_REMOVE(&pi->pi_blocked, uq, uq_lockq);
1530 umtx_unpropagate_priority(pi);
1531 mtx_unlock_spin(&umtx_lock);
1532 umtxq_unlock(&uq->uq_key);
1538 * Add reference count for a PI mutex.
1541 umtx_pi_ref(struct umtx_pi *pi)
1543 struct umtxq_chain *uc;
1545 uc = umtxq_getchain(&pi->pi_key);
1546 UMTXQ_LOCKED_ASSERT(uc);
1551 * Decrease reference count for a PI mutex, if the counter
1552 * is decreased to zero, its memory space is freed.
1555 umtx_pi_unref(struct umtx_pi *pi)
1557 struct umtxq_chain *uc;
1559 uc = umtxq_getchain(&pi->pi_key);
1560 UMTXQ_LOCKED_ASSERT(uc);
1561 KASSERT(pi->pi_refcount > 0, ("invalid reference count"));
1562 if (--pi->pi_refcount == 0) {
1563 mtx_lock_spin(&umtx_lock);
1564 if (pi->pi_owner != NULL) {
1565 TAILQ_REMOVE(&pi->pi_owner->td_umtxq->uq_pi_contested,
1567 pi->pi_owner = NULL;
1569 KASSERT(TAILQ_EMPTY(&pi->pi_blocked),
1570 ("blocked queue not empty"));
1571 mtx_unlock_spin(&umtx_lock);
1572 TAILQ_REMOVE(&uc->uc_pi_list, pi, pi_hashlink);
1578 * Find a PI mutex in hash table.
1580 static struct umtx_pi *
1581 umtx_pi_lookup(struct umtx_key *key)
1583 struct umtxq_chain *uc;
1586 uc = umtxq_getchain(key);
1587 UMTXQ_LOCKED_ASSERT(uc);
1589 TAILQ_FOREACH(pi, &uc->uc_pi_list, pi_hashlink) {
1590 if (umtx_key_match(&pi->pi_key, key)) {
1598 * Insert a PI mutex into hash table.
1601 umtx_pi_insert(struct umtx_pi *pi)
1603 struct umtxq_chain *uc;
1605 uc = umtxq_getchain(&pi->pi_key);
1606 UMTXQ_LOCKED_ASSERT(uc);
1607 TAILQ_INSERT_TAIL(&uc->uc_pi_list, pi, pi_hashlink);
1614 _do_lock_pi(struct thread *td, struct umutex *m, uint32_t flags, int timo,
1618 struct umtx_pi *pi, *new_pi;
1619 uint32_t id, owner, old;
1625 if ((error = umtx_key_get(m, TYPE_PI_UMUTEX, GET_SHARE(flags),
1628 umtxq_lock(&uq->uq_key);
1629 pi = umtx_pi_lookup(&uq->uq_key);
1631 new_pi = umtx_pi_alloc(M_NOWAIT);
1632 if (new_pi == NULL) {
1633 umtxq_unlock(&uq->uq_key);
1634 new_pi = umtx_pi_alloc(M_WAITOK);
1635 umtxq_lock(&uq->uq_key);
1636 pi = umtx_pi_lookup(&uq->uq_key);
1638 umtx_pi_free(new_pi);
1642 if (new_pi != NULL) {
1643 new_pi->pi_key = uq->uq_key;
1644 umtx_pi_insert(new_pi);
1649 umtxq_unlock(&uq->uq_key);
1652 * Care must be exercised when dealing with umtx structure. It
1653 * can fault on any access.
1657 * Try the uncontested case. This should be done in userland.
1659 owner = casuword32(&m->m_owner, UMUTEX_UNOWNED, id);
1661 /* The acquire succeeded. */
1662 if (owner == UMUTEX_UNOWNED) {
1667 /* The address was invalid. */
1673 /* If no one owns it but it is contested try to acquire it. */
1674 if (owner == UMUTEX_CONTESTED) {
1675 owner = casuword32(&m->m_owner,
1676 UMUTEX_CONTESTED, id | UMUTEX_CONTESTED);
1678 if (owner == UMUTEX_CONTESTED) {
1679 umtxq_lock(&uq->uq_key);
1680 umtxq_busy(&uq->uq_key);
1681 error = umtx_pi_claim(pi, td);
1682 umtxq_unbusy(&uq->uq_key);
1683 umtxq_unlock(&uq->uq_key);
1687 /* The address was invalid. */
1693 /* If this failed the lock has changed, restart. */
1697 if ((flags & UMUTEX_ERROR_CHECK) != 0 &&
1698 (owner & ~UMUTEX_CONTESTED) == id) {
1709 * If we caught a signal, we have retried and now
1715 umtxq_lock(&uq->uq_key);
1716 umtxq_busy(&uq->uq_key);
1717 umtxq_unlock(&uq->uq_key);
1720 * Set the contested bit so that a release in user space
1721 * knows to use the system call for unlock. If this fails
1722 * either some one else has acquired the lock or it has been
1725 old = casuword32(&m->m_owner, owner, owner | UMUTEX_CONTESTED);
1727 /* The address was invalid. */
1729 umtxq_lock(&uq->uq_key);
1730 umtxq_unbusy(&uq->uq_key);
1731 umtxq_unlock(&uq->uq_key);
1736 umtxq_lock(&uq->uq_key);
1738 * We set the contested bit, sleep. Otherwise the lock changed
1739 * and we need to retry or we lost a race to the thread
1740 * unlocking the umtx.
1743 error = umtxq_sleep_pi(uq, pi, owner & ~UMUTEX_CONTESTED,
1746 umtxq_unbusy(&uq->uq_key);
1747 umtxq_unlock(&uq->uq_key);
1751 umtxq_lock(&uq->uq_key);
1753 umtxq_unlock(&uq->uq_key);
1755 umtx_key_release(&uq->uq_key);
1760 * Unlock a PI mutex.
1763 do_unlock_pi(struct thread *td, struct umutex *m, uint32_t flags)
1765 struct umtx_key key;
1766 struct umtx_q *uq_first, *uq_first2, *uq_me;
1767 struct umtx_pi *pi, *pi2;
1768 uint32_t owner, old, id;
1775 * Make sure we own this mtx.
1777 owner = fuword32(__DEVOLATILE(uint32_t *, &m->m_owner));
1781 if ((owner & ~UMUTEX_CONTESTED) != id)
1784 /* This should be done in userland */
1785 if ((owner & UMUTEX_CONTESTED) == 0) {
1786 old = casuword32(&m->m_owner, owner, UMUTEX_UNOWNED);
1794 /* We should only ever be in here for contested locks */
1795 if ((error = umtx_key_get(m, TYPE_PI_UMUTEX, GET_SHARE(flags),
1801 count = umtxq_count_pi(&key, &uq_first);
1802 if (uq_first != NULL) {
1803 mtx_lock_spin(&umtx_lock);
1804 pi = uq_first->uq_pi_blocked;
1805 KASSERT(pi != NULL, ("pi == NULL?"));
1806 if (pi->pi_owner != curthread) {
1807 mtx_unlock_spin(&umtx_lock);
1810 umtx_key_release(&key);
1811 /* userland messed the mutex */
1814 uq_me = curthread->td_umtxq;
1815 pi->pi_owner = NULL;
1816 TAILQ_REMOVE(&uq_me->uq_pi_contested, pi, pi_link);
1817 /* get highest priority thread which is still sleeping. */
1818 uq_first = TAILQ_FIRST(&pi->pi_blocked);
1819 while (uq_first != NULL &&
1820 (uq_first->uq_flags & UQF_UMTXQ) == 0) {
1821 uq_first = TAILQ_NEXT(uq_first, uq_lockq);
1824 TAILQ_FOREACH(pi2, &uq_me->uq_pi_contested, pi_link) {
1825 uq_first2 = TAILQ_FIRST(&pi2->pi_blocked);
1826 if (uq_first2 != NULL) {
1827 if (pri > UPRI(uq_first2->uq_thread))
1828 pri = UPRI(uq_first2->uq_thread);
1831 thread_lock(curthread);
1832 sched_unlend_user_prio(curthread, pri);
1833 thread_unlock(curthread);
1834 mtx_unlock_spin(&umtx_lock);
1836 umtxq_signal_thread(uq_first);
1841 * When unlocking the umtx, it must be marked as unowned if
1842 * there is zero or one thread only waiting for it.
1843 * Otherwise, it must be marked as contested.
1845 old = casuword32(&m->m_owner, owner,
1846 count <= 1 ? UMUTEX_UNOWNED : UMUTEX_CONTESTED);
1851 umtx_key_release(&key);
1863 _do_lock_pp(struct thread *td, struct umutex *m, uint32_t flags, int timo,
1866 struct umtx_q *uq, *uq2;
1870 int error, pri, old_inherited_pri, su;
1874 if ((error = umtx_key_get(m, TYPE_PP_UMUTEX, GET_SHARE(flags),
1877 su = (priv_check(td, PRIV_SCHED_RTPRIO) == 0);
1879 old_inherited_pri = uq->uq_inherited_pri;
1880 umtxq_lock(&uq->uq_key);
1881 umtxq_busy(&uq->uq_key);
1882 umtxq_unlock(&uq->uq_key);
1884 ceiling = RTP_PRIO_MAX - fuword32(&m->m_ceilings[0]);
1885 if (ceiling > RTP_PRIO_MAX) {
1890 mtx_lock_spin(&umtx_lock);
1891 if (UPRI(td) < PRI_MIN_REALTIME + ceiling) {
1892 mtx_unlock_spin(&umtx_lock);
1896 if (su && PRI_MIN_REALTIME + ceiling < uq->uq_inherited_pri) {
1897 uq->uq_inherited_pri = PRI_MIN_REALTIME + ceiling;
1899 if (uq->uq_inherited_pri < UPRI(td))
1900 sched_lend_user_prio(td, uq->uq_inherited_pri);
1903 mtx_unlock_spin(&umtx_lock);
1905 owner = casuword32(&m->m_owner,
1906 UMUTEX_CONTESTED, id | UMUTEX_CONTESTED);
1908 if (owner == UMUTEX_CONTESTED) {
1913 /* The address was invalid. */
1919 if ((flags & UMUTEX_ERROR_CHECK) != 0 &&
1920 (owner & ~UMUTEX_CONTESTED) == id) {
1931 * If we caught a signal, we have retried and now
1937 umtxq_lock(&uq->uq_key);
1939 umtxq_unbusy(&uq->uq_key);
1940 error = umtxq_sleep(uq, "umtxpp", timo);
1942 umtxq_unlock(&uq->uq_key);
1944 mtx_lock_spin(&umtx_lock);
1945 uq->uq_inherited_pri = old_inherited_pri;
1947 TAILQ_FOREACH(pi, &uq->uq_pi_contested, pi_link) {
1948 uq2 = TAILQ_FIRST(&pi->pi_blocked);
1950 if (pri > UPRI(uq2->uq_thread))
1951 pri = UPRI(uq2->uq_thread);
1954 if (pri > uq->uq_inherited_pri)
1955 pri = uq->uq_inherited_pri;
1957 sched_unlend_user_prio(td, pri);
1959 mtx_unlock_spin(&umtx_lock);
1963 mtx_lock_spin(&umtx_lock);
1964 uq->uq_inherited_pri = old_inherited_pri;
1966 TAILQ_FOREACH(pi, &uq->uq_pi_contested, pi_link) {
1967 uq2 = TAILQ_FIRST(&pi->pi_blocked);
1969 if (pri > UPRI(uq2->uq_thread))
1970 pri = UPRI(uq2->uq_thread);
1973 if (pri > uq->uq_inherited_pri)
1974 pri = uq->uq_inherited_pri;
1976 sched_unlend_user_prio(td, pri);
1978 mtx_unlock_spin(&umtx_lock);
1982 umtxq_lock(&uq->uq_key);
1983 umtxq_unbusy(&uq->uq_key);
1984 umtxq_unlock(&uq->uq_key);
1985 umtx_key_release(&uq->uq_key);
1990 * Unlock a PP mutex.
1993 do_unlock_pp(struct thread *td, struct umutex *m, uint32_t flags)
1995 struct umtx_key key;
1996 struct umtx_q *uq, *uq2;
2000 int error, pri, new_inherited_pri, su;
2004 su = (priv_check(td, PRIV_SCHED_RTPRIO) == 0);
2007 * Make sure we own this mtx.
2009 owner = fuword32(__DEVOLATILE(uint32_t *, &m->m_owner));
2013 if ((owner & ~UMUTEX_CONTESTED) != id)
2016 error = copyin(&m->m_ceilings[1], &rceiling, sizeof(uint32_t));
2021 new_inherited_pri = PRI_MAX;
2023 rceiling = RTP_PRIO_MAX - rceiling;
2024 if (rceiling > RTP_PRIO_MAX)
2026 new_inherited_pri = PRI_MIN_REALTIME + rceiling;
2029 if ((error = umtx_key_get(m, TYPE_PP_UMUTEX, GET_SHARE(flags),
2036 * For priority protected mutex, always set unlocked state
2037 * to UMUTEX_CONTESTED, so that userland always enters kernel
2038 * to lock the mutex, it is necessary because thread priority
2039 * has to be adjusted for such mutex.
2041 error = suword32(__DEVOLATILE(uint32_t *, &m->m_owner),
2046 umtxq_signal(&key, 1);
2053 mtx_lock_spin(&umtx_lock);
2055 uq->uq_inherited_pri = new_inherited_pri;
2057 TAILQ_FOREACH(pi, &uq->uq_pi_contested, pi_link) {
2058 uq2 = TAILQ_FIRST(&pi->pi_blocked);
2060 if (pri > UPRI(uq2->uq_thread))
2061 pri = UPRI(uq2->uq_thread);
2064 if (pri > uq->uq_inherited_pri)
2065 pri = uq->uq_inherited_pri;
2067 sched_unlend_user_prio(td, pri);
2069 mtx_unlock_spin(&umtx_lock);
2071 umtx_key_release(&key);
2076 do_set_ceiling(struct thread *td, struct umutex *m, uint32_t ceiling,
2077 uint32_t *old_ceiling)
2080 uint32_t save_ceiling;
2085 flags = fuword32(&m->m_flags);
2086 if ((flags & UMUTEX_PRIO_PROTECT) == 0)
2088 if (ceiling > RTP_PRIO_MAX)
2092 if ((error = umtx_key_get(m, TYPE_PP_UMUTEX, GET_SHARE(flags),
2096 umtxq_lock(&uq->uq_key);
2097 umtxq_busy(&uq->uq_key);
2098 umtxq_unlock(&uq->uq_key);
2100 save_ceiling = fuword32(&m->m_ceilings[0]);
2102 owner = casuword32(&m->m_owner,
2103 UMUTEX_CONTESTED, id | UMUTEX_CONTESTED);
2105 if (owner == UMUTEX_CONTESTED) {
2106 suword32(&m->m_ceilings[0], ceiling);
2107 suword32(__DEVOLATILE(uint32_t *, &m->m_owner),
2113 /* The address was invalid. */
2119 if ((owner & ~UMUTEX_CONTESTED) == id) {
2120 suword32(&m->m_ceilings[0], ceiling);
2126 * If we caught a signal, we have retried and now
2133 * We set the contested bit, sleep. Otherwise the lock changed
2134 * and we need to retry or we lost a race to the thread
2135 * unlocking the umtx.
2137 umtxq_lock(&uq->uq_key);
2139 umtxq_unbusy(&uq->uq_key);
2140 error = umtxq_sleep(uq, "umtxpp", 0);
2142 umtxq_unlock(&uq->uq_key);
2144 umtxq_lock(&uq->uq_key);
2146 umtxq_signal(&uq->uq_key, INT_MAX);
2147 umtxq_unbusy(&uq->uq_key);
2148 umtxq_unlock(&uq->uq_key);
2149 umtx_key_release(&uq->uq_key);
2150 if (error == 0 && old_ceiling != NULL)
2151 suword32(old_ceiling, save_ceiling);
2156 _do_lock_umutex(struct thread *td, struct umutex *m, int flags, int timo,
2159 switch(flags & (UMUTEX_PRIO_INHERIT | UMUTEX_PRIO_PROTECT)) {
2161 return (_do_lock_normal(td, m, flags, timo, mode));
2162 case UMUTEX_PRIO_INHERIT:
2163 return (_do_lock_pi(td, m, flags, timo, mode));
2164 case UMUTEX_PRIO_PROTECT:
2165 return (_do_lock_pp(td, m, flags, timo, mode));
2171 * Lock a userland POSIX mutex.
2174 do_lock_umutex(struct thread *td, struct umutex *m,
2175 struct timespec *timeout, int mode)
2177 struct timespec ts, ts2, ts3;
2182 flags = fuword32(&m->m_flags);
2186 if (timeout == NULL) {
2187 error = _do_lock_umutex(td, m, flags, 0, mode);
2188 /* Mutex locking is restarted if it is interrupted. */
2189 if (error == EINTR && mode != _UMUTEX_WAIT)
2193 timespecadd(&ts, timeout);
2194 TIMESPEC_TO_TIMEVAL(&tv, timeout);
2196 error = _do_lock_umutex(td, m, flags, tvtohz(&tv), mode);
2197 if (error != ETIMEDOUT)
2199 getnanouptime(&ts2);
2200 if (timespeccmp(&ts2, &ts, >=)) {
2205 timespecsub(&ts3, &ts2);
2206 TIMESPEC_TO_TIMEVAL(&tv, &ts3);
2208 /* Timed-locking is not restarted. */
2209 if (error == ERESTART)
2216 * Unlock a userland POSIX mutex.
2219 do_unlock_umutex(struct thread *td, struct umutex *m)
2223 flags = fuword32(&m->m_flags);
2227 switch(flags & (UMUTEX_PRIO_INHERIT | UMUTEX_PRIO_PROTECT)) {
2229 return (do_unlock_normal(td, m, flags));
2230 case UMUTEX_PRIO_INHERIT:
2231 return (do_unlock_pi(td, m, flags));
2232 case UMUTEX_PRIO_PROTECT:
2233 return (do_unlock_pp(td, m, flags));
2240 do_cv_wait(struct thread *td, struct ucond *cv, struct umutex *m,
2241 struct timespec *timeout, u_long wflags)
2245 struct timespec cts, ets, tts;
2250 flags = fuword32(&cv->c_flags);
2251 error = umtx_key_get(cv, TYPE_CV, GET_SHARE(flags), &uq->uq_key);
2254 umtxq_lock(&uq->uq_key);
2255 umtxq_busy(&uq->uq_key);
2257 umtxq_unlock(&uq->uq_key);
2260 * The magic thing is we should set c_has_waiters to 1 before
2261 * releasing user mutex.
2263 suword32(__DEVOLATILE(uint32_t *, &cv->c_has_waiters), 1);
2265 umtxq_lock(&uq->uq_key);
2266 umtxq_unbusy(&uq->uq_key);
2267 umtxq_unlock(&uq->uq_key);
2269 error = do_unlock_umutex(td, m);
2271 umtxq_lock(&uq->uq_key);
2273 if ((wflags & UMTX_CHECK_UNPARKING) &&
2274 (td->td_pflags & TDP_WAKEUP)) {
2275 td->td_pflags &= ~TDP_WAKEUP;
2277 } else if (timeout == NULL) {
2278 error = umtxq_sleep(uq, "ucond", 0);
2280 getnanouptime(&ets);
2281 timespecadd(&ets, timeout);
2282 TIMESPEC_TO_TIMEVAL(&tv, timeout);
2284 error = umtxq_sleep(uq, "ucond", tvtohz(&tv));
2285 if (error != ETIMEDOUT)
2287 getnanouptime(&cts);
2288 if (timespeccmp(&cts, &ets, >=)) {
2293 timespecsub(&tts, &cts);
2294 TIMESPEC_TO_TIMEVAL(&tv, &tts);
2300 if ((uq->uq_flags & UQF_UMTXQ) == 0) {
2302 * If we concurrently got do_cv_signal()d
2303 * and we got an error or UNIX signals or a timeout,
2304 * then, perform another umtxq_signal to avoid
2305 * consuming the wakeup. This may cause supurious
2306 * wakeup for another thread which was just queued,
2307 * but SUSV3 explicitly allows supurious wakeup to
2308 * occur, and indeed a kernel based implementation
2311 if (!umtxq_signal(&uq->uq_key, 1))
2314 if (error == ERESTART)
2318 umtxq_unlock(&uq->uq_key);
2319 umtx_key_release(&uq->uq_key);
2324 * Signal a userland condition variable.
2327 do_cv_signal(struct thread *td, struct ucond *cv)
2329 struct umtx_key key;
2330 int error, cnt, nwake;
2333 flags = fuword32(&cv->c_flags);
2334 if ((error = umtx_key_get(cv, TYPE_CV, GET_SHARE(flags), &key)) != 0)
2338 cnt = umtxq_count(&key);
2339 nwake = umtxq_signal(&key, 1);
2343 __DEVOLATILE(uint32_t *, &cv->c_has_waiters), 0);
2348 umtx_key_release(&key);
2353 do_cv_broadcast(struct thread *td, struct ucond *cv)
2355 struct umtx_key key;
2359 flags = fuword32(&cv->c_flags);
2360 if ((error = umtx_key_get(cv, TYPE_CV, GET_SHARE(flags), &key)) != 0)
2365 umtxq_signal(&key, INT_MAX);
2368 error = suword32(__DEVOLATILE(uint32_t *, &cv->c_has_waiters), 0);
2374 umtx_key_release(&key);
2379 do_rw_rdlock(struct thread *td, struct urwlock *rwlock, long fflag, int timo)
2382 uint32_t flags, wrflags;
2383 int32_t state, oldstate;
2384 int32_t blocked_readers;
2388 flags = fuword32(&rwlock->rw_flags);
2389 error = umtx_key_get(rwlock, TYPE_RWLOCK, GET_SHARE(flags), &uq->uq_key);
2393 wrflags = URWLOCK_WRITE_OWNER;
2394 if (!(fflag & URWLOCK_PREFER_READER) && !(flags & URWLOCK_PREFER_READER))
2395 wrflags |= URWLOCK_WRITE_WAITERS;
2398 state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state));
2399 /* try to lock it */
2400 while (!(state & wrflags)) {
2401 if (__predict_false(URWLOCK_READER_COUNT(state) == URWLOCK_MAX_READERS)) {
2402 umtx_key_release(&uq->uq_key);
2405 oldstate = casuword32(&rwlock->rw_state, state, state + 1);
2406 if (oldstate == state) {
2407 umtx_key_release(&uq->uq_key);
2416 /* grab monitor lock */
2417 umtxq_lock(&uq->uq_key);
2418 umtxq_busy(&uq->uq_key);
2419 umtxq_unlock(&uq->uq_key);
2422 * re-read the state, in case it changed between the try-lock above
2423 * and the check below
2425 state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state));
2427 /* set read contention bit */
2428 while ((state & wrflags) && !(state & URWLOCK_READ_WAITERS)) {
2429 oldstate = casuword32(&rwlock->rw_state, state, state | URWLOCK_READ_WAITERS);
2430 if (oldstate == state)
2435 /* state is changed while setting flags, restart */
2436 if (!(state & wrflags)) {
2437 umtxq_lock(&uq->uq_key);
2438 umtxq_unbusy(&uq->uq_key);
2439 umtxq_unlock(&uq->uq_key);
2444 /* contention bit is set, before sleeping, increase read waiter count */
2445 blocked_readers = fuword32(&rwlock->rw_blocked_readers);
2446 suword32(&rwlock->rw_blocked_readers, blocked_readers+1);
2448 while (state & wrflags) {
2449 umtxq_lock(&uq->uq_key);
2451 umtxq_unbusy(&uq->uq_key);
2453 error = umtxq_sleep(uq, "urdlck", timo);
2455 umtxq_busy(&uq->uq_key);
2457 umtxq_unlock(&uq->uq_key);
2460 state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state));
2463 /* decrease read waiter count, and may clear read contention bit */
2464 blocked_readers = fuword32(&rwlock->rw_blocked_readers);
2465 suword32(&rwlock->rw_blocked_readers, blocked_readers-1);
2466 if (blocked_readers == 1) {
2467 state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state));
2469 oldstate = casuword32(&rwlock->rw_state, state,
2470 state & ~URWLOCK_READ_WAITERS);
2471 if (oldstate == state)
2477 umtxq_lock(&uq->uq_key);
2478 umtxq_unbusy(&uq->uq_key);
2479 umtxq_unlock(&uq->uq_key);
2481 umtx_key_release(&uq->uq_key);
2486 do_rw_rdlock2(struct thread *td, void *obj, long val, struct timespec *timeout)
2488 struct timespec ts, ts2, ts3;
2493 timespecadd(&ts, timeout);
2494 TIMESPEC_TO_TIMEVAL(&tv, timeout);
2496 error = do_rw_rdlock(td, obj, val, tvtohz(&tv));
2497 if (error != ETIMEDOUT)
2499 getnanouptime(&ts2);
2500 if (timespeccmp(&ts2, &ts, >=)) {
2505 timespecsub(&ts3, &ts2);
2506 TIMESPEC_TO_TIMEVAL(&tv, &ts3);
2508 if (error == ERESTART)
2514 do_rw_wrlock(struct thread *td, struct urwlock *rwlock, int timo)
2518 int32_t state, oldstate;
2519 int32_t blocked_writers;
2520 int32_t blocked_readers;
2524 flags = fuword32(&rwlock->rw_flags);
2525 error = umtx_key_get(rwlock, TYPE_RWLOCK, GET_SHARE(flags), &uq->uq_key);
2529 blocked_readers = 0;
2531 state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state));
2532 while (!(state & URWLOCK_WRITE_OWNER) && URWLOCK_READER_COUNT(state) == 0) {
2533 oldstate = casuword32(&rwlock->rw_state, state, state | URWLOCK_WRITE_OWNER);
2534 if (oldstate == state) {
2535 umtx_key_release(&uq->uq_key);
2542 if (!(state & (URWLOCK_WRITE_OWNER|URWLOCK_WRITE_WAITERS)) &&
2543 blocked_readers != 0) {
2544 umtxq_lock(&uq->uq_key);
2545 umtxq_busy(&uq->uq_key);
2546 umtxq_signal_queue(&uq->uq_key, INT_MAX, UMTX_SHARED_QUEUE);
2547 umtxq_unbusy(&uq->uq_key);
2548 umtxq_unlock(&uq->uq_key);
2554 /* grab monitor lock */
2555 umtxq_lock(&uq->uq_key);
2556 umtxq_busy(&uq->uq_key);
2557 umtxq_unlock(&uq->uq_key);
2560 * re-read the state, in case it changed between the try-lock above
2561 * and the check below
2563 state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state));
2565 while (((state & URWLOCK_WRITE_OWNER) || URWLOCK_READER_COUNT(state) != 0) &&
2566 (state & URWLOCK_WRITE_WAITERS) == 0) {
2567 oldstate = casuword32(&rwlock->rw_state, state, state | URWLOCK_WRITE_WAITERS);
2568 if (oldstate == state)
2573 if (!(state & URWLOCK_WRITE_OWNER) && URWLOCK_READER_COUNT(state) == 0) {
2574 umtxq_lock(&uq->uq_key);
2575 umtxq_unbusy(&uq->uq_key);
2576 umtxq_unlock(&uq->uq_key);
2580 blocked_writers = fuword32(&rwlock->rw_blocked_writers);
2581 suword32(&rwlock->rw_blocked_writers, blocked_writers+1);
2583 while ((state & URWLOCK_WRITE_OWNER) || URWLOCK_READER_COUNT(state) != 0) {
2584 umtxq_lock(&uq->uq_key);
2585 umtxq_insert_queue(uq, UMTX_EXCLUSIVE_QUEUE);
2586 umtxq_unbusy(&uq->uq_key);
2588 error = umtxq_sleep(uq, "uwrlck", timo);
2590 umtxq_busy(&uq->uq_key);
2591 umtxq_remove_queue(uq, UMTX_EXCLUSIVE_QUEUE);
2592 umtxq_unlock(&uq->uq_key);
2595 state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state));
2598 blocked_writers = fuword32(&rwlock->rw_blocked_writers);
2599 suword32(&rwlock->rw_blocked_writers, blocked_writers-1);
2600 if (blocked_writers == 1) {
2601 state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state));
2603 oldstate = casuword32(&rwlock->rw_state, state,
2604 state & ~URWLOCK_WRITE_WAITERS);
2605 if (oldstate == state)
2609 blocked_readers = fuword32(&rwlock->rw_blocked_readers);
2611 blocked_readers = 0;
2613 umtxq_lock(&uq->uq_key);
2614 umtxq_unbusy(&uq->uq_key);
2615 umtxq_unlock(&uq->uq_key);
2618 umtx_key_release(&uq->uq_key);
2623 do_rw_wrlock2(struct thread *td, void *obj, struct timespec *timeout)
2625 struct timespec ts, ts2, ts3;
2630 timespecadd(&ts, timeout);
2631 TIMESPEC_TO_TIMEVAL(&tv, timeout);
2633 error = do_rw_wrlock(td, obj, tvtohz(&tv));
2634 if (error != ETIMEDOUT)
2636 getnanouptime(&ts2);
2637 if (timespeccmp(&ts2, &ts, >=)) {
2642 timespecsub(&ts3, &ts2);
2643 TIMESPEC_TO_TIMEVAL(&tv, &ts3);
2645 if (error == ERESTART)
2651 do_rw_unlock(struct thread *td, struct urwlock *rwlock)
2655 int32_t state, oldstate;
2656 int error, q, count;
2659 flags = fuword32(&rwlock->rw_flags);
2660 error = umtx_key_get(rwlock, TYPE_RWLOCK, GET_SHARE(flags), &uq->uq_key);
2664 state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state));
2665 if (state & URWLOCK_WRITE_OWNER) {
2667 oldstate = casuword32(&rwlock->rw_state, state,
2668 state & ~URWLOCK_WRITE_OWNER);
2669 if (oldstate != state) {
2671 if (!(oldstate & URWLOCK_WRITE_OWNER)) {
2678 } else if (URWLOCK_READER_COUNT(state) != 0) {
2680 oldstate = casuword32(&rwlock->rw_state, state,
2682 if (oldstate != state) {
2684 if (URWLOCK_READER_COUNT(oldstate) == 0) {
2699 if (!(flags & URWLOCK_PREFER_READER)) {
2700 if (state & URWLOCK_WRITE_WAITERS) {
2702 q = UMTX_EXCLUSIVE_QUEUE;
2703 } else if (state & URWLOCK_READ_WAITERS) {
2705 q = UMTX_SHARED_QUEUE;
2708 if (state & URWLOCK_READ_WAITERS) {
2710 q = UMTX_SHARED_QUEUE;
2711 } else if (state & URWLOCK_WRITE_WAITERS) {
2713 q = UMTX_EXCLUSIVE_QUEUE;
2718 umtxq_lock(&uq->uq_key);
2719 umtxq_busy(&uq->uq_key);
2720 umtxq_signal_queue(&uq->uq_key, count, q);
2721 umtxq_unbusy(&uq->uq_key);
2722 umtxq_unlock(&uq->uq_key);
2725 umtx_key_release(&uq->uq_key);
2730 _umtx_lock(struct thread *td, struct _umtx_lock_args *uap)
2731 /* struct umtx *umtx */
2733 return _do_lock_umtx(td, uap->umtx, td->td_tid, 0);
2737 _umtx_unlock(struct thread *td, struct _umtx_unlock_args *uap)
2738 /* struct umtx *umtx */
2740 return do_unlock_umtx(td, uap->umtx, td->td_tid);
2744 umtx_copyin_timeout(const void *addr, struct timespec *tsp)
2748 error = copyin(addr, tsp, sizeof(struct timespec));
2750 if (tsp->tv_sec < 0 ||
2751 tsp->tv_nsec >= 1000000000 ||
2759 __umtx_op_lock_umtx(struct thread *td, struct _umtx_op_args *uap)
2761 struct timespec *ts, timeout;
2764 /* Allow a null timespec (wait forever). */
2765 if (uap->uaddr2 == NULL)
2768 error = umtx_copyin_timeout(uap->uaddr2, &timeout);
2773 return (do_lock_umtx(td, uap->obj, uap->val, ts));
2777 __umtx_op_unlock_umtx(struct thread *td, struct _umtx_op_args *uap)
2779 return (do_unlock_umtx(td, uap->obj, uap->val));
2783 __umtx_op_wait(struct thread *td, struct _umtx_op_args *uap)
2785 struct timespec *ts, timeout;
2788 if (uap->uaddr2 == NULL)
2791 error = umtx_copyin_timeout(uap->uaddr2, &timeout);
2796 return do_wait(td, uap->obj, uap->val, ts, 0, 0);
2800 __umtx_op_wait_uint(struct thread *td, struct _umtx_op_args *uap)
2802 struct timespec *ts, timeout;
2805 if (uap->uaddr2 == NULL)
2808 error = umtx_copyin_timeout(uap->uaddr2, &timeout);
2813 return do_wait(td, uap->obj, uap->val, ts, 1, 0);
2817 __umtx_op_wait_uint_private(struct thread *td, struct _umtx_op_args *uap)
2819 struct timespec *ts, timeout;
2822 if (uap->uaddr2 == NULL)
2825 error = umtx_copyin_timeout(uap->uaddr2, &timeout);
2830 return do_wait(td, uap->obj, uap->val, ts, 1, 1);
2834 __umtx_op_wake(struct thread *td, struct _umtx_op_args *uap)
2836 return (kern_umtx_wake(td, uap->obj, uap->val, 0));
2840 __umtx_op_wake_private(struct thread *td, struct _umtx_op_args *uap)
2842 return (kern_umtx_wake(td, uap->obj, uap->val, 1));
2846 __umtx_op_lock_umutex(struct thread *td, struct _umtx_op_args *uap)
2848 struct timespec *ts, timeout;
2851 /* Allow a null timespec (wait forever). */
2852 if (uap->uaddr2 == NULL)
2855 error = umtx_copyin_timeout(uap->uaddr2, &timeout);
2860 return do_lock_umutex(td, uap->obj, ts, 0);
2864 __umtx_op_trylock_umutex(struct thread *td, struct _umtx_op_args *uap)
2866 return do_lock_umutex(td, uap->obj, NULL, _UMUTEX_TRY);
2870 __umtx_op_wait_umutex(struct thread *td, struct _umtx_op_args *uap)
2872 struct timespec *ts, timeout;
2875 /* Allow a null timespec (wait forever). */
2876 if (uap->uaddr2 == NULL)
2879 error = umtx_copyin_timeout(uap->uaddr2, &timeout);
2884 return do_lock_umutex(td, uap->obj, ts, _UMUTEX_WAIT);
2888 __umtx_op_wake_umutex(struct thread *td, struct _umtx_op_args *uap)
2890 return do_wake_umutex(td, uap->obj);
2894 __umtx_op_unlock_umutex(struct thread *td, struct _umtx_op_args *uap)
2896 return do_unlock_umutex(td, uap->obj);
2900 __umtx_op_set_ceiling(struct thread *td, struct _umtx_op_args *uap)
2902 return do_set_ceiling(td, uap->obj, uap->val, uap->uaddr1);
2906 __umtx_op_cv_wait(struct thread *td, struct _umtx_op_args *uap)
2908 struct timespec *ts, timeout;
2911 /* Allow a null timespec (wait forever). */
2912 if (uap->uaddr2 == NULL)
2915 error = umtx_copyin_timeout(uap->uaddr2, &timeout);
2920 return (do_cv_wait(td, uap->obj, uap->uaddr1, ts, uap->val));
2924 __umtx_op_cv_signal(struct thread *td, struct _umtx_op_args *uap)
2926 return do_cv_signal(td, uap->obj);
2930 __umtx_op_cv_broadcast(struct thread *td, struct _umtx_op_args *uap)
2932 return do_cv_broadcast(td, uap->obj);
2936 __umtx_op_rw_rdlock(struct thread *td, struct _umtx_op_args *uap)
2938 struct timespec timeout;
2941 /* Allow a null timespec (wait forever). */
2942 if (uap->uaddr2 == NULL) {
2943 error = do_rw_rdlock(td, uap->obj, uap->val, 0);
2945 error = umtx_copyin_timeout(uap->uaddr2, &timeout);
2948 error = do_rw_rdlock2(td, uap->obj, uap->val, &timeout);
2954 __umtx_op_rw_wrlock(struct thread *td, struct _umtx_op_args *uap)
2956 struct timespec timeout;
2959 /* Allow a null timespec (wait forever). */
2960 if (uap->uaddr2 == NULL) {
2961 error = do_rw_wrlock(td, uap->obj, 0);
2963 error = umtx_copyin_timeout(uap->uaddr2, &timeout);
2967 error = do_rw_wrlock2(td, uap->obj, &timeout);
2973 __umtx_op_rw_unlock(struct thread *td, struct _umtx_op_args *uap)
2975 return do_rw_unlock(td, uap->obj);
2978 typedef int (*_umtx_op_func)(struct thread *td, struct _umtx_op_args *uap);
2980 static _umtx_op_func op_table[] = {
2981 __umtx_op_lock_umtx, /* UMTX_OP_LOCK */
2982 __umtx_op_unlock_umtx, /* UMTX_OP_UNLOCK */
2983 __umtx_op_wait, /* UMTX_OP_WAIT */
2984 __umtx_op_wake, /* UMTX_OP_WAKE */
2985 __umtx_op_trylock_umutex, /* UMTX_OP_MUTEX_TRYLOCK */
2986 __umtx_op_lock_umutex, /* UMTX_OP_MUTEX_LOCK */
2987 __umtx_op_unlock_umutex, /* UMTX_OP_MUTEX_UNLOCK */
2988 __umtx_op_set_ceiling, /* UMTX_OP_SET_CEILING */
2989 __umtx_op_cv_wait, /* UMTX_OP_CV_WAIT*/
2990 __umtx_op_cv_signal, /* UMTX_OP_CV_SIGNAL */
2991 __umtx_op_cv_broadcast, /* UMTX_OP_CV_BROADCAST */
2992 __umtx_op_wait_uint, /* UMTX_OP_WAIT_UINT */
2993 __umtx_op_rw_rdlock, /* UMTX_OP_RW_RDLOCK */
2994 __umtx_op_rw_wrlock, /* UMTX_OP_RW_WRLOCK */
2995 __umtx_op_rw_unlock, /* UMTX_OP_RW_UNLOCK */
2996 __umtx_op_wait_uint_private, /* UMTX_OP_WAIT_UINT_PRIVATE */
2997 __umtx_op_wake_private, /* UMTX_OP_WAKE_PRIVATE */
2998 __umtx_op_wait_umutex, /* UMTX_OP_UMUTEX_WAIT */
2999 __umtx_op_wake_umutex /* UMTX_OP_UMUTEX_WAKE */
3003 _umtx_op(struct thread *td, struct _umtx_op_args *uap)
3005 if ((unsigned)uap->op < UMTX_OP_MAX)
3006 return (*op_table[uap->op])(td, uap);
3010 #ifdef COMPAT_FREEBSD32
3012 freebsd32_umtx_lock(struct thread *td, struct freebsd32_umtx_lock_args *uap)
3013 /* struct umtx *umtx */
3015 return (do_lock_umtx32(td, (uint32_t *)uap->umtx, td->td_tid, NULL));
3019 freebsd32_umtx_unlock(struct thread *td, struct freebsd32_umtx_unlock_args *uap)
3020 /* struct umtx *umtx */
3022 return (do_unlock_umtx32(td, (uint32_t *)uap->umtx, td->td_tid));
3031 umtx_copyin_timeout32(void *addr, struct timespec *tsp)
3033 struct timespec32 ts32;
3036 error = copyin(addr, &ts32, sizeof(struct timespec32));
3038 if (ts32.tv_sec < 0 ||
3039 ts32.tv_nsec >= 1000000000 ||
3043 tsp->tv_sec = ts32.tv_sec;
3044 tsp->tv_nsec = ts32.tv_nsec;
3051 __umtx_op_lock_umtx_compat32(struct thread *td, struct _umtx_op_args *uap)
3053 struct timespec *ts, timeout;
3056 /* Allow a null timespec (wait forever). */
3057 if (uap->uaddr2 == NULL)
3060 error = umtx_copyin_timeout32(uap->uaddr2, &timeout);
3065 return (do_lock_umtx32(td, uap->obj, uap->val, ts));
3069 __umtx_op_unlock_umtx_compat32(struct thread *td, struct _umtx_op_args *uap)
3071 return (do_unlock_umtx32(td, uap->obj, (uint32_t)uap->val));
3075 __umtx_op_wait_compat32(struct thread *td, struct _umtx_op_args *uap)
3077 struct timespec *ts, timeout;
3080 if (uap->uaddr2 == NULL)
3083 error = umtx_copyin_timeout32(uap->uaddr2, &timeout);
3088 return do_wait(td, uap->obj, uap->val, ts, 1, 0);
3092 __umtx_op_lock_umutex_compat32(struct thread *td, struct _umtx_op_args *uap)
3094 struct timespec *ts, timeout;
3097 /* Allow a null timespec (wait forever). */
3098 if (uap->uaddr2 == NULL)
3101 error = umtx_copyin_timeout32(uap->uaddr2, &timeout);
3106 return do_lock_umutex(td, uap->obj, ts, 0);
3110 __umtx_op_wait_umutex_compat32(struct thread *td, struct _umtx_op_args *uap)
3112 struct timespec *ts, timeout;
3115 /* Allow a null timespec (wait forever). */
3116 if (uap->uaddr2 == NULL)
3119 error = umtx_copyin_timeout32(uap->uaddr2, &timeout);
3124 return do_lock_umutex(td, uap->obj, ts, _UMUTEX_WAIT);
3128 __umtx_op_cv_wait_compat32(struct thread *td, struct _umtx_op_args *uap)
3130 struct timespec *ts, timeout;
3133 /* Allow a null timespec (wait forever). */
3134 if (uap->uaddr2 == NULL)
3137 error = umtx_copyin_timeout32(uap->uaddr2, &timeout);
3142 return (do_cv_wait(td, uap->obj, uap->uaddr1, ts, uap->val));
3146 __umtx_op_rw_rdlock_compat32(struct thread *td, struct _umtx_op_args *uap)
3148 struct timespec timeout;
3151 /* Allow a null timespec (wait forever). */
3152 if (uap->uaddr2 == NULL) {
3153 error = do_rw_rdlock(td, uap->obj, uap->val, 0);
3155 error = umtx_copyin_timeout32(uap->uaddr2, &timeout);
3158 error = do_rw_rdlock2(td, uap->obj, uap->val, &timeout);
3164 __umtx_op_rw_wrlock_compat32(struct thread *td, struct _umtx_op_args *uap)
3166 struct timespec timeout;
3169 /* Allow a null timespec (wait forever). */
3170 if (uap->uaddr2 == NULL) {
3171 error = do_rw_wrlock(td, uap->obj, 0);
3173 error = umtx_copyin_timeout32(uap->uaddr2, &timeout);
3177 error = do_rw_wrlock2(td, uap->obj, &timeout);
3183 __umtx_op_wait_uint_private_compat32(struct thread *td, struct _umtx_op_args *uap)
3185 struct timespec *ts, timeout;
3188 if (uap->uaddr2 == NULL)
3191 error = umtx_copyin_timeout32(uap->uaddr2, &timeout);
3196 return do_wait(td, uap->obj, uap->val, ts, 1, 1);
3199 static _umtx_op_func op_table_compat32[] = {
3200 __umtx_op_lock_umtx_compat32, /* UMTX_OP_LOCK */
3201 __umtx_op_unlock_umtx_compat32, /* UMTX_OP_UNLOCK */
3202 __umtx_op_wait_compat32, /* UMTX_OP_WAIT */
3203 __umtx_op_wake, /* UMTX_OP_WAKE */
3204 __umtx_op_trylock_umutex, /* UMTX_OP_MUTEX_LOCK */
3205 __umtx_op_lock_umutex_compat32, /* UMTX_OP_MUTEX_TRYLOCK */
3206 __umtx_op_unlock_umutex, /* UMTX_OP_MUTEX_UNLOCK */
3207 __umtx_op_set_ceiling, /* UMTX_OP_SET_CEILING */
3208 __umtx_op_cv_wait_compat32, /* UMTX_OP_CV_WAIT*/
3209 __umtx_op_cv_signal, /* UMTX_OP_CV_SIGNAL */
3210 __umtx_op_cv_broadcast, /* UMTX_OP_CV_BROADCAST */
3211 __umtx_op_wait_compat32, /* UMTX_OP_WAIT_UINT */
3212 __umtx_op_rw_rdlock_compat32, /* UMTX_OP_RW_RDLOCK */
3213 __umtx_op_rw_wrlock_compat32, /* UMTX_OP_RW_WRLOCK */
3214 __umtx_op_rw_unlock, /* UMTX_OP_RW_UNLOCK */
3215 __umtx_op_wait_uint_private_compat32, /* UMTX_OP_WAIT_UINT_PRIVATE */
3216 __umtx_op_wake_private, /* UMTX_OP_WAKE_PRIVATE */
3217 __umtx_op_wait_umutex_compat32, /* UMTX_OP_UMUTEX_WAIT */
3218 __umtx_op_wake_umutex /* UMTX_OP_UMUTEX_WAKE */
3222 freebsd32_umtx_op(struct thread *td, struct freebsd32_umtx_op_args *uap)
3224 if ((unsigned)uap->op < UMTX_OP_MAX)
3225 return (*op_table_compat32[uap->op])(td,
3226 (struct _umtx_op_args *)uap);
3232 umtx_thread_init(struct thread *td)
3234 td->td_umtxq = umtxq_alloc();
3235 td->td_umtxq->uq_thread = td;
3239 umtx_thread_fini(struct thread *td)
3241 umtxq_free(td->td_umtxq);
3245 * It will be called when new thread is created, e.g fork().
3248 umtx_thread_alloc(struct thread *td)
3253 uq->uq_inherited_pri = PRI_MAX;
3255 KASSERT(uq->uq_flags == 0, ("uq_flags != 0"));
3256 KASSERT(uq->uq_thread == td, ("uq_thread != td"));
3257 KASSERT(uq->uq_pi_blocked == NULL, ("uq_pi_blocked != NULL"));
3258 KASSERT(TAILQ_EMPTY(&uq->uq_pi_contested), ("uq_pi_contested is not empty"));
3265 umtx_exec_hook(void *arg __unused, struct proc *p __unused,
3266 struct image_params *imgp __unused)
3268 umtx_thread_cleanup(curthread);
3272 * thread_exit() hook.
3275 umtx_thread_exit(struct thread *td)
3277 umtx_thread_cleanup(td);
3281 * clean up umtx data.
3284 umtx_thread_cleanup(struct thread *td)
3289 if ((uq = td->td_umtxq) == NULL)
3292 mtx_lock_spin(&umtx_lock);
3293 uq->uq_inherited_pri = PRI_MAX;
3294 while ((pi = TAILQ_FIRST(&uq->uq_pi_contested)) != NULL) {
3295 pi->pi_owner = NULL;
3296 TAILQ_REMOVE(&uq->uq_pi_contested, pi, pi_link);
3299 td->td_flags &= ~TDF_UBORROWING;
3301 mtx_unlock_spin(&umtx_lock);