diff options
author | davidxu <davidxu@FreeBSD.org> | 2003-07-17 22:45:33 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2003-07-17 22:45:33 +0000 |
commit | fd1c90fb6f321674f766c628fd63fa44b304fc91 (patch) | |
tree | cef6e85606dd1d16f55753d85b9360e2da512ecc | |
parent | 5f9ce489aae8bf61982119b0522873aeb5ddfbbf (diff) | |
download | FreeBSD-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
-rw-r--r-- | sys/kern/init_sysent.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_kse.c | 123 | ||||
-rw-r--r-- | sys/kern/kern_thread.c | 123 | ||||
-rw-r--r-- | sys/kern/syscalls.c | 2 | ||||
-rw-r--r-- | sys/kern/syscalls.master | 2 | ||||
-rw-r--r-- | sys/sys/kse.h | 7 | ||||
-rw-r--r-- | sys/sys/proc.h | 4 | ||||
-rw-r--r-- | sys/sys/syscall.h | 2 | ||||
-rw-r--r-- | sys/sys/syscall.mk | 2 | ||||
-rw-r--r-- | sys/sys/sysproto.h | 5 |
10 files changed, 138 insertions, 134 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); } diff --git a/sys/sys/kse.h b/sys/sys/kse.h index 9a5e821..1108c4c 100644 --- a/sys/sys/kse.h +++ b/sys/sys/kse.h @@ -94,11 +94,16 @@ struct kse_mailbox { #define KMF_BOUND 0x08 #define KMF_WAITSIGEVENT 0x10 +#define KSE_INTR_INTERRUPT 0x01 +#define KSE_INTR_RESTART 0x02 +#define KSE_INTR_SENDSIG 0x03 +#define KSE_INTR_SIGEXIT 0x04 + #ifndef _KERNEL int kse_create(struct kse_mailbox *, int); int kse_exit(void); int kse_release(struct timespec *); -int kse_thr_interrupt(struct kse_thr_mailbox *, int); +int kse_thr_interrupt(struct kse_thr_mailbox *, int, long); int kse_wakeup(struct kse_mailbox *); #endif /* !_KERNEL */ diff --git a/sys/sys/proc.h b/sys/sys/proc.h index c907e29..8ad52f9 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -298,6 +298,7 @@ struct thread { sigset_t td_oldsigmask; /* (k) Saved mask from pre sigpause. */ sigset_t td_sigmask; /* (c) Current signal mask. */ sigset_t td_siglist; /* (c) Sigs arrived, not delivered. */ + sigset_t *td_waitset; /* (c) Wait set for sigwait */ TAILQ_ENTRY(thread) td_umtx; /* (c?) Link for when we're blocked. */ #define td_endzero td_base_pri @@ -341,7 +342,6 @@ struct thread { #define TDF_SELECT 0x000040 /* Selecting; wakeup/waiting danger. */ #define TDF_CVWAITQ 0x000080 /* Thread is on a cv_waitq (not slpq). */ #define TDF_ONSLEEPQ 0x000200 /* On the sleep queue. */ -#define TDF_NOSIGPOST 0x000400 /* Thread doesn't want signals */ #define TDF_ASTPENDING 0x000800 /* Thread has some asynchronous events. */ #define TDF_TIMOFAIL 0x001000 /* Timeout from sleep after we were awake. */ #define TDF_INTERRUPT 0x002000 /* Thread is marked as interrupted. */ @@ -903,7 +903,7 @@ void ksegrp_unlink(struct ksegrp *kg); void thread_signal_add(struct thread *td, int sig); struct thread *thread_alloc(void); void thread_exit(void) __dead2; -int thread_export_context(struct thread *td); +int thread_export_context(struct thread *td, int willexit); void thread_free(struct thread *td); void thread_link(struct thread *td, struct ksegrp *kg); void thread_reap(void); diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index 54eabe6..036e5d1 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -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 */ #define SYS_syscall 0 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index c0118a1..194be6c 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -1,7 +1,7 @@ # FreeBSD system call names. # 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 MIASM = \ syscall.o \ exit.o \ diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index 5c4d5c9..202918e 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -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 */ #ifndef _SYS_SYSPROTO_H_ @@ -1072,7 +1072,8 @@ struct kse_create_args { }; struct kse_thr_interrupt_args { char tmbx_l_[PADL_(struct kse_thr_mailbox *)]; struct kse_thr_mailbox * tmbx; char tmbx_r_[PADR_(struct kse_thr_mailbox *)]; - char sig_l_[PADL_(int)]; int sig; char sig_r_[PADR_(int)]; + char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; + char data_l_[PADL_(long)]; long data; char data_r_[PADR_(long)]; }; struct kse_release_args { char timeout_l_[PADL_(struct timespec *)]; struct timespec * timeout; char timeout_r_[PADR_(struct timespec *)]; |