]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/kern_synch.c
xnu-517.tar.gz
[apple/xnu.git] / bsd / kern / kern_synch.c
index f7d68435fb1ea1bd3ff93acee000113c200cdd59..8bb7482310e9a734db9ba640425f17af25a5f4e4 100644 (file)
@@ -3,19 +3,22 @@
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
@@ -58,21 +61,16 @@ static void
 _sleep_continue(void)
 {
        register struct proc *p;
-       register thread_t thread = current_thread();
-       thread_act_t th_act;
+       register thread_t self = current_act();
        struct uthread * ut;
        int sig, catch;
        int error = 0;
 
-       th_act = current_act();
-       ut = get_bsdthread_info(th_act);
+       ut = get_bsdthread_info(self);
        catch = ut->uu_pri & PCATCH;
        p = current_proc();
 
-#if FIXME  /* [ */
-       thread->wait_mesg = NULL;
-#endif  /* FIXME ] */
-       switch (get_thread_waitresult(thread)) {
+       switch (get_thread_waitresult(self)) {
                case THREAD_TIMED_OUT:
                        error = EWOULDBLOCK;
                        break;
@@ -87,7 +85,7 @@ _sleep_continue(void)
                        /* else fall through */
                case THREAD_INTERRUPTED:
                        if (catch) {
-                               if (thread_should_abort(current_thread())) {
+                               if (thread_should_abort(self)) {
                                        error = EINTR;
                                } else if (SHOULDissignal(p,ut)) {
                                        if (sig = CURSIG(p)) {
@@ -96,7 +94,7 @@ _sleep_continue(void)
                                                else
                                                        error = ERESTART;
                                        }
-                                       if (thread_should_abort(current_thread())) {
+                                       if (thread_should_abort(self)) {
                                                error = EINTR;
                                        }
                                }
@@ -106,7 +104,7 @@ _sleep_continue(void)
        }
 
        if (error == EINTR || error == ERESTART)
-               act_set_astbsd(th_act);
+               act_set_astbsd(self);
 
        if (ut->uu_timo)
                thread_cancel_timer();
@@ -142,8 +140,7 @@ _sleep(
        int                     (*continuation)(int))
 {
        register struct proc *p;
-       register thread_t thread = current_thread();
-       thread_act_t th_act;
+       register thread_t self = current_act();
        struct uthread * ut;
        int sig, catch = pri & PCATCH;
        int sigttblock = pri & PTTYBLOCK;
@@ -153,8 +150,7 @@ _sleep(
 
        s = splhigh();
 
-       th_act = current_act();
-       ut = get_bsdthread_info(th_act);
+       ut = get_bsdthread_info(self);
        
        p = current_proc();
 #if KTRACE
@@ -163,11 +159,11 @@ _sleep(
 #endif 
        p->p_priority = pri & PRIMASK;
                
-       if (chan)
-               wait_result = assert_wait(chan,
-                                                                 (catch) ? THREAD_ABORTSAFE : THREAD_UNINT);
-
-       if (abstime)
+       if (chan != NULL)
+               assert_wait_prim(chan, NULL, abstime,
+                                                       (catch) ? THREAD_ABORTSAFE : THREAD_UNINT);
+       else
+       if (abstime != 0)
                thread_set_timer_deadline(abstime);
 
        /*
@@ -182,7 +178,8 @@ _sleep(
        if (catch) {
                if (SHOULDissignal(p,ut)) {
                        if (sig = CURSIG(p)) {
-                               clear_wait(thread, THREAD_INTERRUPTED);
+                               if (clear_wait(self, THREAD_INTERRUPTED) == KERN_FAILURE)
+                                       goto block;
                                /* if SIGTTOU or SIGTTIN then block till SIGCONT */
                                if (sigttblock && ((sig == SIGTTOU) || (sig == SIGTTIN))) {
                                        p->p_flag |= P_TTYSLEEP;
@@ -203,24 +200,24 @@ _sleep(
                                goto out;
                        }
                }
-               if (thread_should_abort(current_thread())) {
-                       clear_wait(thread, THREAD_INTERRUPTED);
+               if (thread_should_abort(self)) {
+                       if (clear_wait(self, THREAD_INTERRUPTED) == KERN_FAILURE)
+                               goto block;
                        error = EINTR;
                        goto out;
                }
-               if (get_thread_waitresult(thread) != THREAD_WAITING) {
+               if (get_thread_waitresult(self) != THREAD_WAITING) {
                        /*already happened */
                        goto out;
                }
        }
 
-#if FIXME  /* [ */
-       thread->wait_mesg = wmsg;
-#endif  /* FIXME ] */
+block:
+
        splx(s);
        p->p_stats->p_ru.ru_nvcsw++;
 
-       if (continuation != THREAD_CONTINUE_NULL ) {
+       if ((thread_continue_t)continuation != THREAD_CONTINUE_NULL ) {
          ut->uu_continuation = continuation;
          ut->uu_pri = pri;
          ut->uu_timo = abstime? 1: 0;
@@ -230,9 +227,6 @@ _sleep(
 
        wait_result = thread_block(THREAD_CONTINUE_NULL);
 
-#if FIXME  /* [ */
-       thread->wait_mesg = NULL;
-#endif  /* FIXME ] */
        switch (wait_result) {
                case THREAD_TIMED_OUT:
                        error = EWOULDBLOCK;
@@ -248,7 +242,7 @@ _sleep(
                        /* else fall through */
                case THREAD_INTERRUPTED:
                        if (catch) {
-                               if (thread_should_abort(current_thread())) {
+                               if (thread_should_abort(self)) {
                                        error = EINTR;
                                } else if (SHOULDissignal(p,ut)) {
                                        if (sig = CURSIG(p)) {
@@ -257,7 +251,7 @@ _sleep(
                                                else
                                                        error = ERESTART;
                                        }
-                                       if (thread_should_abort(current_thread())) {
+                                       if (thread_should_abort(self)) {
                                                error = EINTR;
                                        }
                                }
@@ -267,7 +261,7 @@ _sleep(
        }
 out:
        if (error == EINTR || error == ERESTART)
-               act_set_astbsd(th_act);
+               act_set_astbsd(self);
        if (abstime)
                thread_cancel_timer();
        (void) splx(s);