diff options
author | David Xu <davidxu@FreeBSD.org> | 2003-12-09 02:20:56 +0000 |
---|---|---|
committer | David Xu <davidxu@FreeBSD.org> | 2003-12-09 02:20:56 +0000 |
commit | 71679e629d6933bda40564da2a54894aed1358f3 (patch) | |
tree | 336614966b1df2677098ac89ea3a03fc82f7141b /lib | |
parent | ef7af95abd4c13eb0c2cd6961ee08594bfcb7513 (diff) | |
download | src-test2-71679e629d6933bda40564da2a54894aed1358f3.tar.gz src-test2-71679e629d6933bda40564da2a54894aed1358f3.zip |
Notes
Diffstat (limited to 'lib')
60 files changed, 296 insertions, 272 deletions
diff --git a/lib/libkse/thread/thr_aio_suspend.c b/lib/libkse/thread/thr_aio_suspend.c index 94eed27ca02e..5b8a6dcaa421 100644 --- a/lib/libkse/thread/thr_aio_suspend.c +++ b/lib/libkse/thread/thr_aio_suspend.c @@ -42,9 +42,9 @@ _aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_aio_suspend(iocbs, niocb, timeout); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libkse/thread/thr_cancel.c b/lib/libkse/thread/thr_cancel.c index 3387b9ae99c0..8cd7acc2f6af 100644 --- a/lib/libkse/thread/thr_cancel.c +++ b/lib/libkse/thread/thr_cancel.c @@ -11,8 +11,35 @@ __weak_reference(_pthread_setcancelstate, pthread_setcancelstate); __weak_reference(_pthread_setcanceltype, pthread_setcanceltype); __weak_reference(_pthread_testcancel, pthread_testcancel); -static int checkcancel(struct pthread *curthread); -static void testcancel(struct pthread *curthread); +static inline int +checkcancel(struct pthread *curthread) +{ + if (((curthread->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) && + ((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); + } + else + return (0); +} + +static inline void +testcancel(struct pthread *curthread) +{ + if (checkcancel(curthread) != 0) { + /* Unlock before exiting: */ + THR_THREAD_UNLOCK(curthread, curthread); + + _thr_exit_cleanup(); + pthread_exit(PTHREAD_CANCELED); + PANIC("cancel"); + } +} int _pthread_cancel(pthread_t pthread) @@ -217,37 +244,6 @@ _pthread_setcanceltype(int type, int *oldtype) return (ret); } -static int -checkcancel(struct pthread *curthread) -{ - if (((curthread->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) && - ((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); - } - else - return (0); -} - -static void -testcancel(struct pthread *curthread) -{ - - if (checkcancel(curthread) != 0) { - /* Unlock before exiting: */ - THR_THREAD_UNLOCK(curthread, curthread); - - _thr_exit_cleanup(); - pthread_exit(PTHREAD_CANCELED); - PANIC("cancel"); - } -} - void _pthread_testcancel(void) { @@ -259,10 +255,8 @@ _pthread_testcancel(void) } void -_thr_enter_cancellation_point(struct pthread *thread) +_thr_cancel_enter(struct pthread *thread) { - if (!_kse_isthreaded()) - return; /* Look for a cancellation before we block: */ THR_THREAD_LOCK(thread, thread); testcancel(thread); @@ -271,14 +265,13 @@ _thr_enter_cancellation_point(struct pthread *thread) } void -_thr_leave_cancellation_point(struct pthread *thread) +_thr_cancel_leave(struct pthread *thread, int check) { - if (!_kse_isthreaded()) - return; THR_THREAD_LOCK(thread, thread); thread->cancelflags &= ~THR_AT_CANCEL_POINT; /* Look for a cancellation after we unblock: */ - testcancel(thread); + if (check) + testcancel(thread); THR_THREAD_UNLOCK(thread, thread); } diff --git a/lib/libkse/thread/thr_close.c b/lib/libkse/thread/thr_close.c index 269140b3e7f7..263d4a63aaaa 100644 --- a/lib/libkse/thread/thr_close.c +++ b/lib/libkse/thread/thr_close.c @@ -47,9 +47,9 @@ __close(int fd) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_close(fd); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libkse/thread/thr_cond.c b/lib/libkse/thread/thr_cond.c index a1df0bd67ce4..fd7b6d927cff 100644 --- a/lib/libkse/thread/thr_cond.c +++ b/lib/libkse/thread/thr_cond.c @@ -365,9 +365,9 @@ __pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = _pthread_cond_wait(cond, mutex); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } @@ -571,9 +571,9 @@ __pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = _pthread_cond_timedwait(cond, mutex, abstime); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libkse/thread/thr_creat.c b/lib/libkse/thread/thr_creat.c index 478e037fc736..d2a91bfcdd2a 100644 --- a/lib/libkse/thread/thr_creat.c +++ b/lib/libkse/thread/thr_creat.c @@ -43,9 +43,13 @@ ___creat(const char *path, mode_t mode) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __creat(path, mode); - _thr_leave_cancellation_point(curthread); + /* + * To avoid possible file handle leak, + * only check cancellation point if it is failure + */ + _thr_cancel_leave(curthread, (ret == -1)); return ret; } diff --git a/lib/libkse/thread/thr_fcntl.c b/lib/libkse/thread/thr_fcntl.c index 0b4a9904776b..947bc1159d64 100644 --- a/lib/libkse/thread/thr_fcntl.c +++ b/lib/libkse/thread/thr_fcntl.c @@ -44,14 +44,21 @@ int __fcntl(int fd, int cmd,...) { struct pthread *curthread = _get_curthread(); - int ret; + int ret, check = 1; va_list ap; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); va_start(ap, cmd); switch (cmd) { case F_DUPFD: + ret = __sys_fcntl(fd, cmd, va_arg(ap, int)); + /* + * To avoid possible file handle leak, + * only check cancellation point if it is failure + */ + check = (ret == -1); + break; case F_SETFD: case F_SETFL: ret = __sys_fcntl(fd, cmd, va_arg(ap, int)); @@ -65,7 +72,7 @@ __fcntl(int fd, int cmd,...) } va_end(ap); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, check); return (ret); } diff --git a/lib/libkse/thread/thr_fsync.c b/lib/libkse/thread/thr_fsync.c index d5d3398371b9..15fe31a51c5a 100644 --- a/lib/libkse/thread/thr_fsync.c +++ b/lib/libkse/thread/thr_fsync.c @@ -43,9 +43,9 @@ __fsync(int fd) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_fsync(fd); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libkse/thread/thr_join.c b/lib/libkse/thread/thr_join.c index 592aa3aa8f98..9f940da0ff74 100644 --- a/lib/libkse/thread/thr_join.c +++ b/lib/libkse/thread/thr_join.c @@ -45,19 +45,19 @@ _pthread_join(pthread_t pthread, void **thread_return) kse_critical_t crit; int ret = 0; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); /* Check if the caller has specified an invalid thread: */ if (pthread == NULL || pthread->magic != THR_MAGIC) { /* Invalid thread: */ - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (EINVAL); } /* Check if the caller has specified itself: */ if (pthread == curthread) { /* Avoid a deadlock condition: */ - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (EDEADLK); } @@ -67,7 +67,7 @@ _pthread_join(pthread_t pthread, void **thread_return) */ if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/1)) != 0) { /* Return an error: */ - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ESRCH); } @@ -155,7 +155,7 @@ _pthread_join(pthread_t pthread, void **thread_return) *thread_return = curthread->join_status.ret; } } - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); /* Return the completion status: */ return (ret); diff --git a/lib/libkse/thread/thr_kern.c b/lib/libkse/thread/thr_kern.c index 7fd8b38fe0a8..a5d068bf3c64 100644 --- a/lib/libkse/thread/thr_kern.c +++ b/lib/libkse/thread/thr_kern.c @@ -389,12 +389,6 @@ _kse_init(void) } } -int -_kse_isthreaded(void) -{ - return (__isthreaded != 0); -} - /* * This is called when the first thread (other than the initial * thread) is created. @@ -636,7 +630,7 @@ _thr_sched_switch_unlocked(struct pthread *curthread) if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) kse_sched_single(&curkse->k_kcb->kcb_kmbx); else { - curkse->k_switch = 1; + KSE_SET_SWITCH(curkse); _thread_enter_uts(curthread->tcb, curkse->k_kcb); } @@ -696,7 +690,7 @@ kse_sched_single(struct kse_mailbox *kmbx) curkse = (struct kse *)kmbx->km_udata; curthread = curkse->k_curthread; - if ((curkse->k_flags & KF_INITIALIZED) == 0) { + if (__predict_false((curkse->k_flags & KF_INITIALIZED) == 0)) { /* Setup this KSEs specific data. */ _kcb_set(curkse->k_kcb); _tcb_set(curkse->k_kcb, curthread->tcb); @@ -914,7 +908,7 @@ kse_sched_multi(struct kse_mailbox *kmbx) "Mailbox not null in kse_sched_multi"); /* Check for first time initialization: */ - if ((curkse->k_flags & KF_INITIALIZED) == 0) { + if (__predict_false((curkse->k_flags & KF_INITIALIZED) == 0)) { /* Setup this KSEs specific data. */ _kcb_set(curkse->k_kcb); @@ -929,9 +923,15 @@ kse_sched_multi(struct kse_mailbox *kmbx) _tcb_set(curkse->k_kcb, NULL); /* If this is an upcall; take the scheduler lock. */ - if (curkse->k_switch == 0) + if (!KSE_IS_SWITCH(curkse)) KSE_SCHED_LOCK(curkse, curkse->k_kseg); - curkse->k_switch = 0; + else + KSE_CLEAR_SWITCH(curkse); + + if (KSE_IS_IDLE(curkse)) { + KSE_CLEAR_IDLE(curkse); + curkse->k_kseg->kg_idle_kses--; + } /* * Now that the scheduler lock is held, get the current @@ -941,10 +941,6 @@ kse_sched_multi(struct kse_mailbox *kmbx) */ curthread = curkse->k_curthread; - if (KSE_IS_IDLE(curkse)) { - KSE_CLEAR_IDLE(curkse); - curkse->k_kseg->kg_idle_kses--; - } /* * If the current thread was completed in another KSE, then * it will be in the run queue. Don't mark it as being blocked. @@ -2295,11 +2291,8 @@ kse_reinit(struct kse *kse, int sys_scope) kse->k_schedq = 0; kse->k_locklevel = 0; kse->k_flags = 0; - kse->k_idle = 0; kse->k_error = 0; kse->k_cpu = 0; - kse->k_done = 0; - kse->k_switch = 0; kse->k_sigseqno = 0; } diff --git a/lib/libkse/thread/thr_msync.c b/lib/libkse/thread/thr_msync.c index 24b78ecbacdf..c2e34335dc4a 100644 --- a/lib/libkse/thread/thr_msync.c +++ b/lib/libkse/thread/thr_msync.c @@ -25,9 +25,9 @@ __msync(void *addr, size_t len, int flags) * write. The only real use of this wrapper is to guarantee * a cancellation point, as per the standard. sigh. */ - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_msync(addr, len, flags); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libkse/thread/thr_nanosleep.c b/lib/libkse/thread/thr_nanosleep.c index 57bbef9e37fc..e8baa844a1d0 100644 --- a/lib/libkse/thread/thr_nanosleep.c +++ b/lib/libkse/thread/thr_nanosleep.c @@ -121,9 +121,9 @@ __nanosleep(const struct timespec *time_to_sleep, struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = _nanosleep(time_to_sleep, time_remaining); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libkse/thread/thr_open.c b/lib/libkse/thread/thr_open.c index ec60ba4e723a..8ac625d8a30f 100644 --- a/lib/libkse/thread/thr_open.c +++ b/lib/libkse/thread/thr_open.c @@ -50,7 +50,7 @@ __open(const char *path, int flags,...) int mode = 0; va_list ap; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); /* Check if the file is being created: */ if (flags & O_CREAT) { @@ -61,7 +61,11 @@ __open(const char *path, int flags,...) } ret = __sys_open(path, flags, mode); - _thr_leave_cancellation_point(curthread); + /* + * To avoid possible file handle leak, + * only check cancellation point if it is failure + */ + _thr_cancel_leave(curthread, (ret == -1)); return ret; } diff --git a/lib/libkse/thread/thr_pause.c b/lib/libkse/thread/thr_pause.c index aa97c77823fe..391b5a0b55bb 100644 --- a/lib/libkse/thread/thr_pause.c +++ b/lib/libkse/thread/thr_pause.c @@ -43,9 +43,9 @@ _pause(void) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __pause(); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libkse/thread/thr_poll.c b/lib/libkse/thread/thr_poll.c index 0b78047838e0..1b165989b4f3 100644 --- a/lib/libkse/thread/thr_poll.c +++ b/lib/libkse/thread/thr_poll.c @@ -49,9 +49,9 @@ __poll(struct pollfd *fds, unsigned int nfds, int timeout) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_poll(fds, nfds, timeout); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libkse/thread/thr_private.h b/lib/libkse/thread/thr_private.h index fc5f97e7c97a..8c344ec85e23 100644 --- a/lib/libkse/thread/thr_private.h +++ b/lib/libkse/thread/thr_private.h @@ -81,12 +81,14 @@ #define DBG_MUTEX 0x0001 #define DBG_SIG 0x0002 - +#ifdef _PTHREADS_INVARIANTS #define THR_ASSERT(cond, msg) do { \ if (!(cond)) \ PANIC(msg); \ } while (0) - +#else +#define THR_ASSERT(cond, msg) +#endif /* * State change macro without scheduling queue change: @@ -192,15 +194,21 @@ struct kse { int k_flags; #define KF_STARTED 0x0001 /* kernel kse created */ #define KF_INITIALIZED 0x0002 /* initialized on 1st upcall */ -#define KF_TERMINATED 0x0004 - int k_idle; /* kse is idle */ +#define KF_TERMINATED 0x0004 /* kse is terminated */ +#define KF_IDLE 0x0008 /* kse is idle */ +#define KF_SWITCH 0x0010 /* thread switch in UTS */ int k_error; /* syscall errno in critical */ int k_cpu; /* CPU ID when bound */ - int k_done; /* this KSE is done */ - int k_switch; /* thread switch in UTS */ int k_sigseqno; /* signal buffered count */ }; +#define KSE_SET_IDLE(kse) ((kse)->k_flags |= KF_IDLE) +#define KSE_CLEAR_IDLE(kse) ((kse)->k_flags &= ~KF_IDLE) +#define KSE_IS_IDLE(kse) (((kse)->k_flags & KF_IDLE) != 0) +#define KSE_SET_SWITCH(kse) ((kse)->k_flags |= KF_SWITCH) +#define KSE_CLEAR_SWITCH(kse) ((kse)->k_flags &= ~KF_SWITCH) +#define KSE_IS_SWITCH(kse) (((kse)->k_flags & KF_SWITCH) != 0) + /* * Each KSE group contains one or more KSEs in which threads can run. * At least for now, there is one scheduling queue per KSE group; KSEs @@ -293,10 +301,6 @@ do { \ #define KSE_WAKEUP(kse) kse_wakeup(&(kse)->k_kcb->kcb_kmbx) -#define KSE_SET_IDLE(kse) ((kse)->k_idle = 1) -#define KSE_CLEAR_IDLE(kse) ((kse)->k_idle = 0) -#define KSE_IS_IDLE(kse) ((kse)->k_idle != 0) - /* * TailQ initialization values. */ @@ -659,7 +663,6 @@ struct pthread { int active; /* thread running */ int blocked; /* thread blocked in kernel */ int need_switchout; - int need_wakeup; /* * Used for tracking delivery of signal handlers. @@ -984,7 +987,15 @@ do { \ (((thrd)->state == PS_SUSPENDED) || \ (((thrd)->flags & THR_FLAGS_SUSPENDED) != 0)) #define THR_IS_EXITING(thrd) (((thrd)->flags & THR_FLAGS_EXITING) != 0) - + +extern int __isthreaded; + +static inline int +_kse_isthreaded(void) +{ + return (__isthreaded != 0); +} + /* * Global variables for the pthread kernel. */ @@ -1149,8 +1160,8 @@ void _thr_sig_rundown(struct pthread *, ucontext_t *, void _thr_sig_send(struct pthread *pthread, int sig); void _thr_sigframe_restore(struct pthread *thread, struct pthread_sigframe *psf); void _thr_spinlock_init(void); -void _thr_enter_cancellation_point(struct pthread *); -void _thr_leave_cancellation_point(struct pthread *); +void _thr_cancel_enter(struct pthread *); +void _thr_cancel_leave(struct pthread *, int); int _thr_setconcurrency(int new_level); int _thr_setmaxconcurrency(void); void _thr_critical_enter(struct pthread *); diff --git a/lib/libkse/thread/thr_pselect.c b/lib/libkse/thread/thr_pselect.c index c1a4c5ddba0f..ce7a530dc4f4 100644 --- a/lib/libkse/thread/thr_pselect.c +++ b/lib/libkse/thread/thr_pselect.c @@ -49,9 +49,9 @@ _pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __pselect(count, rfds, wfds, efds, timo, mask); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libkse/thread/thr_read.c b/lib/libkse/thread/thr_read.c index 34dabd35ac4f..c0391c55411a 100644 --- a/lib/libkse/thread/thr_read.c +++ b/lib/libkse/thread/thr_read.c @@ -48,9 +48,9 @@ __read(int fd, void *buf, size_t nbytes) struct pthread *curthread = _get_curthread(); ssize_t ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_read(fd, buf, nbytes); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libkse/thread/thr_readv.c b/lib/libkse/thread/thr_readv.c index 3a8823f90657..eb0e54aa0454 100644 --- a/lib/libkse/thread/thr_readv.c +++ b/lib/libkse/thread/thr_readv.c @@ -48,9 +48,9 @@ __readv(int fd, const struct iovec *iov, int iovcnt) struct pthread *curthread = _get_curthread(); ssize_t ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_readv(fd, iov, iovcnt); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libkse/thread/thr_select.c b/lib/libkse/thread/thr_select.c index 25be6a95be6e..792ff09eb189 100644 --- a/lib/libkse/thread/thr_select.c +++ b/lib/libkse/thread/thr_select.c @@ -57,9 +57,9 @@ __select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, TIMEVAL_TO_TIMESPEC(timeout, &ts); return nanosleep(&ts, NULL); } else { - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); } return ret; } diff --git a/lib/libkse/thread/thr_sem.c b/lib/libkse/thread/thr_sem.c index d6021a8ac3a2..c7f6308c50c4 100644 --- a/lib/libkse/thread/thr_sem.c +++ b/lib/libkse/thread/thr_sem.c @@ -169,7 +169,7 @@ _sem_wait(sem_t *sem) struct pthread *curthread = _get_curthread(); int retval; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); _SEM_CHECK_VALIDITY(sem); @@ -186,7 +186,7 @@ _sem_wait(sem_t *sem) retval = 0; RETURN: - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (retval); } diff --git a/lib/libkse/thread/thr_sigsuspend.c b/lib/libkse/thread/thr_sigsuspend.c index 4d3aa4ec2580..cad57451b406 100644 --- a/lib/libkse/thread/thr_sigsuspend.c +++ b/lib/libkse/thread/thr_sigsuspend.c @@ -95,9 +95,9 @@ __sigsuspend(const sigset_t * set) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = _sigsuspend(set); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libkse/thread/thr_sigwait.c b/lib/libkse/thread/thr_sigwait.c index 43f932172ffe..76f53686098e 100644 --- a/lib/libkse/thread/thr_sigwait.c +++ b/lib/libkse/thread/thr_sigwait.c @@ -137,9 +137,9 @@ __sigtimedwait(const sigset_t *set, siginfo_t *info, struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = lib_sigtimedwait(set, info, timeout); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } @@ -155,9 +155,9 @@ __sigwaitinfo(const sigset_t *set, siginfo_t *info) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = lib_sigtimedwait(set, info, NULL); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } @@ -173,7 +173,7 @@ __sigwait(const sigset_t *set, int *sig) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = lib_sigtimedwait(set, NULL, NULL); if (ret > 0) { *sig = ret; @@ -181,7 +181,7 @@ __sigwait(const sigset_t *set, int *sig) } else ret = -1; - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libkse/thread/thr_sleep.c b/lib/libkse/thread/thr_sleep.c index b494e5bcdea5..7547e60674a1 100644 --- a/lib/libkse/thread/thr_sleep.c +++ b/lib/libkse/thread/thr_sleep.c @@ -43,9 +43,9 @@ _sleep(unsigned int seconds) struct pthread *curthread = _get_curthread(); unsigned int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sleep(seconds); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libkse/thread/thr_system.c b/lib/libkse/thread/thr_system.c index ae26c9cad0d8..57c219977714 100644 --- a/lib/libkse/thread/thr_system.c +++ b/lib/libkse/thread/thr_system.c @@ -43,9 +43,9 @@ _system(const char *string) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __system(string); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libkse/thread/thr_tcdrain.c b/lib/libkse/thread/thr_tcdrain.c index 86af9c2dcaa8..d0d701b0f360 100644 --- a/lib/libkse/thread/thr_tcdrain.c +++ b/lib/libkse/thread/thr_tcdrain.c @@ -43,9 +43,9 @@ _tcdrain(int fd) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __tcdrain(fd); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libkse/thread/thr_wait.c b/lib/libkse/thread/thr_wait.c index b0a3af4b55b0..689f6833dce7 100644 --- a/lib/libkse/thread/thr_wait.c +++ b/lib/libkse/thread/thr_wait.c @@ -42,9 +42,9 @@ _wait(int *istat) struct pthread *curthread = _get_curthread(); pid_t ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __wait(istat); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libkse/thread/thr_wait4.c b/lib/libkse/thread/thr_wait4.c index 07ff79df1825..12a10670dcfd 100644 --- a/lib/libkse/thread/thr_wait4.c +++ b/lib/libkse/thread/thr_wait4.c @@ -49,9 +49,9 @@ __wait4(pid_t pid, int *istat, int options, struct rusage *rusage) struct pthread *curthread = _get_curthread(); pid_t ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = _wait4(pid, istat, options, rusage); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libkse/thread/thr_waitpid.c b/lib/libkse/thread/thr_waitpid.c index e09bbd58db42..4edef3bfdb81 100644 --- a/lib/libkse/thread/thr_waitpid.c +++ b/lib/libkse/thread/thr_waitpid.c @@ -44,9 +44,9 @@ _waitpid(pid_t wpid, int *status, int options) struct pthread *curthread = _get_curthread(); pid_t ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __waitpid(wpid, status, options); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libkse/thread/thr_write.c b/lib/libkse/thread/thr_write.c index 53d897ced1e9..39d221c363d0 100644 --- a/lib/libkse/thread/thr_write.c +++ b/lib/libkse/thread/thr_write.c @@ -48,9 +48,9 @@ __write(int fd, const void *buf, size_t nbytes) struct pthread *curthread = _get_curthread(); ssize_t ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_write(fd, buf, nbytes); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libkse/thread/thr_writev.c b/lib/libkse/thread/thr_writev.c index e13c9d2f2960..81499d708f39 100644 --- a/lib/libkse/thread/thr_writev.c +++ b/lib/libkse/thread/thr_writev.c @@ -50,9 +50,9 @@ __writev(int fd, const struct iovec *iov, int iovcnt) struct pthread *curthread = _get_curthread(); ssize_t ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_writev(fd, iov, iovcnt); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libpthread/thread/thr_aio_suspend.c b/lib/libpthread/thread/thr_aio_suspend.c index 94eed27ca02e..5b8a6dcaa421 100644 --- a/lib/libpthread/thread/thr_aio_suspend.c +++ b/lib/libpthread/thread/thr_aio_suspend.c @@ -42,9 +42,9 @@ _aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_aio_suspend(iocbs, niocb, timeout); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libpthread/thread/thr_cancel.c b/lib/libpthread/thread/thr_cancel.c index 3387b9ae99c0..8cd7acc2f6af 100644 --- a/lib/libpthread/thread/thr_cancel.c +++ b/lib/libpthread/thread/thr_cancel.c @@ -11,8 +11,35 @@ __weak_reference(_pthread_setcancelstate, pthread_setcancelstate); __weak_reference(_pthread_setcanceltype, pthread_setcanceltype); __weak_reference(_pthread_testcancel, pthread_testcancel); -static int checkcancel(struct pthread *curthread); -static void testcancel(struct pthread *curthread); +static inline int +checkcancel(struct pthread *curthread) +{ + if (((curthread->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) && + ((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); + } + else + return (0); +} + +static inline void +testcancel(struct pthread *curthread) +{ + if (checkcancel(curthread) != 0) { + /* Unlock before exiting: */ + THR_THREAD_UNLOCK(curthread, curthread); + + _thr_exit_cleanup(); + pthread_exit(PTHREAD_CANCELED); + PANIC("cancel"); + } +} int _pthread_cancel(pthread_t pthread) @@ -217,37 +244,6 @@ _pthread_setcanceltype(int type, int *oldtype) return (ret); } -static int -checkcancel(struct pthread *curthread) -{ - if (((curthread->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) && - ((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); - } - else - return (0); -} - -static void -testcancel(struct pthread *curthread) -{ - - if (checkcancel(curthread) != 0) { - /* Unlock before exiting: */ - THR_THREAD_UNLOCK(curthread, curthread); - - _thr_exit_cleanup(); - pthread_exit(PTHREAD_CANCELED); - PANIC("cancel"); - } -} - void _pthread_testcancel(void) { @@ -259,10 +255,8 @@ _pthread_testcancel(void) } void -_thr_enter_cancellation_point(struct pthread *thread) +_thr_cancel_enter(struct pthread *thread) { - if (!_kse_isthreaded()) - return; /* Look for a cancellation before we block: */ THR_THREAD_LOCK(thread, thread); testcancel(thread); @@ -271,14 +265,13 @@ _thr_enter_cancellation_point(struct pthread *thread) } void -_thr_leave_cancellation_point(struct pthread *thread) +_thr_cancel_leave(struct pthread *thread, int check) { - if (!_kse_isthreaded()) - return; THR_THREAD_LOCK(thread, thread); thread->cancelflags &= ~THR_AT_CANCEL_POINT; /* Look for a cancellation after we unblock: */ - testcancel(thread); + if (check) + testcancel(thread); THR_THREAD_UNLOCK(thread, thread); } diff --git a/lib/libpthread/thread/thr_close.c b/lib/libpthread/thread/thr_close.c index 269140b3e7f7..263d4a63aaaa 100644 --- a/lib/libpthread/thread/thr_close.c +++ b/lib/libpthread/thread/thr_close.c @@ -47,9 +47,9 @@ __close(int fd) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_close(fd); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libpthread/thread/thr_cond.c b/lib/libpthread/thread/thr_cond.c index a1df0bd67ce4..fd7b6d927cff 100644 --- a/lib/libpthread/thread/thr_cond.c +++ b/lib/libpthread/thread/thr_cond.c @@ -365,9 +365,9 @@ __pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = _pthread_cond_wait(cond, mutex); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } @@ -571,9 +571,9 @@ __pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = _pthread_cond_timedwait(cond, mutex, abstime); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libpthread/thread/thr_creat.c b/lib/libpthread/thread/thr_creat.c index 478e037fc736..d2a91bfcdd2a 100644 --- a/lib/libpthread/thread/thr_creat.c +++ b/lib/libpthread/thread/thr_creat.c @@ -43,9 +43,13 @@ ___creat(const char *path, mode_t mode) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __creat(path, mode); - _thr_leave_cancellation_point(curthread); + /* + * To avoid possible file handle leak, + * only check cancellation point if it is failure + */ + _thr_cancel_leave(curthread, (ret == -1)); return ret; } diff --git a/lib/libpthread/thread/thr_fcntl.c b/lib/libpthread/thread/thr_fcntl.c index 0b4a9904776b..947bc1159d64 100644 --- a/lib/libpthread/thread/thr_fcntl.c +++ b/lib/libpthread/thread/thr_fcntl.c @@ -44,14 +44,21 @@ int __fcntl(int fd, int cmd,...) { struct pthread *curthread = _get_curthread(); - int ret; + int ret, check = 1; va_list ap; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); va_start(ap, cmd); switch (cmd) { case F_DUPFD: + ret = __sys_fcntl(fd, cmd, va_arg(ap, int)); + /* + * To avoid possible file handle leak, + * only check cancellation point if it is failure + */ + check = (ret == -1); + break; case F_SETFD: case F_SETFL: ret = __sys_fcntl(fd, cmd, va_arg(ap, int)); @@ -65,7 +72,7 @@ __fcntl(int fd, int cmd,...) } va_end(ap); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, check); return (ret); } diff --git a/lib/libpthread/thread/thr_fsync.c b/lib/libpthread/thread/thr_fsync.c index d5d3398371b9..15fe31a51c5a 100644 --- a/lib/libpthread/thread/thr_fsync.c +++ b/lib/libpthread/thread/thr_fsync.c @@ -43,9 +43,9 @@ __fsync(int fd) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_fsync(fd); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libpthread/thread/thr_join.c b/lib/libpthread/thread/thr_join.c index 592aa3aa8f98..9f940da0ff74 100644 --- a/lib/libpthread/thread/thr_join.c +++ b/lib/libpthread/thread/thr_join.c @@ -45,19 +45,19 @@ _pthread_join(pthread_t pthread, void **thread_return) kse_critical_t crit; int ret = 0; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); /* Check if the caller has specified an invalid thread: */ if (pthread == NULL || pthread->magic != THR_MAGIC) { /* Invalid thread: */ - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (EINVAL); } /* Check if the caller has specified itself: */ if (pthread == curthread) { /* Avoid a deadlock condition: */ - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (EDEADLK); } @@ -67,7 +67,7 @@ _pthread_join(pthread_t pthread, void **thread_return) */ if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/1)) != 0) { /* Return an error: */ - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ESRCH); } @@ -155,7 +155,7 @@ _pthread_join(pthread_t pthread, void **thread_return) *thread_return = curthread->join_status.ret; } } - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); /* Return the completion status: */ return (ret); diff --git a/lib/libpthread/thread/thr_kern.c b/lib/libpthread/thread/thr_kern.c index 7fd8b38fe0a8..a5d068bf3c64 100644 --- a/lib/libpthread/thread/thr_kern.c +++ b/lib/libpthread/thread/thr_kern.c @@ -389,12 +389,6 @@ _kse_init(void) } } -int -_kse_isthreaded(void) -{ - return (__isthreaded != 0); -} - /* * This is called when the first thread (other than the initial * thread) is created. @@ -636,7 +630,7 @@ _thr_sched_switch_unlocked(struct pthread *curthread) if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) kse_sched_single(&curkse->k_kcb->kcb_kmbx); else { - curkse->k_switch = 1; + KSE_SET_SWITCH(curkse); _thread_enter_uts(curthread->tcb, curkse->k_kcb); } @@ -696,7 +690,7 @@ kse_sched_single(struct kse_mailbox *kmbx) curkse = (struct kse *)kmbx->km_udata; curthread = curkse->k_curthread; - if ((curkse->k_flags & KF_INITIALIZED) == 0) { + if (__predict_false((curkse->k_flags & KF_INITIALIZED) == 0)) { /* Setup this KSEs specific data. */ _kcb_set(curkse->k_kcb); _tcb_set(curkse->k_kcb, curthread->tcb); @@ -914,7 +908,7 @@ kse_sched_multi(struct kse_mailbox *kmbx) "Mailbox not null in kse_sched_multi"); /* Check for first time initialization: */ - if ((curkse->k_flags & KF_INITIALIZED) == 0) { + if (__predict_false((curkse->k_flags & KF_INITIALIZED) == 0)) { /* Setup this KSEs specific data. */ _kcb_set(curkse->k_kcb); @@ -929,9 +923,15 @@ kse_sched_multi(struct kse_mailbox *kmbx) _tcb_set(curkse->k_kcb, NULL); /* If this is an upcall; take the scheduler lock. */ - if (curkse->k_switch == 0) + if (!KSE_IS_SWITCH(curkse)) KSE_SCHED_LOCK(curkse, curkse->k_kseg); - curkse->k_switch = 0; + else + KSE_CLEAR_SWITCH(curkse); + + if (KSE_IS_IDLE(curkse)) { + KSE_CLEAR_IDLE(curkse); + curkse->k_kseg->kg_idle_kses--; + } /* * Now that the scheduler lock is held, get the current @@ -941,10 +941,6 @@ kse_sched_multi(struct kse_mailbox *kmbx) */ curthread = curkse->k_curthread; - if (KSE_IS_IDLE(curkse)) { - KSE_CLEAR_IDLE(curkse); - curkse->k_kseg->kg_idle_kses--; - } /* * If the current thread was completed in another KSE, then * it will be in the run queue. Don't mark it as being blocked. @@ -2295,11 +2291,8 @@ kse_reinit(struct kse *kse, int sys_scope) kse->k_schedq = 0; kse->k_locklevel = 0; kse->k_flags = 0; - kse->k_idle = 0; kse->k_error = 0; kse->k_cpu = 0; - kse->k_done = 0; - kse->k_switch = 0; kse->k_sigseqno = 0; } diff --git a/lib/libpthread/thread/thr_msync.c b/lib/libpthread/thread/thr_msync.c index 24b78ecbacdf..c2e34335dc4a 100644 --- a/lib/libpthread/thread/thr_msync.c +++ b/lib/libpthread/thread/thr_msync.c @@ -25,9 +25,9 @@ __msync(void *addr, size_t len, int flags) * write. The only real use of this wrapper is to guarantee * a cancellation point, as per the standard. sigh. */ - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_msync(addr, len, flags); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libpthread/thread/thr_nanosleep.c b/lib/libpthread/thread/thr_nanosleep.c index 57bbef9e37fc..e8baa844a1d0 100644 --- a/lib/libpthread/thread/thr_nanosleep.c +++ b/lib/libpthread/thread/thr_nanosleep.c @@ -121,9 +121,9 @@ __nanosleep(const struct timespec *time_to_sleep, struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = _nanosleep(time_to_sleep, time_remaining); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libpthread/thread/thr_open.c b/lib/libpthread/thread/thr_open.c index ec60ba4e723a..8ac625d8a30f 100644 --- a/lib/libpthread/thread/thr_open.c +++ b/lib/libpthread/thread/thr_open.c @@ -50,7 +50,7 @@ __open(const char *path, int flags,...) int mode = 0; va_list ap; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); /* Check if the file is being created: */ if (flags & O_CREAT) { @@ -61,7 +61,11 @@ __open(const char *path, int flags,...) } ret = __sys_open(path, flags, mode); - _thr_leave_cancellation_point(curthread); + /* + * To avoid possible file handle leak, + * only check cancellation point if it is failure + */ + _thr_cancel_leave(curthread, (ret == -1)); return ret; } diff --git a/lib/libpthread/thread/thr_pause.c b/lib/libpthread/thread/thr_pause.c index aa97c77823fe..391b5a0b55bb 100644 --- a/lib/libpthread/thread/thr_pause.c +++ b/lib/libpthread/thread/thr_pause.c @@ -43,9 +43,9 @@ _pause(void) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __pause(); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libpthread/thread/thr_poll.c b/lib/libpthread/thread/thr_poll.c index 0b78047838e0..1b165989b4f3 100644 --- a/lib/libpthread/thread/thr_poll.c +++ b/lib/libpthread/thread/thr_poll.c @@ -49,9 +49,9 @@ __poll(struct pollfd *fds, unsigned int nfds, int timeout) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_poll(fds, nfds, timeout); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libpthread/thread/thr_private.h b/lib/libpthread/thread/thr_private.h index fc5f97e7c97a..8c344ec85e23 100644 --- a/lib/libpthread/thread/thr_private.h +++ b/lib/libpthread/thread/thr_private.h @@ -81,12 +81,14 @@ #define DBG_MUTEX 0x0001 #define DBG_SIG 0x0002 - +#ifdef _PTHREADS_INVARIANTS #define THR_ASSERT(cond, msg) do { \ if (!(cond)) \ PANIC(msg); \ } while (0) - +#else +#define THR_ASSERT(cond, msg) +#endif /* * State change macro without scheduling queue change: @@ -192,15 +194,21 @@ struct kse { int k_flags; #define KF_STARTED 0x0001 /* kernel kse created */ #define KF_INITIALIZED 0x0002 /* initialized on 1st upcall */ -#define KF_TERMINATED 0x0004 - int k_idle; /* kse is idle */ +#define KF_TERMINATED 0x0004 /* kse is terminated */ +#define KF_IDLE 0x0008 /* kse is idle */ +#define KF_SWITCH 0x0010 /* thread switch in UTS */ int k_error; /* syscall errno in critical */ int k_cpu; /* CPU ID when bound */ - int k_done; /* this KSE is done */ - int k_switch; /* thread switch in UTS */ int k_sigseqno; /* signal buffered count */ }; +#define KSE_SET_IDLE(kse) ((kse)->k_flags |= KF_IDLE) +#define KSE_CLEAR_IDLE(kse) ((kse)->k_flags &= ~KF_IDLE) +#define KSE_IS_IDLE(kse) (((kse)->k_flags & KF_IDLE) != 0) +#define KSE_SET_SWITCH(kse) ((kse)->k_flags |= KF_SWITCH) +#define KSE_CLEAR_SWITCH(kse) ((kse)->k_flags &= ~KF_SWITCH) +#define KSE_IS_SWITCH(kse) (((kse)->k_flags & KF_SWITCH) != 0) + /* * Each KSE group contains one or more KSEs in which threads can run. * At least for now, there is one scheduling queue per KSE group; KSEs @@ -293,10 +301,6 @@ do { \ #define KSE_WAKEUP(kse) kse_wakeup(&(kse)->k_kcb->kcb_kmbx) -#define KSE_SET_IDLE(kse) ((kse)->k_idle = 1) -#define KSE_CLEAR_IDLE(kse) ((kse)->k_idle = 0) -#define KSE_IS_IDLE(kse) ((kse)->k_idle != 0) - /* * TailQ initialization values. */ @@ -659,7 +663,6 @@ struct pthread { int active; /* thread running */ int blocked; /* thread blocked in kernel */ int need_switchout; - int need_wakeup; /* * Used for tracking delivery of signal handlers. @@ -984,7 +987,15 @@ do { \ (((thrd)->state == PS_SUSPENDED) || \ (((thrd)->flags & THR_FLAGS_SUSPENDED) != 0)) #define THR_IS_EXITING(thrd) (((thrd)->flags & THR_FLAGS_EXITING) != 0) - + +extern int __isthreaded; + +static inline int +_kse_isthreaded(void) +{ + return (__isthreaded != 0); +} + /* * Global variables for the pthread kernel. */ @@ -1149,8 +1160,8 @@ void _thr_sig_rundown(struct pthread *, ucontext_t *, void _thr_sig_send(struct pthread *pthread, int sig); void _thr_sigframe_restore(struct pthread *thread, struct pthread_sigframe *psf); void _thr_spinlock_init(void); -void _thr_enter_cancellation_point(struct pthread *); -void _thr_leave_cancellation_point(struct pthread *); +void _thr_cancel_enter(struct pthread *); +void _thr_cancel_leave(struct pthread *, int); int _thr_setconcurrency(int new_level); int _thr_setmaxconcurrency(void); void _thr_critical_enter(struct pthread *); diff --git a/lib/libpthread/thread/thr_pselect.c b/lib/libpthread/thread/thr_pselect.c index c1a4c5ddba0f..ce7a530dc4f4 100644 --- a/lib/libpthread/thread/thr_pselect.c +++ b/lib/libpthread/thread/thr_pselect.c @@ -49,9 +49,9 @@ _pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __pselect(count, rfds, wfds, efds, timo, mask); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libpthread/thread/thr_read.c b/lib/libpthread/thread/thr_read.c index 34dabd35ac4f..c0391c55411a 100644 --- a/lib/libpthread/thread/thr_read.c +++ b/lib/libpthread/thread/thr_read.c @@ -48,9 +48,9 @@ __read(int fd, void *buf, size_t nbytes) struct pthread *curthread = _get_curthread(); ssize_t ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_read(fd, buf, nbytes); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libpthread/thread/thr_readv.c b/lib/libpthread/thread/thr_readv.c index 3a8823f90657..eb0e54aa0454 100644 --- a/lib/libpthread/thread/thr_readv.c +++ b/lib/libpthread/thread/thr_readv.c @@ -48,9 +48,9 @@ __readv(int fd, const struct iovec *iov, int iovcnt) struct pthread *curthread = _get_curthread(); ssize_t ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_readv(fd, iov, iovcnt); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libpthread/thread/thr_select.c b/lib/libpthread/thread/thr_select.c index 25be6a95be6e..792ff09eb189 100644 --- a/lib/libpthread/thread/thr_select.c +++ b/lib/libpthread/thread/thr_select.c @@ -57,9 +57,9 @@ __select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, TIMEVAL_TO_TIMESPEC(timeout, &ts); return nanosleep(&ts, NULL); } else { - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); } return ret; } diff --git a/lib/libpthread/thread/thr_sem.c b/lib/libpthread/thread/thr_sem.c index d6021a8ac3a2..c7f6308c50c4 100644 --- a/lib/libpthread/thread/thr_sem.c +++ b/lib/libpthread/thread/thr_sem.c @@ -169,7 +169,7 @@ _sem_wait(sem_t *sem) struct pthread *curthread = _get_curthread(); int retval; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); _SEM_CHECK_VALIDITY(sem); @@ -186,7 +186,7 @@ _sem_wait(sem_t *sem) retval = 0; RETURN: - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (retval); } diff --git a/lib/libpthread/thread/thr_sigsuspend.c b/lib/libpthread/thread/thr_sigsuspend.c index 4d3aa4ec2580..cad57451b406 100644 --- a/lib/libpthread/thread/thr_sigsuspend.c +++ b/lib/libpthread/thread/thr_sigsuspend.c @@ -95,9 +95,9 @@ __sigsuspend(const sigset_t * set) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = _sigsuspend(set); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libpthread/thread/thr_sigwait.c b/lib/libpthread/thread/thr_sigwait.c index 43f932172ffe..76f53686098e 100644 --- a/lib/libpthread/thread/thr_sigwait.c +++ b/lib/libpthread/thread/thr_sigwait.c @@ -137,9 +137,9 @@ __sigtimedwait(const sigset_t *set, siginfo_t *info, struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = lib_sigtimedwait(set, info, timeout); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } @@ -155,9 +155,9 @@ __sigwaitinfo(const sigset_t *set, siginfo_t *info) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = lib_sigtimedwait(set, info, NULL); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } @@ -173,7 +173,7 @@ __sigwait(const sigset_t *set, int *sig) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = lib_sigtimedwait(set, NULL, NULL); if (ret > 0) { *sig = ret; @@ -181,7 +181,7 @@ __sigwait(const sigset_t *set, int *sig) } else ret = -1; - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libpthread/thread/thr_sleep.c b/lib/libpthread/thread/thr_sleep.c index b494e5bcdea5..7547e60674a1 100644 --- a/lib/libpthread/thread/thr_sleep.c +++ b/lib/libpthread/thread/thr_sleep.c @@ -43,9 +43,9 @@ _sleep(unsigned int seconds) struct pthread *curthread = _get_curthread(); unsigned int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sleep(seconds); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libpthread/thread/thr_system.c b/lib/libpthread/thread/thr_system.c index ae26c9cad0d8..57c219977714 100644 --- a/lib/libpthread/thread/thr_system.c +++ b/lib/libpthread/thread/thr_system.c @@ -43,9 +43,9 @@ _system(const char *string) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __system(string); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libpthread/thread/thr_tcdrain.c b/lib/libpthread/thread/thr_tcdrain.c index 86af9c2dcaa8..d0d701b0f360 100644 --- a/lib/libpthread/thread/thr_tcdrain.c +++ b/lib/libpthread/thread/thr_tcdrain.c @@ -43,9 +43,9 @@ _tcdrain(int fd) struct pthread *curthread = _get_curthread(); int ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __tcdrain(fd); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return (ret); } diff --git a/lib/libpthread/thread/thr_wait.c b/lib/libpthread/thread/thr_wait.c index b0a3af4b55b0..689f6833dce7 100644 --- a/lib/libpthread/thread/thr_wait.c +++ b/lib/libpthread/thread/thr_wait.c @@ -42,9 +42,9 @@ _wait(int *istat) struct pthread *curthread = _get_curthread(); pid_t ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __wait(istat); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libpthread/thread/thr_wait4.c b/lib/libpthread/thread/thr_wait4.c index 07ff79df1825..12a10670dcfd 100644 --- a/lib/libpthread/thread/thr_wait4.c +++ b/lib/libpthread/thread/thr_wait4.c @@ -49,9 +49,9 @@ __wait4(pid_t pid, int *istat, int options, struct rusage *rusage) struct pthread *curthread = _get_curthread(); pid_t ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = _wait4(pid, istat, options, rusage); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libpthread/thread/thr_waitpid.c b/lib/libpthread/thread/thr_waitpid.c index e09bbd58db42..4edef3bfdb81 100644 --- a/lib/libpthread/thread/thr_waitpid.c +++ b/lib/libpthread/thread/thr_waitpid.c @@ -44,9 +44,9 @@ _waitpid(pid_t wpid, int *status, int options) struct pthread *curthread = _get_curthread(); pid_t ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __waitpid(wpid, status, options); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libpthread/thread/thr_write.c b/lib/libpthread/thread/thr_write.c index 53d897ced1e9..39d221c363d0 100644 --- a/lib/libpthread/thread/thr_write.c +++ b/lib/libpthread/thread/thr_write.c @@ -48,9 +48,9 @@ __write(int fd, const void *buf, size_t nbytes) struct pthread *curthread = _get_curthread(); ssize_t ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_write(fd, buf, nbytes); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } diff --git a/lib/libpthread/thread/thr_writev.c b/lib/libpthread/thread/thr_writev.c index e13c9d2f2960..81499d708f39 100644 --- a/lib/libpthread/thread/thr_writev.c +++ b/lib/libpthread/thread/thr_writev.c @@ -50,9 +50,9 @@ __writev(int fd, const struct iovec *iov, int iovcnt) struct pthread *curthread = _get_curthread(); ssize_t ret; - _thr_enter_cancellation_point(curthread); + _thr_cancel_enter(curthread); ret = __sys_writev(fd, iov, iovcnt); - _thr_leave_cancellation_point(curthread); + _thr_cancel_leave(curthread, 1); return ret; } |