#include <vm/vm_map.h>
#include <mach/vm_region.h>
-#include <libkern/OSAtomic.h>
-
-#include <pexpert/pexpert.h>
-
-#include "kern_internal.h"
-#include "synch_internal.h"
-#include "kern_trace.h"
+#include "kern/kern_internal.h"
+#include "kern/synch_internal.h"
+#include "kern/kern_trace.h"
typedef struct uthread *uthread_t;
#define KW_UNLOCK_PREPOST_READLOCK 0x08
#define KW_UNLOCK_PREPOST_WRLOCK 0x20
-static int ksyn_wq_hash_lookup(user_addr_t uaddr, proc_t p, int flags, ksyn_wait_queue_t *kwq, struct pthhashhead **hashptr, uint64_t *object, uint64_t *offset);
+static int ksyn_wq_hash_lookup(user_addr_t uaddr, proc_t p, int flags, ksyn_wait_queue_t *kwq, struct pthhashhead **hashptr, uint64_t object, uint64_t offset);
static int ksyn_wqfind(user_addr_t mutex, uint32_t mgen, uint32_t ugen, uint32_t rw_wc, int flags, int wqtype , ksyn_wait_queue_t *wq);
static void ksyn_wqrelease(ksyn_wait_queue_t mkwq, int qfreenow, int wqtype);
static int ksyn_findobj(user_addr_t uaddr, uint64_t *objectp, uint64_t *offsetp);
static void
pthread_list_lock(void)
{
- lck_mtx_lock(pthread_list_mlock);
+ lck_mtx_lock_spin(pthread_list_mlock);
}
static void
pthread_kern->psynch_wait_update_owner(kwq, kwq->kw_owner,
&kwq->kw_turnstile);
ksyn_wqunlock(kwq);
- _kwq_cleanup_old_owner(&old_owner);
goto out;
}
old_owner = _kwq_set_owner(kwq, current_thread(), 0);
pthread_kern->psynch_wait_update_owner(kwq, kwq->kw_owner,
&kwq->kw_turnstile);
-
+
ksyn_wqunlock(kwq);
- _kwq_cleanup_old_owner(&old_owner);
*retval = updatebits;
goto out;
}
pthread_kern->thread_deallocate_safe(tid_th);
tid_th = THREAD_NULL;
}
+ assert(old_owner == THREAD_NULL);
error = ksyn_wait(kwq, KSYN_QUEUE_WRITE, mgen, ins_flags, 0, 0,
psynch_mtxcontinue, kThreadWaitPThreadMutex);
// ksyn_wait drops wait queue lock
if (tid_th) {
thread_deallocate(tid_th);
}
+ if (old_owner) {
+ thread_deallocate(old_owner);
+ }
return error;
}
static int
ksyn_wq_hash_lookup(user_addr_t uaddr, proc_t p, int flags,
ksyn_wait_queue_t *out_kwq, struct pthhashhead **out_hashptr,
- uint64_t *out_object, uint64_t *out_offset)
+ uint64_t object, uint64_t offset)
{
int res = 0;
ksyn_wait_queue_t kwq;
- uint64_t object = 0, offset = 0;
struct pthhashhead *hashptr;
if ((flags & PTHREAD_PSHARED_FLAGS_MASK) == PTHREAD_PROCESS_SHARED) {
hashptr = pth_glob_hashtbl;
- res = ksyn_findobj(uaddr, &object, &offset);
- if (res == 0) {
- LIST_FOREACH(kwq, &hashptr[object & pthhash], kw_hash) {
- if (kwq->kw_object == object && kwq->kw_offset == offset) {
- break;
- }
+ LIST_FOREACH(kwq, &hashptr[object & pthhash], kw_hash) {
+ if (kwq->kw_object == object && kwq->kw_offset == offset) {
+ break;
}
- } else {
- kwq = NULL;
}
} else {
hashptr = pthread_kern->proc_get_pthhash(p);
}
}
*out_kwq = kwq;
- *out_object = object;
- *out_offset = offset;
*out_hashptr = hashptr;
return res;
}
while (res == 0) {
pthread_list_lock();
res = ksyn_wq_hash_lookup(uaddr, current_proc(), flags, &kwq, &hashptr,
- &object, &offset);
+ object, offset);
if (res != 0) {
pthread_list_unlock();
break;