X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/2d21ac55c334faf3a56e5634905ed6987fc787d4..bb59bff194111743b33cc36712410b5656329d3c:/bsd/kern/kern_synch.c?ds=sidebyside diff --git a/bsd/kern/kern_synch.c b/bsd/kern/kern_synch.c index 8cfe29bfc..b1c4eda1c 100644 --- a/bsd/kern/kern_synch.c +++ b/bsd/kern/kern_synch.c @@ -53,12 +53,11 @@ #include #include -#include +#include #include /* for unix_syscall_return() */ #include -extern boolean_t thread_should_abort(thread_t); /* XXX */ extern void compute_averunnable(void *); /* XXX */ @@ -71,11 +70,12 @@ _sleep_continue( __unused void *parameter, wait_result_t wresult) struct uthread * ut; int sig, catch; int error = 0; - int dropmutex; + int dropmutex, spinmutex; ut = get_bsdthread_info(self); catch = ut->uu_pri & PCATCH; dropmutex = ut->uu_pri & PDROP; + spinmutex = ut->uu_pri & PSPIN; switch (wresult) { case THREAD_TIMED_OUT: @@ -116,9 +116,12 @@ _sleep_continue( __unused void *parameter, wait_result_t wresult) if (error == EINTR || error == ERESTART) act_set_astbsd(self); - if (ut->uu_mtx && !dropmutex) - lck_mtx_lock(ut->uu_mtx); - + if (ut->uu_mtx && !dropmutex) { + if (spinmutex) + lck_mtx_lock_spin(ut->uu_mtx); + else + lck_mtx_lock(ut->uu_mtx); + } ut->uu_wchan = NULL; ut->uu_wmesg = NULL; @@ -158,8 +161,9 @@ _sleep( struct proc *p; thread_t self = current_thread(); struct uthread * ut; - int sig, catch = pri & PCATCH; + int sig, catch; int dropmutex = pri & PDROP; + int spinmutex = pri & PSPIN; int wait_result; int error = 0; @@ -169,27 +173,40 @@ _sleep( p->p_priority = pri & PRIMASK; /* It can still block in proc_exit() after the teardown. */ if (p->p_stats != NULL) - OSIncrementAtomic(&p->p_stats->p_ru.ru_nvcsw); + OSIncrementAtomicLong(&p->p_stats->p_ru.ru_nvcsw); + + if (pri & PCATCH) + catch = THREAD_ABORTSAFE; + else + catch = THREAD_UNINT; /* set wait message & channel */ ut->uu_wchan = chan; ut->uu_wmesg = wmsg ? wmsg : "unknown"; if (mtx != NULL && chan != NULL && (thread_continue_t)continuation == THREAD_CONTINUE_NULL) { + int flags; + + if (dropmutex) + flags = LCK_SLEEP_UNLOCK; + else + flags = LCK_SLEEP_DEFAULT; + + if (spinmutex) + flags |= LCK_SLEEP_SPIN; if (abstime) - wait_result = lck_mtx_sleep_deadline(mtx, (dropmutex) ? LCK_SLEEP_UNLOCK : 0, - chan, (catch) ? THREAD_ABORTSAFE : THREAD_UNINT, abstime); + wait_result = lck_mtx_sleep_deadline(mtx, flags, chan, catch, abstime); else - wait_result = lck_mtx_sleep(mtx, (dropmutex) ? LCK_SLEEP_UNLOCK : 0, - chan, (catch) ? THREAD_ABORTSAFE : THREAD_UNINT); + wait_result = lck_mtx_sleep(mtx, flags, chan, catch); } else { if (chan != NULL) - assert_wait_deadline(chan, (catch) ? THREAD_ABORTSAFE : THREAD_UNINT, abstime); + assert_wait_deadline(chan, catch, abstime); if (mtx) lck_mtx_unlock(mtx); - if (catch) { + + if (catch == THREAD_ABORTSAFE) { if (SHOULDissignal(p,ut)) { if ((sig = CURSIG(p)) != 0) { if (clear_wait(self, THREAD_INTERRUPTED) == KERN_FAILURE) @@ -198,8 +215,12 @@ _sleep( error = EINTR; else error = ERESTART; - if (mtx && !dropmutex) - lck_mtx_lock(mtx); + if (mtx && !dropmutex) { + if (spinmutex) + lck_mtx_lock_spin(mtx); + else + lck_mtx_lock(mtx); + } goto out; } } @@ -208,8 +229,12 @@ _sleep( goto block; error = EINTR; - if (mtx && !dropmutex) - lck_mtx_lock(mtx); + if (mtx && !dropmutex) { + if (spinmutex) + lck_mtx_lock_spin(mtx); + else + lck_mtx_lock(mtx); + } goto out; } } @@ -227,8 +252,12 @@ block: wait_result = thread_block(THREAD_CONTINUE_NULL); - if (mtx && !dropmutex) - lck_mtx_lock(mtx); + if (mtx && !dropmutex) { + if (spinmutex) + lck_mtx_lock_spin(mtx); + else + lck_mtx_lock(mtx); + } } switch (wait_result) { @@ -241,11 +270,11 @@ block: * first, regardless of whether awakened due * to receiving event. */ - if (!catch) + if (catch != THREAD_ABORTSAFE) break; /* else fall through */ case THREAD_INTERRUPTED: - if (catch) { + if (catch == THREAD_ABORTSAFE) { if (thread_should_abort(self)) { error = EINTR; } else if (SHOULDissignal(p, ut)) { @@ -258,7 +287,10 @@ block: if (thread_should_abort(self)) { error = EINTR; } - } + } else if( (ut->uu_flag & ( UT_CANCELDISABLE | UT_CANCEL | UT_CANCELED)) == UT_CANCEL) { + /* due to thread cancel */ + error = EINTR; + } } else error = EINTR; break; @@ -372,7 +404,7 @@ tsleep1( void wakeup(void *chan) { - thread_wakeup_prim((caddr_t)chan, FALSE, THREAD_AWAKENED); + thread_wakeup((caddr_t)chan); } /* @@ -384,7 +416,7 @@ wakeup(void *chan) void wakeup_one(caddr_t chan) { - thread_wakeup_prim((caddr_t)chan, TRUE, THREAD_AWAKENED); + thread_wakeup_one((caddr_t)chan); } /*