summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2003-07-17 22:45:33 +0000
committerdavidxu <davidxu@FreeBSD.org>2003-07-17 22:45:33 +0000
commitfd1c90fb6f321674f766c628fd63fa44b304fc91 (patch)
treecef6e85606dd1d16f55753d85b9360e2da512ecc /sys/kern
parent5f9ce489aae8bf61982119b0522873aeb5ddfbbf (diff)
downloadFreeBSD-src-fd1c90fb6f321674f766c628fd63fa44b304fc91.zip
FreeBSD-src-fd1c90fb6f321674f766c628fd63fa44b304fc91.tar.gz
o Refine kse_thr_interrupt to allow it to handle different commands.
o Remove TDF_NOSIGPOST. o Add a member td_waitset to proc structure, it will be used for sigwait. Tested by: deischen
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/init_sysent.c2
-rw-r--r--sys/kern/kern_kse.c123
-rw-r--r--sys/kern/kern_thread.c123
-rw-r--r--sys/kern/syscalls.c2
-rw-r--r--sys/kern/syscalls.master2
5 files changed, 125 insertions, 127 deletions
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c
index bbee0bb..cfaedc4 100644
--- a/sys/kern/init_sysent.c
+++ b/sys/kern/init_sysent.c
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: src/sys/kern/syscalls.master,v 1.150 2003/06/04 03:49:31 rwatson Exp
+ * created from FreeBSD: src/sys/kern/syscalls.master,v 1.151 2003/06/28 08:29:05 davidxu Exp
*/
#include "opt_compat.h"
diff --git a/sys/kern/kern_kse.c b/sys/kern/kern_kse.c
index 89d3f46..6bcbd95 100644
--- a/sys/kern/kern_kse.c
+++ b/sys/kern/kern_kse.c
@@ -384,7 +384,8 @@ proc_linkup(struct proc *p, struct ksegrp *kg,
/*
struct kse_thr_interrupt_args {
struct kse_thr_mailbox * tmbx;
- int sig;
+ int cmd;
+ long data;
};
*/
int
@@ -392,47 +393,63 @@ kse_thr_interrupt(struct thread *td, struct kse_thr_interrupt_args *uap)
{
struct proc *p;
struct thread *td2;
- int sig = uap->sig;
p = td->td_proc;
- if (!(p->p_flag & P_SA) || (uap->tmbx == NULL) ||
- (sig < -2) || (sig > _SIG_MAXSIG))
+ if (!(p->p_flag & P_SA))
return (EINVAL);
- PROC_LOCK(p);
- mtx_lock_spin(&sched_lock);
- FOREACH_THREAD_IN_PROC(p, td2) {
- if (td2->td_mailbox == uap->tmbx)
- break;
- }
- if (td2 == NULL) {
- mtx_unlock_spin(&sched_lock);
- PROC_UNLOCK(p);
- return (ESRCH);
- }
- if (sig > 0) {
- td2->td_flags &= ~TDF_INTERRUPT;
- mtx_unlock_spin(&sched_lock);
- tdsignal(td2, sig, SIGTARGET_TD);
- } else if (sig == 0) {
- mtx_unlock_spin(&sched_lock);
- } else {
- td2->td_flags |= TDF_INTERRUPT | TDF_ASTPENDING;
- if (TD_CAN_UNBIND(td2))
- td2->td_upcall->ku_flags |= KUF_DOUPCALL;
- if (sig == -1)
- td2->td_intrval = EINTR;
- else if (sig == -2)
- td2->td_intrval = ERESTART;
- if (TD_ON_SLEEPQ(td2) && (td2->td_flags & TDF_SINTR)) {
- if (td2->td_flags & TDF_CVWAITQ)
- cv_abort(td2);
+ switch (uap->cmd) {
+ case KSE_INTR_SENDSIG:
+ if (uap->data < 0 || uap->data > _SIG_MAXSIG)
+ return (EINVAL);
+ case KSE_INTR_INTERRUPT:
+ case KSE_INTR_RESTART:
+ PROC_LOCK(p);
+ mtx_lock_spin(&sched_lock);
+ FOREACH_THREAD_IN_PROC(p, td2) {
+ if (td2->td_mailbox == uap->tmbx)
+ break;
+ }
+ if (td2 == NULL) {
+ mtx_unlock_spin(&sched_lock);
+ PROC_UNLOCK(p);
+ return (ESRCH);
+ }
+ if (uap->cmd == KSE_INTR_SENDSIG) {
+ if (uap->data > 0) {
+ td2->td_flags &= ~TDF_INTERRUPT;
+ mtx_unlock_spin(&sched_lock);
+ tdsignal(td2, (int)uap->data, SIGTARGET_TD);
+ } else {
+ mtx_unlock_spin(&sched_lock);
+ }
+ } else {
+ td2->td_flags |= TDF_INTERRUPT | TDF_ASTPENDING;
+ if (TD_CAN_UNBIND(td2))
+ td2->td_upcall->ku_flags |= KUF_DOUPCALL;
+ if (uap->cmd == KSE_INTR_INTERRUPT)
+ td2->td_intrval = EINTR;
else
- abortsleep(td2);
+ td2->td_intrval = ERESTART;
+ if (TD_ON_SLEEPQ(td2) && (td2->td_flags & TDF_SINTR)) {
+ if (td2->td_flags & TDF_CVWAITQ)
+ cv_abort(td2);
+ else
+ abortsleep(td2);
+ }
+ mtx_unlock_spin(&sched_lock);
}
- mtx_unlock_spin(&sched_lock);
+ PROC_UNLOCK(p);
+ break;
+ case KSE_INTR_SIGEXIT:
+ if (uap->data < 1 || uap->data > _SIG_MAXSIG)
+ return (EINVAL);
+ PROC_LOCK(p);
+ sigexit(td, (int)uap->data);
+ break;
+ default:
+ return (EINVAL);
}
- PROC_UNLOCK(p);
return (0);
}
@@ -991,7 +1008,7 @@ thread_free(struct thread *td)
* The list is anchored in the ksegrp structure.
*/
int
-thread_export_context(struct thread *td)
+thread_export_context(struct thread *td, int willexit)
{
struct proc *p;
struct ksegrp *kg;
@@ -1023,17 +1040,19 @@ thread_export_context(struct thread *td)
* For sync signal, it is only possible when the signal is not
* caught by userland or process is being debugged.
*/
+ PROC_LOCK(p);
if (td->td_flags & TDF_NEEDSIGCHK) {
mtx_lock_spin(&sched_lock);
td->td_flags &= ~TDF_NEEDSIGCHK;
mtx_unlock_spin(&sched_lock);
- PROC_LOCK(p);
mtx_lock(&p->p_sigacts->ps_mtx);
while ((sig = cursig(td)) != 0)
postsig(sig);
mtx_unlock(&p->p_sigacts->ps_mtx);
- PROC_UNLOCK(p);
}
+ if (willexit)
+ SIGFILLSET(td->td_sigmask);
+ PROC_UNLOCK(p);
/* Get address in latest mbox of list pointer */
addr = (void *)(&td->td_mailbox->tm_next);
@@ -1067,11 +1086,7 @@ thread_export_context(struct thread *td)
bad:
PROC_LOCK(p);
- psignal(p, SIGSEGV);
- PROC_UNLOCK(p);
- /* The mailbox is bad, don't use it */
- td->td_mailbox = NULL;
- td->td_usticks = 0;
+ sigexit(td, SIGILL);
return (error);
}
@@ -1665,15 +1680,7 @@ thread_userret(struct thread *td, struct trapframe *frame)
return (0);
}
mtx_unlock_spin(&sched_lock);
- error = thread_export_context(td);
- if (error) {
- /*
- * Failing to do the KSE operation just defaults
- * back to synchonous operation, so just return from
- * the syscall.
- */
- goto out;
- }
+ thread_export_context(td, 0);
/*
* There is something to report, and we own an upcall
* strucuture, we can go to userland.
@@ -1681,22 +1688,14 @@ thread_userret(struct thread *td, struct trapframe *frame)
*/
td->td_pflags |= TDP_UPCALLING;
} else if (td->td_mailbox && (ku == NULL)) {
- /*
- * Because we are exiting, SIGKILL and SIGSTOP shouldn't
- * be posted to us anymore, otherwise they will be lost.
- */
- mtx_lock_spin(&sched_lock);
- td->td_flags |= TDF_NOSIGPOST;
- mtx_unlock_spin(&sched_lock);
- error = thread_export_context(td);
- /* possibly upcall with error? */
+ thread_export_context(td, 1);
PROC_LOCK(p);
/*
* There are upcall threads waiting for
* work to do, wake one of them up.
* XXXKSE Maybe wake all of them up.
*/
- if (!error && kg->kg_upsleeps)
+ if (kg->kg_upsleeps)
wakeup_one(&kg->kg_completed);
mtx_lock_spin(&sched_lock);
thread_stopped(p);
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index 89d3f46..6bcbd95 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -384,7 +384,8 @@ proc_linkup(struct proc *p, struct ksegrp *kg,
/*
struct kse_thr_interrupt_args {
struct kse_thr_mailbox * tmbx;
- int sig;
+ int cmd;
+ long data;
};
*/
int
@@ -392,47 +393,63 @@ kse_thr_interrupt(struct thread *td, struct kse_thr_interrupt_args *uap)
{
struct proc *p;
struct thread *td2;
- int sig = uap->sig;
p = td->td_proc;
- if (!(p->p_flag & P_SA) || (uap->tmbx == NULL) ||
- (sig < -2) || (sig > _SIG_MAXSIG))
+ if (!(p->p_flag & P_SA))
return (EINVAL);
- PROC_LOCK(p);
- mtx_lock_spin(&sched_lock);
- FOREACH_THREAD_IN_PROC(p, td2) {
- if (td2->td_mailbox == uap->tmbx)
- break;
- }
- if (td2 == NULL) {
- mtx_unlock_spin(&sched_lock);
- PROC_UNLOCK(p);
- return (ESRCH);
- }
- if (sig > 0) {
- td2->td_flags &= ~TDF_INTERRUPT;
- mtx_unlock_spin(&sched_lock);
- tdsignal(td2, sig, SIGTARGET_TD);
- } else if (sig == 0) {
- mtx_unlock_spin(&sched_lock);
- } else {
- td2->td_flags |= TDF_INTERRUPT | TDF_ASTPENDING;
- if (TD_CAN_UNBIND(td2))
- td2->td_upcall->ku_flags |= KUF_DOUPCALL;
- if (sig == -1)
- td2->td_intrval = EINTR;
- else if (sig == -2)
- td2->td_intrval = ERESTART;
- if (TD_ON_SLEEPQ(td2) && (td2->td_flags & TDF_SINTR)) {
- if (td2->td_flags & TDF_CVWAITQ)
- cv_abort(td2);
+ switch (uap->cmd) {
+ case KSE_INTR_SENDSIG:
+ if (uap->data < 0 || uap->data > _SIG_MAXSIG)
+ return (EINVAL);
+ case KSE_INTR_INTERRUPT:
+ case KSE_INTR_RESTART:
+ PROC_LOCK(p);
+ mtx_lock_spin(&sched_lock);
+ FOREACH_THREAD_IN_PROC(p, td2) {
+ if (td2->td_mailbox == uap->tmbx)
+ break;
+ }
+ if (td2 == NULL) {
+ mtx_unlock_spin(&sched_lock);
+ PROC_UNLOCK(p);
+ return (ESRCH);
+ }
+ if (uap->cmd == KSE_INTR_SENDSIG) {
+ if (uap->data > 0) {
+ td2->td_flags &= ~TDF_INTERRUPT;
+ mtx_unlock_spin(&sched_lock);
+ tdsignal(td2, (int)uap->data, SIGTARGET_TD);
+ } else {
+ mtx_unlock_spin(&sched_lock);
+ }
+ } else {
+ td2->td_flags |= TDF_INTERRUPT | TDF_ASTPENDING;
+ if (TD_CAN_UNBIND(td2))
+ td2->td_upcall->ku_flags |= KUF_DOUPCALL;
+ if (uap->cmd == KSE_INTR_INTERRUPT)
+ td2->td_intrval = EINTR;
else
- abortsleep(td2);
+ td2->td_intrval = ERESTART;
+ if (TD_ON_SLEEPQ(td2) && (td2->td_flags & TDF_SINTR)) {
+ if (td2->td_flags & TDF_CVWAITQ)
+ cv_abort(td2);
+ else
+ abortsleep(td2);
+ }
+ mtx_unlock_spin(&sched_lock);
}
- mtx_unlock_spin(&sched_lock);
+ PROC_UNLOCK(p);
+ break;
+ case KSE_INTR_SIGEXIT:
+ if (uap->data < 1 || uap->data > _SIG_MAXSIG)
+ return (EINVAL);
+ PROC_LOCK(p);
+ sigexit(td, (int)uap->data);
+ break;
+ default:
+ return (EINVAL);
}
- PROC_UNLOCK(p);
return (0);
}
@@ -991,7 +1008,7 @@ thread_free(struct thread *td)
* The list is anchored in the ksegrp structure.
*/
int
-thread_export_context(struct thread *td)
+thread_export_context(struct thread *td, int willexit)
{
struct proc *p;
struct ksegrp *kg;
@@ -1023,17 +1040,19 @@ thread_export_context(struct thread *td)
* For sync signal, it is only possible when the signal is not
* caught by userland or process is being debugged.
*/
+ PROC_LOCK(p);
if (td->td_flags & TDF_NEEDSIGCHK) {
mtx_lock_spin(&sched_lock);
td->td_flags &= ~TDF_NEEDSIGCHK;
mtx_unlock_spin(&sched_lock);
- PROC_LOCK(p);
mtx_lock(&p->p_sigacts->ps_mtx);
while ((sig = cursig(td)) != 0)
postsig(sig);
mtx_unlock(&p->p_sigacts->ps_mtx);
- PROC_UNLOCK(p);
}
+ if (willexit)
+ SIGFILLSET(td->td_sigmask);
+ PROC_UNLOCK(p);
/* Get address in latest mbox of list pointer */
addr = (void *)(&td->td_mailbox->tm_next);
@@ -1067,11 +1086,7 @@ thread_export_context(struct thread *td)
bad:
PROC_LOCK(p);
- psignal(p, SIGSEGV);
- PROC_UNLOCK(p);
- /* The mailbox is bad, don't use it */
- td->td_mailbox = NULL;
- td->td_usticks = 0;
+ sigexit(td, SIGILL);
return (error);
}
@@ -1665,15 +1680,7 @@ thread_userret(struct thread *td, struct trapframe *frame)
return (0);
}
mtx_unlock_spin(&sched_lock);
- error = thread_export_context(td);
- if (error) {
- /*
- * Failing to do the KSE operation just defaults
- * back to synchonous operation, so just return from
- * the syscall.
- */
- goto out;
- }
+ thread_export_context(td, 0);
/*
* There is something to report, and we own an upcall
* strucuture, we can go to userland.
@@ -1681,22 +1688,14 @@ thread_userret(struct thread *td, struct trapframe *frame)
*/
td->td_pflags |= TDP_UPCALLING;
} else if (td->td_mailbox && (ku == NULL)) {
- /*
- * Because we are exiting, SIGKILL and SIGSTOP shouldn't
- * be posted to us anymore, otherwise they will be lost.
- */
- mtx_lock_spin(&sched_lock);
- td->td_flags |= TDF_NOSIGPOST;
- mtx_unlock_spin(&sched_lock);
- error = thread_export_context(td);
- /* possibly upcall with error? */
+ thread_export_context(td, 1);
PROC_LOCK(p);
/*
* There are upcall threads waiting for
* work to do, wake one of them up.
* XXXKSE Maybe wake all of them up.
*/
- if (!error && kg->kg_upsleeps)
+ if (kg->kg_upsleeps)
wakeup_one(&kg->kg_completed);
mtx_lock_spin(&sched_lock);
thread_stopped(p);
diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c
index c91c79b..14bfaf4 100644
--- a/sys/kern/syscalls.c
+++ b/sys/kern/syscalls.c
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: src/sys/kern/syscalls.master,v 1.150 2003/06/04 03:49:31 rwatson Exp
+ * created from FreeBSD: src/sys/kern/syscalls.master,v 1.151 2003/06/28 08:29:05 davidxu Exp
*/
const char *syscallnames[] = {
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 0e171ab..febd7a1 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -556,7 +556,7 @@
380 MSTD BSD { int kse_wakeup(struct kse_mailbox *mbx); }
381 STD BSD { int kse_create(struct kse_mailbox *mbx, \
int newgroup); }
-382 MSTD BSD { int kse_thr_interrupt(struct kse_thr_mailbox *tmbx, int sig); }
+382 MSTD BSD { int kse_thr_interrupt(struct kse_thr_mailbox *tmbx, int cmd, long data); }
383 MSTD BSD { int kse_release(struct timespec *timeout); }
384 MSTD BSD { int __mac_get_proc(struct mac *mac_p); }
385 MSTD BSD { int __mac_set_proc(struct mac *mac_p); }
OpenPOWER on IntegriCloud