Rename _thr_enter_cancellation_point to _thr_cancel_enter, rename
_thr_leave_cancellation_point to _thr_cancel_leave, add a parameter to _thr_cancel_leave to indicate whether cancellation point should be checked, this gives us an option to not check cancallation point if a syscall successfully returns to avoid any leaks, current I have creat(), open() and fcntl(F_DUPFD) to not check cancellation point after they sucessfully returned. Replace some members in structure kse with bit flags to same some memory. Conditionally compile THR_ASSERT to nothing if _PTHREAD_INVARIANTS is not defined. Inline some small functions in thr_cancel.c. Use __predict_false in thr_kern.c for some executed only once code. Reviewd by: deischen
This commit is contained in:
parent
ef7af95abd
commit
71679e629d
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user