From owner-p4-projects@FreeBSD.ORG Sat Nov 20 04:15:31 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 7824016A4D1; Sat, 20 Nov 2004 04:15:31 +0000 (GMT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 50DF516A4CF for ; Sat, 20 Nov 2004 04:15:31 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2C13043D1D for ; Sat, 20 Nov 2004 04:15:31 +0000 (GMT) (envelope-from davidxu@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.11/8.12.11) with ESMTP id iAK4FVhU005438 for ; Sat, 20 Nov 2004 04:15:31 GMT (envelope-from davidxu@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.11/8.12.11/Submit) id iAK4FUEQ005435 for perforce@freebsd.org; Sat, 20 Nov 2004 04:15:30 GMT (envelope-from davidxu@freebsd.org) Date: Sat, 20 Nov 2004 04:15:30 GMT Message-Id: <200411200415.iAK4FUEQ005435@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to davidxu@freebsd.org using -f From: David Xu To: Perforce Change Reviews Subject: PERFORCE change 65508 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 20 Nov 2004 04:15:31 -0000 http://perforce.freebsd.org/chv.cgi?CH=65508 Change 65508 by davidxu@davidxu_alona on 2004/11/20 04:15:10 1. If thread is exiting, don't return true in checkcancel(). 2. Use thread lock. Affected files ... .. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_cancel.c#2 edit Differences ... ==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_cancel.c#2 (text+ko) ==== @@ -14,15 +14,24 @@ static inline int checkcancel(struct pthread *curthread) { - if (((curthread->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) && - ((curthread->cancelflags & THR_CANCELLING) != 0)) { + if ((curthread->cancelflags & THR_CANCELLING) != 0) { /* * It is possible for this thread to be swapped out * while performing cancellation; do not allow it * to be cancelled again. */ - curthread->cancelflags &= ~THR_CANCELLING; - return (1); + if ((curthread->flags & THR_FLAGS_EXITING) != 0) { + /* + * this may happen once, but after this, it + * shouldn't happen again. + */ + curthread->cancelflags &= ~THR_CANCELLING; + return (0); + } + if ((curthread->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) { + curthread->cancelflags &= ~THR_CANCELLING; + return (1); + } } else return (0); @@ -33,7 +42,7 @@ { if (checkcancel(curthread) != 0) { /* Unlock before exiting: */ - THR_THREAD_UNLOCK(curthread, curthread); + THR_UNLOCK(curthread); _thr_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); @@ -46,7 +55,7 @@ { struct pthread *curthread = _get_curthread(); struct pthread *joinee = NULL; - struct kse_mailbox *kmbx = NULL; + long tid = -1; int ret; if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0)) == 0) { @@ -54,9 +63,7 @@ * Take the thread's lock while we change the cancel flags. */ THR_THREAD_LOCK(curthread, pthread); - THR_SCHED_LOCK(curthread, pthread); if (pthread->flags & THR_FLAGS_EXITING) { - THR_SCHED_UNLOCK(curthread, pthread); THR_THREAD_UNLOCK(curthread, pthread); _thr_ref_delete(curthread, pthread); return (ESRCH); @@ -75,40 +82,15 @@ case PS_RUNNING: /* No need to resume: */ pthread->cancelflags |= THR_CANCELLING; + tid = pthread->tid; break; - case PS_LOCKWAIT: - /* - * These can't be removed from the queue. - * Just mark it as cancelling and tell it - * to yield once it leaves the critical - * region. - */ - pthread->cancelflags |= THR_CANCELLING; - pthread->critical_yield = 1; - break; - - case PS_SLEEP_WAIT: - case PS_SIGSUSPEND: - case PS_SIGWAIT: - /* Interrupt and resume: */ - pthread->interrupted = 1; - pthread->cancelflags |= THR_CANCELLING; - kmbx = _thr_setrunnable_unlocked(pthread); - break; - case PS_JOIN: /* Disconnect the thread from the joinee: */ joinee = pthread->join_status.thread; pthread->join_status.thread = NULL; pthread->cancelflags |= THR_CANCELLING; - kmbx = _thr_setrunnable_unlocked(pthread); - if ((joinee != NULL) && - (pthread->kseg == joinee->kseg)) { - /* Remove the joiner from the joinee. */ - joinee->joiner = NULL; - joinee = NULL; - } + tid = _thr_setrunnable_unlocked(pthread); break; case PS_SUSPENDED: @@ -126,7 +108,7 @@ */ pthread->interrupted = 1; pthread->cancelflags |= THR_CANCEL_NEEDED; - kmbx = _thr_setrunnable_unlocked(pthread); + tid = _thr_setrunnable_unlocked(pthread); pthread->continuation = _thr_finish_cancellation; break; @@ -137,29 +119,27 @@ /* Ignore - only here to silence -Wall: */ break; } - if ((pthread->cancelflags & THR_AT_CANCEL_POINT) && - (pthread->blocked != 0 || - pthread->attr.flags & PTHREAD_SCOPE_SYSTEM)) - kse_thr_interrupt(&pthread->tcb->tcb_tmbx, - KSE_INTR_INTERRUPT, 0); + +#if 0 + thr_interrupt(pthread->tid, 1); +#endif } /* * Release the thread's lock and remove the * reference: */ - THR_SCHED_UNLOCK(curthread, pthread); THR_THREAD_UNLOCK(curthread, pthread); _thr_ref_delete(curthread, pthread); - if (kmbx != NULL) - kse_wakeup(kmbx); + if (tid != -1) + thr_wake(tid); if ((joinee != NULL) && (_thr_ref_add(curthread, joinee, /* include dead */1) == 0)) { /* Remove the joiner from the joinee. */ - THR_SCHED_LOCK(curthread, joinee); + THR_THREAD_LOCK(curthread, joinee); joinee->joiner = NULL; - THR_SCHED_UNLOCK(curthread, joinee); + THR_THREAD_UNLOCK(curthread, joinee); _thr_ref_delete(curthread, joinee); } } @@ -175,7 +155,7 @@ int need_exit = 0; /* Take the thread's lock while fiddling with the state: */ - THR_THREAD_LOCK(curthread, curthread); + THR_LOCK(curthread); ostate = curthread->cancelflags & PTHREAD_CANCEL_DISABLE; @@ -194,7 +174,7 @@ ret = EINVAL; } - THR_THREAD_UNLOCK(curthread, curthread); + THR_UNLOCK(curthread); if (need_exit != 0) { _thr_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); @@ -215,7 +195,7 @@ int need_exit = 0; /* Take the thread's lock while fiddling with the state: */ - THR_THREAD_LOCK(curthread, curthread); + THR_LOCK(curthread); otype = curthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS; switch (type) { @@ -232,7 +212,7 @@ ret = EINVAL; } - THR_THREAD_UNLOCK(curthread, curthread); + THR_UNLOCK(curthread); if (need_exit != 0) { _thr_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); @@ -249,30 +229,30 @@ { struct pthread *curthread = _get_curthread(); - THR_THREAD_LOCK(curthread, curthread); + THR_LOCK(curthread); testcancel(curthread); - THR_THREAD_UNLOCK(curthread, curthread); + THR_UNLOCK(curthread); } void -_thr_cancel_enter(struct pthread *thread) +_thr_cancel_enter(struct pthread *curthread) { /* Look for a cancellation before we block: */ - THR_THREAD_LOCK(thread, thread); - testcancel(thread); - thread->cancelflags |= THR_AT_CANCEL_POINT; - THR_THREAD_UNLOCK(thread, thread); + THR_LOCK(curthread); + testcancel(curthread); + curthread->cancelflags |= THR_AT_CANCEL_POINT; + THR_UNLOCK(curthread); } void -_thr_cancel_leave(struct pthread *thread, int check) +_thr_cancel_leave(struct pthread *curthread, int check) { - THR_THREAD_LOCK(thread, thread); - thread->cancelflags &= ~THR_AT_CANCEL_POINT; + THR_LOCK(curthread); + curthread->cancelflags &= ~THR_AT_CANCEL_POINT; /* Look for a cancellation after we unblock: */ if (check) - testcancel(thread); - THR_THREAD_UNLOCK(thread, thread); + testcancel(curthread); + THR_UNLOCK(curthread); } void @@ -283,12 +263,12 @@ curthread->continuation = NULL; curthread->interrupted = 0; - THR_THREAD_LOCK(curthread, curthread); + THR_LOCK(curthread); if ((curthread->cancelflags & THR_CANCEL_NEEDED) != 0) { curthread->cancelflags &= ~THR_CANCEL_NEEDED; - THR_THREAD_UNLOCK(curthread, curthread); + THR_UNLOCK(curthread); _thr_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); } - THR_THREAD_UNLOCK(curthread, curthread); + THR_UNLOCK(curthread); }