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();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_aio_suspend(iocbs, niocb, timeout);
|
ret = __sys_aio_suspend(iocbs, niocb, timeout);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,35 @@ __weak_reference(_pthread_setcancelstate, pthread_setcancelstate);
|
|||||||
__weak_reference(_pthread_setcanceltype, pthread_setcanceltype);
|
__weak_reference(_pthread_setcanceltype, pthread_setcanceltype);
|
||||||
__weak_reference(_pthread_testcancel, pthread_testcancel);
|
__weak_reference(_pthread_testcancel, pthread_testcancel);
|
||||||
|
|
||||||
static int checkcancel(struct pthread *curthread);
|
static inline int
|
||||||
static void testcancel(struct pthread *curthread);
|
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
|
int
|
||||||
_pthread_cancel(pthread_t pthread)
|
_pthread_cancel(pthread_t pthread)
|
||||||
@ -217,37 +244,6 @@ _pthread_setcanceltype(int type, int *oldtype)
|
|||||||
return (ret);
|
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
|
void
|
||||||
_pthread_testcancel(void)
|
_pthread_testcancel(void)
|
||||||
{
|
{
|
||||||
@ -259,10 +255,8 @@ _pthread_testcancel(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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: */
|
/* Look for a cancellation before we block: */
|
||||||
THR_THREAD_LOCK(thread, thread);
|
THR_THREAD_LOCK(thread, thread);
|
||||||
testcancel(thread);
|
testcancel(thread);
|
||||||
@ -271,14 +265,13 @@ _thr_enter_cancellation_point(struct pthread *thread)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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);
|
THR_THREAD_LOCK(thread, thread);
|
||||||
thread->cancelflags &= ~THR_AT_CANCEL_POINT;
|
thread->cancelflags &= ~THR_AT_CANCEL_POINT;
|
||||||
/* Look for a cancellation after we unblock: */
|
/* Look for a cancellation after we unblock: */
|
||||||
testcancel(thread);
|
if (check)
|
||||||
|
testcancel(thread);
|
||||||
THR_THREAD_UNLOCK(thread, thread);
|
THR_THREAD_UNLOCK(thread, thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,9 +47,9 @@ __close(int fd)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_close(fd);
|
ret = __sys_close(fd);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -365,9 +365,9 @@ __pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = _pthread_cond_wait(cond, mutex);
|
ret = _pthread_cond_wait(cond, mutex);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,9 +571,9 @@ __pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = _pthread_cond_timedwait(cond, mutex, abstime);
|
ret = _pthread_cond_timedwait(cond, mutex, abstime);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,9 +43,13 @@ ___creat(const char *path, mode_t mode)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __creat(path, mode);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -44,14 +44,21 @@ int
|
|||||||
__fcntl(int fd, int cmd,...)
|
__fcntl(int fd, int cmd,...)
|
||||||
{
|
{
|
||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret, check = 1;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
|
|
||||||
va_start(ap, cmd);
|
va_start(ap, cmd);
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case F_DUPFD:
|
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_SETFD:
|
||||||
case F_SETFL:
|
case F_SETFL:
|
||||||
ret = __sys_fcntl(fd, cmd, va_arg(ap, int));
|
ret = __sys_fcntl(fd, cmd, va_arg(ap, int));
|
||||||
@ -65,7 +72,7 @@ __fcntl(int fd, int cmd,...)
|
|||||||
}
|
}
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, check);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,9 @@ __fsync(int fd)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_fsync(fd);
|
ret = __sys_fsync(fd);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -45,19 +45,19 @@ _pthread_join(pthread_t pthread, void **thread_return)
|
|||||||
kse_critical_t crit;
|
kse_critical_t crit;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
|
|
||||||
/* Check if the caller has specified an invalid thread: */
|
/* Check if the caller has specified an invalid thread: */
|
||||||
if (pthread == NULL || pthread->magic != THR_MAGIC) {
|
if (pthread == NULL || pthread->magic != THR_MAGIC) {
|
||||||
/* Invalid thread: */
|
/* Invalid thread: */
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the caller has specified itself: */
|
/* Check if the caller has specified itself: */
|
||||||
if (pthread == curthread) {
|
if (pthread == curthread) {
|
||||||
/* Avoid a deadlock condition: */
|
/* Avoid a deadlock condition: */
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
return (EDEADLK);
|
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) {
|
if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/1)) != 0) {
|
||||||
/* Return an error: */
|
/* Return an error: */
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
return (ESRCH);
|
return (ESRCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ _pthread_join(pthread_t pthread, void **thread_return)
|
|||||||
*thread_return = curthread->join_status.ret;
|
*thread_return = curthread->join_status.ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
/* Return the completion status: */
|
/* Return the completion status: */
|
||||||
return (ret);
|
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
|
* This is called when the first thread (other than the initial
|
||||||
* thread) is created.
|
* thread) is created.
|
||||||
@ -636,7 +630,7 @@ _thr_sched_switch_unlocked(struct pthread *curthread)
|
|||||||
if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM)
|
if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM)
|
||||||
kse_sched_single(&curkse->k_kcb->kcb_kmbx);
|
kse_sched_single(&curkse->k_kcb->kcb_kmbx);
|
||||||
else {
|
else {
|
||||||
curkse->k_switch = 1;
|
KSE_SET_SWITCH(curkse);
|
||||||
_thread_enter_uts(curthread->tcb, curkse->k_kcb);
|
_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;
|
curkse = (struct kse *)kmbx->km_udata;
|
||||||
curthread = curkse->k_curthread;
|
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. */
|
/* Setup this KSEs specific data. */
|
||||||
_kcb_set(curkse->k_kcb);
|
_kcb_set(curkse->k_kcb);
|
||||||
_tcb_set(curkse->k_kcb, curthread->tcb);
|
_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");
|
"Mailbox not null in kse_sched_multi");
|
||||||
|
|
||||||
/* Check for first time initialization: */
|
/* 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. */
|
/* Setup this KSEs specific data. */
|
||||||
_kcb_set(curkse->k_kcb);
|
_kcb_set(curkse->k_kcb);
|
||||||
|
|
||||||
@ -929,9 +923,15 @@ kse_sched_multi(struct kse_mailbox *kmbx)
|
|||||||
_tcb_set(curkse->k_kcb, NULL);
|
_tcb_set(curkse->k_kcb, NULL);
|
||||||
|
|
||||||
/* If this is an upcall; take the scheduler lock. */
|
/* 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);
|
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
|
* 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;
|
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
|
* If the current thread was completed in another KSE, then
|
||||||
* it will be in the run queue. Don't mark it as being blocked.
|
* 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_schedq = 0;
|
||||||
kse->k_locklevel = 0;
|
kse->k_locklevel = 0;
|
||||||
kse->k_flags = 0;
|
kse->k_flags = 0;
|
||||||
kse->k_idle = 0;
|
|
||||||
kse->k_error = 0;
|
kse->k_error = 0;
|
||||||
kse->k_cpu = 0;
|
kse->k_cpu = 0;
|
||||||
kse->k_done = 0;
|
|
||||||
kse->k_switch = 0;
|
|
||||||
kse->k_sigseqno = 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
|
* write. The only real use of this wrapper is to guarantee
|
||||||
* a cancellation point, as per the standard. sigh.
|
* a cancellation point, as per the standard. sigh.
|
||||||
*/
|
*/
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_msync(addr, len, flags);
|
ret = __sys_msync(addr, len, flags);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -121,9 +121,9 @@ __nanosleep(const struct timespec *time_to_sleep,
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = _nanosleep(time_to_sleep, time_remaining);
|
ret = _nanosleep(time_to_sleep, time_remaining);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ __open(const char *path, int flags,...)
|
|||||||
int mode = 0;
|
int mode = 0;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
|
|
||||||
/* Check if the file is being created: */
|
/* Check if the file is being created: */
|
||||||
if (flags & O_CREAT) {
|
if (flags & O_CREAT) {
|
||||||
@ -61,7 +61,11 @@ __open(const char *path, int flags,...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = __sys_open(path, flags, mode);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,9 @@ _pause(void)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __pause();
|
ret = __pause();
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -49,9 +49,9 @@ __poll(struct pollfd *fds, unsigned int nfds, int timeout)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_poll(fds, nfds, timeout);
|
ret = __sys_poll(fds, nfds, timeout);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -81,12 +81,14 @@
|
|||||||
#define DBG_MUTEX 0x0001
|
#define DBG_MUTEX 0x0001
|
||||||
#define DBG_SIG 0x0002
|
#define DBG_SIG 0x0002
|
||||||
|
|
||||||
|
#ifdef _PTHREADS_INVARIANTS
|
||||||
#define THR_ASSERT(cond, msg) do { \
|
#define THR_ASSERT(cond, msg) do { \
|
||||||
if (!(cond)) \
|
if (!(cond)) \
|
||||||
PANIC(msg); \
|
PANIC(msg); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
#else
|
||||||
|
#define THR_ASSERT(cond, msg)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* State change macro without scheduling queue change:
|
* State change macro without scheduling queue change:
|
||||||
@ -192,15 +194,21 @@ struct kse {
|
|||||||
int k_flags;
|
int k_flags;
|
||||||
#define KF_STARTED 0x0001 /* kernel kse created */
|
#define KF_STARTED 0x0001 /* kernel kse created */
|
||||||
#define KF_INITIALIZED 0x0002 /* initialized on 1st upcall */
|
#define KF_INITIALIZED 0x0002 /* initialized on 1st upcall */
|
||||||
#define KF_TERMINATED 0x0004
|
#define KF_TERMINATED 0x0004 /* kse is terminated */
|
||||||
int k_idle; /* kse is idle */
|
#define KF_IDLE 0x0008 /* kse is idle */
|
||||||
|
#define KF_SWITCH 0x0010 /* thread switch in UTS */
|
||||||
int k_error; /* syscall errno in critical */
|
int k_error; /* syscall errno in critical */
|
||||||
int k_cpu; /* CPU ID when bound */
|
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 */
|
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.
|
* 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
|
* 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_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.
|
* TailQ initialization values.
|
||||||
*/
|
*/
|
||||||
@ -659,7 +663,6 @@ struct pthread {
|
|||||||
int active; /* thread running */
|
int active; /* thread running */
|
||||||
int blocked; /* thread blocked in kernel */
|
int blocked; /* thread blocked in kernel */
|
||||||
int need_switchout;
|
int need_switchout;
|
||||||
int need_wakeup;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used for tracking delivery of signal handlers.
|
* Used for tracking delivery of signal handlers.
|
||||||
@ -985,6 +988,14 @@ do { \
|
|||||||
(((thrd)->flags & THR_FLAGS_SUSPENDED) != 0))
|
(((thrd)->flags & THR_FLAGS_SUSPENDED) != 0))
|
||||||
#define THR_IS_EXITING(thrd) (((thrd)->flags & THR_FLAGS_EXITING) != 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.
|
* 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_sig_send(struct pthread *pthread, int sig);
|
||||||
void _thr_sigframe_restore(struct pthread *thread, struct pthread_sigframe *psf);
|
void _thr_sigframe_restore(struct pthread *thread, struct pthread_sigframe *psf);
|
||||||
void _thr_spinlock_init(void);
|
void _thr_spinlock_init(void);
|
||||||
void _thr_enter_cancellation_point(struct pthread *);
|
void _thr_cancel_enter(struct pthread *);
|
||||||
void _thr_leave_cancellation_point(struct pthread *);
|
void _thr_cancel_leave(struct pthread *, int);
|
||||||
int _thr_setconcurrency(int new_level);
|
int _thr_setconcurrency(int new_level);
|
||||||
int _thr_setmaxconcurrency(void);
|
int _thr_setmaxconcurrency(void);
|
||||||
void _thr_critical_enter(struct pthread *);
|
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();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __pselect(count, rfds, wfds, efds, timo, mask);
|
ret = __pselect(count, rfds, wfds, efds, timo, mask);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -48,9 +48,9 @@ __read(int fd, void *buf, size_t nbytes)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_read(fd, buf, nbytes);
|
ret = __sys_read(fd, buf, nbytes);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -48,9 +48,9 @@ __readv(int fd, const struct iovec *iov, int iovcnt)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_readv(fd, iov, iovcnt);
|
ret = __sys_readv(fd, iov, iovcnt);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -57,9 +57,9 @@ __select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
|||||||
TIMEVAL_TO_TIMESPEC(timeout, &ts);
|
TIMEVAL_TO_TIMESPEC(timeout, &ts);
|
||||||
return nanosleep(&ts, NULL);
|
return nanosleep(&ts, NULL);
|
||||||
} else {
|
} else {
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout);
|
ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ _sem_wait(sem_t *sem)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
|
|
||||||
_SEM_CHECK_VALIDITY(sem);
|
_SEM_CHECK_VALIDITY(sem);
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ _sem_wait(sem_t *sem)
|
|||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
RETURN:
|
RETURN:
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
return (retval);
|
return (retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,9 +95,9 @@ __sigsuspend(const sigset_t * set)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = _sigsuspend(set);
|
ret = _sigsuspend(set);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -137,9 +137,9 @@ __sigtimedwait(const sigset_t *set, siginfo_t *info,
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = lib_sigtimedwait(set, info, timeout);
|
ret = lib_sigtimedwait(set, info, timeout);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,9 +155,9 @@ __sigwaitinfo(const sigset_t *set, siginfo_t *info)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = lib_sigtimedwait(set, info, NULL);
|
ret = lib_sigtimedwait(set, info, NULL);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ __sigwait(const sigset_t *set, int *sig)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = lib_sigtimedwait(set, NULL, NULL);
|
ret = lib_sigtimedwait(set, NULL, NULL);
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
*sig = ret;
|
*sig = ret;
|
||||||
@ -181,7 +181,7 @@ __sigwait(const sigset_t *set, int *sig)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
ret = -1;
|
ret = -1;
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,9 +43,9 @@ _sleep(unsigned int seconds)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
unsigned int ret;
|
unsigned int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sleep(seconds);
|
ret = __sleep(seconds);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,9 @@ _system(const char *string)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __system(string);
|
ret = __system(string);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,9 @@ _tcdrain(int fd)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __tcdrain(fd);
|
ret = __tcdrain(fd);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -42,9 +42,9 @@ _wait(int *istat)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
pid_t ret;
|
pid_t ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __wait(istat);
|
ret = __wait(istat);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -49,9 +49,9 @@ __wait4(pid_t pid, int *istat, int options, struct rusage *rusage)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
pid_t ret;
|
pid_t ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = _wait4(pid, istat, options, rusage);
|
ret = _wait4(pid, istat, options, rusage);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -44,9 +44,9 @@ _waitpid(pid_t wpid, int *status, int options)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
pid_t ret;
|
pid_t ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __waitpid(wpid, status, options);
|
ret = __waitpid(wpid, status, options);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -48,9 +48,9 @@ __write(int fd, const void *buf, size_t nbytes)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_write(fd, buf, nbytes);
|
ret = __sys_write(fd, buf, nbytes);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -50,9 +50,9 @@ __writev(int fd, const struct iovec *iov, int iovcnt)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_writev(fd, iov, iovcnt);
|
ret = __sys_writev(fd, iov, iovcnt);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -42,9 +42,9 @@ _aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_aio_suspend(iocbs, niocb, timeout);
|
ret = __sys_aio_suspend(iocbs, niocb, timeout);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,35 @@ __weak_reference(_pthread_setcancelstate, pthread_setcancelstate);
|
|||||||
__weak_reference(_pthread_setcanceltype, pthread_setcanceltype);
|
__weak_reference(_pthread_setcanceltype, pthread_setcanceltype);
|
||||||
__weak_reference(_pthread_testcancel, pthread_testcancel);
|
__weak_reference(_pthread_testcancel, pthread_testcancel);
|
||||||
|
|
||||||
static int checkcancel(struct pthread *curthread);
|
static inline int
|
||||||
static void testcancel(struct pthread *curthread);
|
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
|
int
|
||||||
_pthread_cancel(pthread_t pthread)
|
_pthread_cancel(pthread_t pthread)
|
||||||
@ -217,37 +244,6 @@ _pthread_setcanceltype(int type, int *oldtype)
|
|||||||
return (ret);
|
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
|
void
|
||||||
_pthread_testcancel(void)
|
_pthread_testcancel(void)
|
||||||
{
|
{
|
||||||
@ -259,10 +255,8 @@ _pthread_testcancel(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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: */
|
/* Look for a cancellation before we block: */
|
||||||
THR_THREAD_LOCK(thread, thread);
|
THR_THREAD_LOCK(thread, thread);
|
||||||
testcancel(thread);
|
testcancel(thread);
|
||||||
@ -271,14 +265,13 @@ _thr_enter_cancellation_point(struct pthread *thread)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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);
|
THR_THREAD_LOCK(thread, thread);
|
||||||
thread->cancelflags &= ~THR_AT_CANCEL_POINT;
|
thread->cancelflags &= ~THR_AT_CANCEL_POINT;
|
||||||
/* Look for a cancellation after we unblock: */
|
/* Look for a cancellation after we unblock: */
|
||||||
testcancel(thread);
|
if (check)
|
||||||
|
testcancel(thread);
|
||||||
THR_THREAD_UNLOCK(thread, thread);
|
THR_THREAD_UNLOCK(thread, thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,9 +47,9 @@ __close(int fd)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_close(fd);
|
ret = __sys_close(fd);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -365,9 +365,9 @@ __pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = _pthread_cond_wait(cond, mutex);
|
ret = _pthread_cond_wait(cond, mutex);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,9 +571,9 @@ __pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = _pthread_cond_timedwait(cond, mutex, abstime);
|
ret = _pthread_cond_timedwait(cond, mutex, abstime);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,9 +43,13 @@ ___creat(const char *path, mode_t mode)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __creat(path, mode);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -44,14 +44,21 @@ int
|
|||||||
__fcntl(int fd, int cmd,...)
|
__fcntl(int fd, int cmd,...)
|
||||||
{
|
{
|
||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret, check = 1;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
|
|
||||||
va_start(ap, cmd);
|
va_start(ap, cmd);
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case F_DUPFD:
|
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_SETFD:
|
||||||
case F_SETFL:
|
case F_SETFL:
|
||||||
ret = __sys_fcntl(fd, cmd, va_arg(ap, int));
|
ret = __sys_fcntl(fd, cmd, va_arg(ap, int));
|
||||||
@ -65,7 +72,7 @@ __fcntl(int fd, int cmd,...)
|
|||||||
}
|
}
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, check);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,9 @@ __fsync(int fd)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_fsync(fd);
|
ret = __sys_fsync(fd);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -45,19 +45,19 @@ _pthread_join(pthread_t pthread, void **thread_return)
|
|||||||
kse_critical_t crit;
|
kse_critical_t crit;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
|
|
||||||
/* Check if the caller has specified an invalid thread: */
|
/* Check if the caller has specified an invalid thread: */
|
||||||
if (pthread == NULL || pthread->magic != THR_MAGIC) {
|
if (pthread == NULL || pthread->magic != THR_MAGIC) {
|
||||||
/* Invalid thread: */
|
/* Invalid thread: */
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the caller has specified itself: */
|
/* Check if the caller has specified itself: */
|
||||||
if (pthread == curthread) {
|
if (pthread == curthread) {
|
||||||
/* Avoid a deadlock condition: */
|
/* Avoid a deadlock condition: */
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
return (EDEADLK);
|
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) {
|
if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/1)) != 0) {
|
||||||
/* Return an error: */
|
/* Return an error: */
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
return (ESRCH);
|
return (ESRCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ _pthread_join(pthread_t pthread, void **thread_return)
|
|||||||
*thread_return = curthread->join_status.ret;
|
*thread_return = curthread->join_status.ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
/* Return the completion status: */
|
/* Return the completion status: */
|
||||||
return (ret);
|
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
|
* This is called when the first thread (other than the initial
|
||||||
* thread) is created.
|
* thread) is created.
|
||||||
@ -636,7 +630,7 @@ _thr_sched_switch_unlocked(struct pthread *curthread)
|
|||||||
if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM)
|
if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM)
|
||||||
kse_sched_single(&curkse->k_kcb->kcb_kmbx);
|
kse_sched_single(&curkse->k_kcb->kcb_kmbx);
|
||||||
else {
|
else {
|
||||||
curkse->k_switch = 1;
|
KSE_SET_SWITCH(curkse);
|
||||||
_thread_enter_uts(curthread->tcb, curkse->k_kcb);
|
_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;
|
curkse = (struct kse *)kmbx->km_udata;
|
||||||
curthread = curkse->k_curthread;
|
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. */
|
/* Setup this KSEs specific data. */
|
||||||
_kcb_set(curkse->k_kcb);
|
_kcb_set(curkse->k_kcb);
|
||||||
_tcb_set(curkse->k_kcb, curthread->tcb);
|
_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");
|
"Mailbox not null in kse_sched_multi");
|
||||||
|
|
||||||
/* Check for first time initialization: */
|
/* 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. */
|
/* Setup this KSEs specific data. */
|
||||||
_kcb_set(curkse->k_kcb);
|
_kcb_set(curkse->k_kcb);
|
||||||
|
|
||||||
@ -929,9 +923,15 @@ kse_sched_multi(struct kse_mailbox *kmbx)
|
|||||||
_tcb_set(curkse->k_kcb, NULL);
|
_tcb_set(curkse->k_kcb, NULL);
|
||||||
|
|
||||||
/* If this is an upcall; take the scheduler lock. */
|
/* 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);
|
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
|
* 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;
|
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
|
* If the current thread was completed in another KSE, then
|
||||||
* it will be in the run queue. Don't mark it as being blocked.
|
* 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_schedq = 0;
|
||||||
kse->k_locklevel = 0;
|
kse->k_locklevel = 0;
|
||||||
kse->k_flags = 0;
|
kse->k_flags = 0;
|
||||||
kse->k_idle = 0;
|
|
||||||
kse->k_error = 0;
|
kse->k_error = 0;
|
||||||
kse->k_cpu = 0;
|
kse->k_cpu = 0;
|
||||||
kse->k_done = 0;
|
|
||||||
kse->k_switch = 0;
|
|
||||||
kse->k_sigseqno = 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
|
* write. The only real use of this wrapper is to guarantee
|
||||||
* a cancellation point, as per the standard. sigh.
|
* a cancellation point, as per the standard. sigh.
|
||||||
*/
|
*/
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_msync(addr, len, flags);
|
ret = __sys_msync(addr, len, flags);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -121,9 +121,9 @@ __nanosleep(const struct timespec *time_to_sleep,
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = _nanosleep(time_to_sleep, time_remaining);
|
ret = _nanosleep(time_to_sleep, time_remaining);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ __open(const char *path, int flags,...)
|
|||||||
int mode = 0;
|
int mode = 0;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
|
|
||||||
/* Check if the file is being created: */
|
/* Check if the file is being created: */
|
||||||
if (flags & O_CREAT) {
|
if (flags & O_CREAT) {
|
||||||
@ -61,7 +61,11 @@ __open(const char *path, int flags,...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = __sys_open(path, flags, mode);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,9 @@ _pause(void)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __pause();
|
ret = __pause();
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -49,9 +49,9 @@ __poll(struct pollfd *fds, unsigned int nfds, int timeout)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_poll(fds, nfds, timeout);
|
ret = __sys_poll(fds, nfds, timeout);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -81,12 +81,14 @@
|
|||||||
#define DBG_MUTEX 0x0001
|
#define DBG_MUTEX 0x0001
|
||||||
#define DBG_SIG 0x0002
|
#define DBG_SIG 0x0002
|
||||||
|
|
||||||
|
#ifdef _PTHREADS_INVARIANTS
|
||||||
#define THR_ASSERT(cond, msg) do { \
|
#define THR_ASSERT(cond, msg) do { \
|
||||||
if (!(cond)) \
|
if (!(cond)) \
|
||||||
PANIC(msg); \
|
PANIC(msg); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
#else
|
||||||
|
#define THR_ASSERT(cond, msg)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* State change macro without scheduling queue change:
|
* State change macro without scheduling queue change:
|
||||||
@ -192,15 +194,21 @@ struct kse {
|
|||||||
int k_flags;
|
int k_flags;
|
||||||
#define KF_STARTED 0x0001 /* kernel kse created */
|
#define KF_STARTED 0x0001 /* kernel kse created */
|
||||||
#define KF_INITIALIZED 0x0002 /* initialized on 1st upcall */
|
#define KF_INITIALIZED 0x0002 /* initialized on 1st upcall */
|
||||||
#define KF_TERMINATED 0x0004
|
#define KF_TERMINATED 0x0004 /* kse is terminated */
|
||||||
int k_idle; /* kse is idle */
|
#define KF_IDLE 0x0008 /* kse is idle */
|
||||||
|
#define KF_SWITCH 0x0010 /* thread switch in UTS */
|
||||||
int k_error; /* syscall errno in critical */
|
int k_error; /* syscall errno in critical */
|
||||||
int k_cpu; /* CPU ID when bound */
|
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 */
|
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.
|
* 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
|
* 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_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.
|
* TailQ initialization values.
|
||||||
*/
|
*/
|
||||||
@ -659,7 +663,6 @@ struct pthread {
|
|||||||
int active; /* thread running */
|
int active; /* thread running */
|
||||||
int blocked; /* thread blocked in kernel */
|
int blocked; /* thread blocked in kernel */
|
||||||
int need_switchout;
|
int need_switchout;
|
||||||
int need_wakeup;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used for tracking delivery of signal handlers.
|
* Used for tracking delivery of signal handlers.
|
||||||
@ -985,6 +988,14 @@ do { \
|
|||||||
(((thrd)->flags & THR_FLAGS_SUSPENDED) != 0))
|
(((thrd)->flags & THR_FLAGS_SUSPENDED) != 0))
|
||||||
#define THR_IS_EXITING(thrd) (((thrd)->flags & THR_FLAGS_EXITING) != 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.
|
* 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_sig_send(struct pthread *pthread, int sig);
|
||||||
void _thr_sigframe_restore(struct pthread *thread, struct pthread_sigframe *psf);
|
void _thr_sigframe_restore(struct pthread *thread, struct pthread_sigframe *psf);
|
||||||
void _thr_spinlock_init(void);
|
void _thr_spinlock_init(void);
|
||||||
void _thr_enter_cancellation_point(struct pthread *);
|
void _thr_cancel_enter(struct pthread *);
|
||||||
void _thr_leave_cancellation_point(struct pthread *);
|
void _thr_cancel_leave(struct pthread *, int);
|
||||||
int _thr_setconcurrency(int new_level);
|
int _thr_setconcurrency(int new_level);
|
||||||
int _thr_setmaxconcurrency(void);
|
int _thr_setmaxconcurrency(void);
|
||||||
void _thr_critical_enter(struct pthread *);
|
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();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __pselect(count, rfds, wfds, efds, timo, mask);
|
ret = __pselect(count, rfds, wfds, efds, timo, mask);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -48,9 +48,9 @@ __read(int fd, void *buf, size_t nbytes)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_read(fd, buf, nbytes);
|
ret = __sys_read(fd, buf, nbytes);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -48,9 +48,9 @@ __readv(int fd, const struct iovec *iov, int iovcnt)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_readv(fd, iov, iovcnt);
|
ret = __sys_readv(fd, iov, iovcnt);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -57,9 +57,9 @@ __select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
|||||||
TIMEVAL_TO_TIMESPEC(timeout, &ts);
|
TIMEVAL_TO_TIMESPEC(timeout, &ts);
|
||||||
return nanosleep(&ts, NULL);
|
return nanosleep(&ts, NULL);
|
||||||
} else {
|
} else {
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout);
|
ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ _sem_wait(sem_t *sem)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
|
|
||||||
_SEM_CHECK_VALIDITY(sem);
|
_SEM_CHECK_VALIDITY(sem);
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ _sem_wait(sem_t *sem)
|
|||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
RETURN:
|
RETURN:
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
return (retval);
|
return (retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,9 +95,9 @@ __sigsuspend(const sigset_t * set)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = _sigsuspend(set);
|
ret = _sigsuspend(set);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -137,9 +137,9 @@ __sigtimedwait(const sigset_t *set, siginfo_t *info,
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = lib_sigtimedwait(set, info, timeout);
|
ret = lib_sigtimedwait(set, info, timeout);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,9 +155,9 @@ __sigwaitinfo(const sigset_t *set, siginfo_t *info)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = lib_sigtimedwait(set, info, NULL);
|
ret = lib_sigtimedwait(set, info, NULL);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ __sigwait(const sigset_t *set, int *sig)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = lib_sigtimedwait(set, NULL, NULL);
|
ret = lib_sigtimedwait(set, NULL, NULL);
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
*sig = ret;
|
*sig = ret;
|
||||||
@ -181,7 +181,7 @@ __sigwait(const sigset_t *set, int *sig)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
ret = -1;
|
ret = -1;
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,9 +43,9 @@ _sleep(unsigned int seconds)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
unsigned int ret;
|
unsigned int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sleep(seconds);
|
ret = __sleep(seconds);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,9 @@ _system(const char *string)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __system(string);
|
ret = __system(string);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,9 @@ _tcdrain(int fd)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __tcdrain(fd);
|
ret = __tcdrain(fd);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -42,9 +42,9 @@ _wait(int *istat)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
pid_t ret;
|
pid_t ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __wait(istat);
|
ret = __wait(istat);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -49,9 +49,9 @@ __wait4(pid_t pid, int *istat, int options, struct rusage *rusage)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
pid_t ret;
|
pid_t ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = _wait4(pid, istat, options, rusage);
|
ret = _wait4(pid, istat, options, rusage);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -44,9 +44,9 @@ _waitpid(pid_t wpid, int *status, int options)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
pid_t ret;
|
pid_t ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __waitpid(wpid, status, options);
|
ret = __waitpid(wpid, status, options);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -48,9 +48,9 @@ __write(int fd, const void *buf, size_t nbytes)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_write(fd, buf, nbytes);
|
ret = __sys_write(fd, buf, nbytes);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -50,9 +50,9 @@ __writev(int fd, const struct iovec *iov, int iovcnt)
|
|||||||
struct pthread *curthread = _get_curthread();
|
struct pthread *curthread = _get_curthread();
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
_thr_enter_cancellation_point(curthread);
|
_thr_cancel_enter(curthread);
|
||||||
ret = __sys_writev(fd, iov, iovcnt);
|
ret = __sys_writev(fd, iov, iovcnt);
|
||||||
_thr_leave_cancellation_point(curthread);
|
_thr_cancel_leave(curthread, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user