summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Xu <davidxu@FreeBSD.org>2003-12-09 02:20:56 +0000
committerDavid Xu <davidxu@FreeBSD.org>2003-12-09 02:20:56 +0000
commit71679e629d6933bda40564da2a54894aed1358f3 (patch)
tree336614966b1df2677098ac89ea3a03fc82f7141b /lib
parentef7af95abd4c13eb0c2cd6961ee08594bfcb7513 (diff)
downloadsrc-test2-71679e629d6933bda40564da2a54894aed1358f3.tar.gz
src-test2-71679e629d6933bda40564da2a54894aed1358f3.zip
Notes
Diffstat (limited to 'lib')
-rw-r--r--lib/libkse/thread/thr_aio_suspend.c4
-rw-r--r--lib/libkse/thread/thr_cancel.c73
-rw-r--r--lib/libkse/thread/thr_close.c4
-rw-r--r--lib/libkse/thread/thr_cond.c8
-rw-r--r--lib/libkse/thread/thr_creat.c8
-rw-r--r--lib/libkse/thread/thr_fcntl.c13
-rw-r--r--lib/libkse/thread/thr_fsync.c4
-rw-r--r--lib/libkse/thread/thr_join.c10
-rw-r--r--lib/libkse/thread/thr_kern.c29
-rw-r--r--lib/libkse/thread/thr_msync.c4
-rw-r--r--lib/libkse/thread/thr_nanosleep.c4
-rw-r--r--lib/libkse/thread/thr_open.c8
-rw-r--r--lib/libkse/thread/thr_pause.c4
-rw-r--r--lib/libkse/thread/thr_poll.c4
-rw-r--r--lib/libkse/thread/thr_private.h39
-rw-r--r--lib/libkse/thread/thr_pselect.c4
-rw-r--r--lib/libkse/thread/thr_read.c4
-rw-r--r--lib/libkse/thread/thr_readv.c4
-rw-r--r--lib/libkse/thread/thr_select.c4
-rw-r--r--lib/libkse/thread/thr_sem.c4
-rw-r--r--lib/libkse/thread/thr_sigsuspend.c4
-rw-r--r--lib/libkse/thread/thr_sigwait.c12
-rw-r--r--lib/libkse/thread/thr_sleep.c4
-rw-r--r--lib/libkse/thread/thr_system.c4
-rw-r--r--lib/libkse/thread/thr_tcdrain.c4
-rw-r--r--lib/libkse/thread/thr_wait.c4
-rw-r--r--lib/libkse/thread/thr_wait4.c4
-rw-r--r--lib/libkse/thread/thr_waitpid.c4
-rw-r--r--lib/libkse/thread/thr_write.c4
-rw-r--r--lib/libkse/thread/thr_writev.c4
-rw-r--r--lib/libpthread/thread/thr_aio_suspend.c4
-rw-r--r--lib/libpthread/thread/thr_cancel.c73
-rw-r--r--lib/libpthread/thread/thr_close.c4
-rw-r--r--lib/libpthread/thread/thr_cond.c8
-rw-r--r--lib/libpthread/thread/thr_creat.c8
-rw-r--r--lib/libpthread/thread/thr_fcntl.c13
-rw-r--r--lib/libpthread/thread/thr_fsync.c4
-rw-r--r--lib/libpthread/thread/thr_join.c10
-rw-r--r--lib/libpthread/thread/thr_kern.c29
-rw-r--r--lib/libpthread/thread/thr_msync.c4
-rw-r--r--lib/libpthread/thread/thr_nanosleep.c4
-rw-r--r--lib/libpthread/thread/thr_open.c8
-rw-r--r--lib/libpthread/thread/thr_pause.c4
-rw-r--r--lib/libpthread/thread/thr_poll.c4
-rw-r--r--lib/libpthread/thread/thr_private.h39
-rw-r--r--lib/libpthread/thread/thr_pselect.c4
-rw-r--r--lib/libpthread/thread/thr_read.c4
-rw-r--r--lib/libpthread/thread/thr_readv.c4
-rw-r--r--lib/libpthread/thread/thr_select.c4
-rw-r--r--lib/libpthread/thread/thr_sem.c4
-rw-r--r--lib/libpthread/thread/thr_sigsuspend.c4
-rw-r--r--lib/libpthread/thread/thr_sigwait.c12
-rw-r--r--lib/libpthread/thread/thr_sleep.c4
-rw-r--r--lib/libpthread/thread/thr_system.c4
-rw-r--r--lib/libpthread/thread/thr_tcdrain.c4
-rw-r--r--lib/libpthread/thread/thr_wait.c4
-rw-r--r--lib/libpthread/thread/thr_wait4.c4
-rw-r--r--lib/libpthread/thread/thr_waitpid.c4
-rw-r--r--lib/libpthread/thread/thr_write.c4
-rw-r--r--lib/libpthread/thread/thr_writev.c4
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;
}