]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/kern/wait_queue.c
xnu-517.9.5.tar.gz
[apple/xnu.git] / osfmk / kern / wait_queue.c
index 627bf793cd34a3ab5c4662add87d5d82818a61da..eef777359290480c5954f525203739a81b1894a7 100644 (file)
@@ -408,14 +408,12 @@ wait_queue_link_noalloc(
         */
        s = splsched();
        wait_queue_lock(wq);
         */
        s = splsched();
        wait_queue_lock(wq);
-       wqs_lock(wq_set);
        q = &wq->wq_queue;
        wq_element = (wait_queue_element_t) queue_first(q);
        while (!queue_end(q, (queue_entry_t)wq_element)) {
                WAIT_QUEUE_ELEMENT_CHECK(wq, wq_element);
                if (wq_element->wqe_type == WAIT_QUEUE_LINK &&
                    ((wait_queue_link_t)wq_element)->wql_setqueue == wq_set) {
        q = &wq->wq_queue;
        wq_element = (wait_queue_element_t) queue_first(q);
        while (!queue_end(q, (queue_entry_t)wq_element)) {
                WAIT_QUEUE_ELEMENT_CHECK(wq, wq_element);
                if (wq_element->wqe_type == WAIT_QUEUE_LINK &&
                    ((wait_queue_link_t)wq_element)->wql_setqueue == wq_set) {
-                       wqs_unlock(wq_set);
                        wait_queue_unlock(wq);
                        splx(s);
                        return KERN_ALREADY_IN_SET;
                        wait_queue_unlock(wq);
                        splx(s);
                        return KERN_ALREADY_IN_SET;
@@ -427,6 +425,7 @@ wait_queue_link_noalloc(
        /*
         * Not already a member, so we can add it.
         */
        /*
         * Not already a member, so we can add it.
         */
+       wqs_lock(wq_set);
 
        WAIT_QUEUE_SET_CHECK(wq_set);
 
 
        WAIT_QUEUE_SET_CHECK(wq_set);
 
@@ -833,6 +832,7 @@ wait_queue_unlink_one(
  *
  *     Conditions:
  *             The wait queue is assumed locked.
  *
  *     Conditions:
  *             The wait queue is assumed locked.
+ *             The waiting thread is assumed locked.
  *
  */
 __private_extern__ wait_result_t
  *
  */
 __private_extern__ wait_result_t
@@ -840,18 +840,18 @@ wait_queue_assert_wait64_locked(
        wait_queue_t wq,
        event64_t event,
        wait_interrupt_t interruptible,
        wait_queue_t wq,
        event64_t event,
        wait_interrupt_t interruptible,
-       boolean_t unlock)
+       thread_t thread)
 {
 {
-       thread_t thread;
        wait_result_t wait_result;
 
        wait_result_t wait_result;
 
+       if (!wait_queue_assert_possible(thread))
+               panic("wait_queue_assert_wait64_locked");
+
        if (wq->wq_type == _WAIT_QUEUE_SET_inited) {
                wait_queue_set_t wqs = (wait_queue_set_t)wq;
        if (wq->wq_type == _WAIT_QUEUE_SET_inited) {
                wait_queue_set_t wqs = (wait_queue_set_t)wq;
-               if (wqs->wqs_isprepost && wqs->wqs_refcount > 0) {
-                       if (unlock)
-                               wait_queue_unlock(wq);
+
+               if (wqs->wqs_isprepost && wqs->wqs_refcount > 0)
                        return(THREAD_AWAKENED);
                        return(THREAD_AWAKENED);
-               }
        }
          
        /*
        }
          
        /*
@@ -860,8 +860,6 @@ wait_queue_assert_wait64_locked(
         * the front of the queue.  Later, these queues will honor the policy
         * value set at wait_queue_init time.
         */
         * the front of the queue.  Later, these queues will honor the policy
         * value set at wait_queue_init time.
         */
-       thread = current_thread();
-       thread_lock(thread);
        wait_result = thread_mark_wait_locked(thread, interruptible);
        if (wait_result == THREAD_WAITING) {
                if (thread->vm_privilege)
        wait_result = thread_mark_wait_locked(thread, interruptible);
        if (wait_result == THREAD_WAITING) {
                if (thread->vm_privilege)
@@ -871,9 +869,6 @@ wait_queue_assert_wait64_locked(
                thread->wait_event = event;
                thread->wait_queue = wq;
        }
                thread->wait_event = event;
                thread->wait_queue = wq;
        }
-       thread_unlock(thread);
-       if (unlock)
-               wait_queue_unlock(wq);
        return(wait_result);
 }
 
        return(wait_result);
 }
 
@@ -894,6 +889,7 @@ wait_queue_assert_wait(
 {
        spl_t s;
        wait_result_t ret;
 {
        spl_t s;
        wait_result_t ret;
+       thread_t cur_thread = current_thread();
 
        /* If it is an invalid wait queue, you can't wait on it */
        if (!wait_queue_is_valid(wq)) {
 
        /* If it is an invalid wait queue, you can't wait on it */
        if (!wait_queue_is_valid(wq)) {
@@ -903,10 +899,12 @@ wait_queue_assert_wait(
 
        s = splsched();
        wait_queue_lock(wq);
 
        s = splsched();
        wait_queue_lock(wq);
+       thread_lock(cur_thread);
        ret = wait_queue_assert_wait64_locked(
                                wq, (event64_t)((uint32_t)event),
        ret = wait_queue_assert_wait64_locked(
                                wq, (event64_t)((uint32_t)event),
-                               interruptible, TRUE);
-       /* wait queue unlocked */
+                               interruptible, cur_thread);
+       thread_unlock(cur_thread);
+       wait_queue_unlock(wq);
        splx(s);
        return(ret);
 }
        splx(s);
        return(ret);
 }
@@ -927,6 +925,7 @@ wait_queue_assert_wait64(
 {
        spl_t s;
        wait_result_t ret;
 {
        spl_t s;
        wait_result_t ret;
+       thread_t cur_thread = current_thread();
 
        /* If it is an invalid wait queue, you cant wait on it */
        if (!wait_queue_is_valid(wq)) {
 
        /* If it is an invalid wait queue, you cant wait on it */
        if (!wait_queue_is_valid(wq)) {
@@ -936,8 +935,10 @@ wait_queue_assert_wait64(
 
        s = splsched();
        wait_queue_lock(wq);
 
        s = splsched();
        wait_queue_lock(wq);
-       ret = wait_queue_assert_wait64_locked(wq, event, interruptible, TRUE);
-       /* wait queue unlocked */
+       thread_lock(cur_thread);
+       ret = wait_queue_assert_wait64_locked(wq, event, interruptible, cur_thread);
+       thread_unlock(cur_thread);
+       wait_queue_unlock(wq);
        splx(s);
        return(ret);
 }
        splx(s);
        return(ret);
 }