From c70b5cef9cd869b5048eb62edb340396b02e4db0 Mon Sep 17 00:00:00 2001 From: Ted Unangst Date: Sat, 3 Dec 2005 18:09:10 +0000 Subject: kernel support for threaded processes (rthreads). uses rfork(RFTHREAD) to create threads, which are presently processes that are a little more tightly bound together. several new syscalls added to facilitate a userland thread library. all conditional on RTHREADS, currently disabled. ok deraadt --- sys/kern/init_main.c | 6 +++- sys/kern/init_sysent.c | 27 +++++++++++++- sys/kern/kern_exec.c | 4 +-- sys/kern/kern_exit.c | 66 +++++++++++++++++++++++++++++++--- sys/kern/kern_fork.c | 16 ++++++++- sys/kern/kern_kthread.c | 4 +-- sys/kern/kern_proc.c | 10 +++++- sys/kern/kern_prot.c | 20 +++++++++-- sys/kern/kern_sig.c | 30 ++++++++++++++-- sys/kern/kern_synch.c | 93 +++++++++++++++++++++++++++++++++++++++++++++--- sys/kern/syscalls.c | 16 ++++++++- sys/kern/syscalls.master | 16 ++++++++- sys/sys/param.h | 3 +- sys/sys/proc.h | 24 +++++++++++-- sys/sys/syscall.h | 22 ++++++++++-- sys/sys/syscallargs.h | 29 ++++++++++++++- 16 files changed, 356 insertions(+), 30 deletions(-) (limited to 'sys') diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index fa07ab9941a..16798e2c49d 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init_main.c,v 1.125 2005/11/12 04:31:24 jsg Exp $ */ +/* $OpenBSD: init_main.c,v 1.126 2005/12/03 18:09:08 tedu Exp $ */ /* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */ /* @@ -270,6 +270,10 @@ main(void *framep) session0.s_count = 1; session0.s_leader = p; + p->p_thrparent = p; + LIST_INIT(&p->p_thrchildren); + LIST_INIT(&p->p_sleepers); + p->p_flag = P_INMEM | P_SYSTEM | P_NOCLDWAIT; p->p_stat = SONPROC; p->p_nice = NZERO; diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 979ed123775..23921e461d1 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init_sysent.c,v 1.87 2005/07/03 20:14:19 drahn Exp $ */ +/* $OpenBSD: init_sysent.c,v 1.88 2005/12/03 18:09:08 tedu Exp $ */ /* * System call switch table. @@ -792,6 +792,31 @@ struct sysent sysent[] = { #else { 0, 0, sys_nosys }, /* 297 = unimplemented */ +#endif + { 0, 0, + sys_sched_yield }, /* 298 = sched_yield */ +#ifdef RTHREADS + { 0, 0, + sys_getthrid }, /* 299 = getthrid */ + { 3, s(struct sys_thrsleep_args), + sys_thrsleep }, /* 300 = thrsleep */ + { 1, s(struct sys_thrwakeup_args), + sys_thrwakeup }, /* 301 = thrwakeup */ + { 1, s(struct sys_threxit_args), + sys_threxit }, /* 302 = threxit */ + { 1, s(struct sys_thrsigdivert_args), + sys_thrsigdivert }, /* 303 = thrsigdivert */ +#else + { 0, 0, + sys_nosys }, /* 299 = unimplemented */ + { 0, 0, + sys_nosys }, /* 300 = unimplemented */ + { 0, 0, + sys_nosys }, /* 301 = unimplemented */ + { 0, 0, + sys_nosys }, /* 302 = unimplemented */ + { 0, 0, + sys_nosys }, /* 303 = unimplemented */ #endif }; diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index a4fe2366a23..dc01d2833d9 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exec.c,v 1.96 2005/11/28 00:14:28 jsg Exp $ */ +/* $OpenBSD: kern_exec.c,v 1.97 2005/12/03 18:09:08 tedu Exp $ */ /* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */ /*- @@ -709,7 +709,7 @@ exec_abort: free_pack_abort: free(pack.ep_hdr, M_EXEC); - exit1(p, W_EXITCODE(0, SIGABRT)); + exit1(p, W_EXITCODE(0, SIGABRT), EXIT_NORMAL); /* NOTREACHED */ p->p_flag &= ~P_INEXEC; diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index afd18111a2b..7034dcbd8fc 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exit.c,v 1.56 2005/11/28 00:14:28 jsg Exp $ */ +/* $OpenBSD: kern_exit.c,v 1.57 2005/12/03 18:09:08 tedu Exp $ */ /* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */ /* @@ -88,24 +88,73 @@ sys_exit(struct proc *p, void *v, register_t *retval) syscallarg(int) rval; } */ *uap = v; - exit1(p, W_EXITCODE(SCARG(uap, rval), 0)); + exit1(p, W_EXITCODE(SCARG(uap, rval), 0), EXIT_NORMAL); /* NOTREACHED */ return (0); } +#ifdef RTHREADS +int +sys_threxit(struct proc *p, void *v, register_t *retval) +{ + struct sys_threxit_args *uap = v; + + exit1(p, W_EXITCODE(SCARG(uap, rval), 0), EXIT_THREAD); + + return (0); +} +#endif + /* * Exit: deallocate address space and other resources, change proc state * to zombie, and unlink proc from allproc and parent's lists. Save exit * status and rusage for wait(). Check for child processes and orphan them. */ void -exit1(struct proc *p, int rv) +exit1(struct proc *p, int rv, int flags) { struct proc *q, *nq; if (p->p_pid == 1) panic("init died (signal %d, exit %d)", WTERMSIG(rv), WEXITSTATUS(rv)); + + /* + * if one thread calls exit, we take down everybody. + * we have to be careful not to get recursively caught. + * this is kinda sick. + */ + if (flags == EXIT_NORMAL && p != p->p_thrparent && + (p->p_thrparent->p_flag & P_WEXIT) == 0) { + printf("thread exiting normally %d\n", p->p_pid); + /* + * we are one of the threads. we SIGKILL the parent, + * then wait for it to kill us back. as soon as we return, + * we'll exit again. + */ + p->p_thrparent->p_flag |= P_IGNEXITRV; + p->p_thrparent->p_xstat = rv; + psignal(p->p_thrparent, SIGKILL); + tsleep(&p->p_thrparent->p_thrchildren, PUSER | PCATCH, "dying", + 0); + printf("thread got sig %d\n", p->p_pid); + return; + } else if (p == p->p_thrparent) { + p->p_flag |= P_WEXIT; + if (flags == EXIT_NORMAL) { + q = LIST_FIRST(&p->p_thrchildren); + for (; q != 0; q = nq) { + nq = LIST_NEXT(q, p_thrsib); + q->p_flag |= P_IGNEXITRV; + q->p_xstat = rv; + printf("parent killing child %d\n", q->p_pid); + psignal(q, SIGKILL); + } + } + while (!LIST_EMPTY(&p->p_thrchildren)) + tsleep(&p->p_thrchildren, PUSER, "thrdeath", 0); + } + if (p->p_flag & P_PROFIL) stopprofclock(p); @@ -218,11 +267,20 @@ exit1(struct proc *p, int rv) } } + /* unlink oursleves from the active threads */ + if (p != p->p_thrparent) { + LIST_REMOVE(p, p_thrsib); + if (LIST_EMPTY(&p->p_thrparent->p_thrchildren)) + wakeup(&p->p_thrparent->p_thrchildren); + } + + /* * Save exit status and final rusage info, adding in child rusage * info and self times. */ - p->p_xstat = rv; + if (!(p->p_flag & P_IGNEXITRV)) + p->p_xstat = rv; *p->p_ru = p->p_stats->p_ru; calcru(p, &p->p_ru->ru_utime, &p->p_ru->ru_stime, NULL); ruadd(p->p_ru, &p->p_stats->p_cru); diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 62e68a3d51c..7123eb5be37 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_fork.c,v 1.78 2005/11/02 20:03:16 aaron Exp $ */ +/* $OpenBSD: kern_fork.c,v 1.79 2005/12/03 18:09:08 tedu Exp $ */ /* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */ /* @@ -139,6 +139,10 @@ sys_rfork(struct proc *p, void *v, register_t *retval) if (rforkflags & RFMEM) flags |= FORK_SHAREVM; +#ifdef RTHREADS + if (rforkflags & RFTHREAD) + flags |= FORK_THREAD; +#endif return (fork1(p, SIGCHLD, flags, NULL, 0, NULL, NULL, retval, NULL)); } @@ -281,6 +285,16 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize, LIST_INSERT_HEAD(&p1->p_children, p2, p_sibling); LIST_INIT(&p2->p_children); + if (flags & FORK_THREAD) { + p2->p_thrparent = p1->p_thrparent; + LIST_INSERT_HEAD(&p1->p_thrparent->p_thrchildren, p2, p_thrsib); + } else { + p2->p_thrparent = p2; + } + + LIST_INIT(&p2->p_thrchildren); + LIST_INIT(&p2->p_sleepers); + #ifdef KTRACE /* * Copy traceflag and tracefile if enabled. diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c index 971d5e76eb6..7f8e60b7141 100644 --- a/sys/kern/kern_kthread.c +++ b/sys/kern/kern_kthread.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_kthread.c,v 1.24 2004/12/08 06:56:14 miod Exp $ */ +/* $OpenBSD: kern_kthread.c,v 1.25 2005/12/03 18:09:08 tedu Exp $ */ /* $NetBSD: kern_kthread.c,v 1.3 1998/12/22 21:21:36 kleink Exp $ */ /*- @@ -114,7 +114,7 @@ kthread_exit(int ecode) printf("WARNING: thread `%s' (%d) exits with status %d\n", curproc->p_comm, curproc->p_pid, ecode); - exit1(curproc, W_EXITCODE(ecode, 0)); + exit1(curproc, W_EXITCODE(ecode, 0), EXIT_NORMAL); /* * XXX Fool the compiler. Making exit1() __dead is a can diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index b319492a93b..de57bbe7b1d 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_proc.c,v 1.28 2005/11/28 00:14:28 jsg Exp $ */ +/* $OpenBSD: kern_proc.c,v 1.29 2005/12/03 18:09:08 tedu Exp $ */ /* $NetBSD: kern_proc.c,v 1.14 1996/02/09 18:59:41 christos Exp $ */ /* @@ -85,6 +85,10 @@ procinit(void) LIST_INIT(&allproc); LIST_INIT(&zombproc); +#ifdef RTHREADS + extern struct pool sleeper_pool; +#endif + pidhashtbl = hashinit(maxproc / 4, M_PROC, M_NOWAIT, &pidhash); pgrphashtbl = hashinit(maxproc / 4, M_PROC, M_NOWAIT, &pgrphash); uihashtbl = hashinit(maxproc / 16, M_PROC, M_NOWAIT, &uihash); @@ -103,6 +107,10 @@ procinit(void) &pool_allocator_nointr); pool_init(&pcred_pool, sizeof(struct pcred), 0, 0, 0, "pcredpl", &pool_allocator_nointr); +#ifdef RTHREADS + pool_init(&sleeper_pool, sizeof(struct twaitnode), 0, 0, 0, "thrwaitpl", + &pool_allocator_nointr); +#endif } /* diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 58b32807097..f3081e33740 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_prot.c,v 1.27 2005/11/28 00:14:29 jsg Exp $ */ +/* $OpenBSD: kern_prot.c,v 1.28 2005/12/03 18:09:08 tedu Exp $ */ /* $NetBSD: kern_prot.c,v 1.33 1996/02/09 18:59:42 christos Exp $ */ /* @@ -60,14 +60,28 @@ int sys_getpid(struct proc *p, void *v, register_t *retval) { - *retval = p->p_pid; + *retval = p->p_thrparent->p_pid; #if defined(COMPAT_43) || defined(COMPAT_SUNOS) || defined(COMPAT_IBCS2) || \ defined(COMPAT_FREEBSD) || defined(COMPAT_BSDOS) - retval[1] = p->p_pptr->p_pid; + retval[1] = p->p_thrparent->p_pptr->p_pid; #endif return (0); } +#ifdef RTHREADS +/* ARGSUSED */ +int +sys_getthrid(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + + *retval = p->p_pid; + return (0); +} +#endif + /* ARGSUSED */ int sys_getppid(struct proc *p, void *v, register_t *retval) diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index cf4368ff149..9656982fe7c 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.77 2005/11/28 00:14:29 jsg Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.78 2005/12/03 18:09:08 tedu Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -97,6 +97,11 @@ cansignal(struct proc *p, struct pcred *pc, struct proc *q, int signum) if (p == q) return (1); /* process can always signal itself */ + /* a thread can only be signalled from within the same process */ + if (q->p_flag & P_THREAD) + return (p->p_thrparent == q->p_thrparent); + + if (signum == SIGCONT && q->p_session == p->p_session) return (1); /* SIGCONT in session */ @@ -766,6 +771,7 @@ psignal(struct proc *p, int signum) int s, prop; sig_t action; int mask; + struct proc *q; #ifdef DIAGNOSTIC if ((u_int)signum >= NSIG || signum == 0) @@ -776,6 +782,14 @@ psignal(struct proc *p, int signum) if (p->p_flag & P_WEXIT) return; + LIST_FOREACH(q, &p->p_thrchildren, p_thrsib) { + if (q->p_sigdivert & (1 << signum)) { + q->p_sigdivert = 0; + psignal(q, signum); + return; + } + } + KNOTE(&p->p_klist, NOTE_SIGNAL | signum); mask = sigmask(signum); @@ -1279,7 +1293,7 @@ sigexit(struct proc *p, int signum) if (coredump(p) == 0) signum |= WCOREFLAG; } - exit1(p, W_EXITCODE(0, signum)); + exit1(p, W_EXITCODE(0, signum), EXIT_NORMAL); /* NOTREACHED */ } @@ -1424,6 +1438,18 @@ sys_nosys(struct proc *p, void *v, register_t *retval) return (ENOSYS); } +#ifdef RTHREADS +int +sys_thrsigdivert(struct proc *p, void *v, register_t *retval) +{ + struct sys_thrsigdivert_args *uap = v; + + p->p_sigdivert = SCARG(uap, sigmask); + + return (0); +} +#endif + void initsiginfo(siginfo_t *si, int sig, u_long code, int type, union sigval val) { diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index b32a6b05182..9665e74338d 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_synch.c,v 1.66 2005/11/28 00:14:29 jsg Exp $ */ +/* $OpenBSD: kern_synch.c,v 1.67 2005/12/03 18:09:08 tedu Exp $ */ /* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */ /* @@ -47,6 +47,11 @@ #include #include #include +#include +#include +#include + +#include #ifdef KTRACE #include @@ -127,8 +132,12 @@ ltsleep(void *ident, int priority, const char *wmesg, int timo, SCHED_LOCK(s); #ifdef DIAGNOSTIC - if (ident == NULL || p->p_stat != SONPROC || p->p_back != NULL) - panic("tsleep"); + if (ident == NULL) + panic("tsleep: no ident"); + if (p->p_stat != SONPROC) + panic("tsleep: not SONPROC"); + if (p->p_back != NULL) + panic("tsleep: p_back not NULL"); #endif p->p_wchan = ident; @@ -300,8 +309,10 @@ wakeup_n(void *ident, int n) restart: for (q = &qp->sq_head; (p = *q) != NULL; ) { #ifdef DIAGNOSTIC - if (p->p_back || (p->p_stat != SSLEEP && p->p_stat != SSTOP)) - panic("wakeup"); + if (p->p_back) + panic("wakeup: p_back not NULL"); + if (p->p_stat != SSLEEP && p->p_stat != SSTOP) + panic("wakeup: p_stat is %d", (int)p->p_stat); #endif if (p->p_wchan == ident) { --n; @@ -357,3 +368,75 @@ wakeup(void *chan) { wakeup_n(chan, -1); } + +int +sys_sched_yield(struct proc *p, void *v, register_t *retval) +{ + yield(); + return (0); +} + +#ifdef RTHREADS + +struct pool sleeper_pool; + +int +sys_thrsleep(struct proc *p, void *v, register_t *revtal) +{ + struct sys_thrsleep_args *uap = v; + long ident = SCARG(uap, ident); + int timo = SCARG(uap, timeout); + _spinlock_lock_t *lock = SCARG(uap, lock); + _spinlock_lock_t unlocked = _SPINLOCK_UNLOCKED; + + struct twaitnode *n, *n2; + int error; + + n = pool_get(&sleeper_pool, PR_WAITOK); + n->t_ident = ident; + /* we may have slept */ + LIST_FOREACH(n2, &p->p_thrparent->p_sleepers, t_next) { + if (n2->t_ident == ident) + break; + } + if (n2) { + pool_put(&sleeper_pool, n); + n = n2; + } else { + LIST_INSERT_HEAD(&p->p_thrparent->p_sleepers, n, t_next); + } + + if (lock) + copyout(&unlocked, lock, sizeof(unlocked)); + if (hz > 1000) + timo = timo * (hz / 1000); + else + timo = timo / (1000 / hz); + error = tsleep(n, PUSER | PCATCH, "sys_tsleep", timo); + + return (error); + +} + +int +sys_thrwakeup(struct proc *p, void *v, register_t *retval) +{ + struct sys_thrwakeup_args *uap = v; + long ident = SCARG(uap, ident); + struct twaitnode *n; + + LIST_FOREACH(n, &p->p_thrparent->p_sleepers, t_next) { + if (n->t_ident == ident) { + LIST_REMOVE(n, t_next); + break; + } + } + if (!n) + return (ESRCH); + wakeup(n); + pool_put(&sleeper_pool, n); + yield(); + + return (0); +} +#endif diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index d8f6a7de78d..4f6d22f09fa 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: syscalls.c,v 1.88 2005/07/03 20:14:19 drahn Exp $ */ +/* $OpenBSD: syscalls.c,v 1.89 2005/12/03 18:09:08 tedu Exp $ */ /* * System call names. @@ -406,5 +406,19 @@ char *syscallnames[] = { "msgctl", /* 297 = msgctl */ #else "#297 (unimplemented)", /* 297 = unimplemented */ +#endif + "sched_yield", /* 298 = sched_yield */ +#ifdef RTHREADS + "getthrid", /* 299 = getthrid */ + "thrsleep", /* 300 = thrsleep */ + "thrwakeup", /* 301 = thrwakeup */ + "threxit", /* 302 = threxit */ + "thrsigdivert", /* 303 = thrsigdivert */ +#else + "#299 (unimplemented)", /* 299 = unimplemented */ + "#300 (unimplemented)", /* 300 = unimplemented */ + "#301 (unimplemented)", /* 301 = unimplemented */ + "#302 (unimplemented)", /* 302 = unimplemented */ + "#303 (unimplemented)", /* 303 = unimplemented */ #endif }; diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 5c6e0efaee0..1313e320676 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ -; $OpenBSD: syscalls.master,v 1.78 2005/07/03 20:13:59 drahn Exp $ +; $OpenBSD: syscalls.master,v 1.79 2005/12/03 18:09:08 tedu Exp $ ; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -594,3 +594,17 @@ #else 297 UNIMPL #endif +298 STD { int sys_sched_yield(void); } +#ifdef RTHREADS +299 STD { pid_t sys_getthrid(void); } +300 STD { int sys_thrsleep(long ident, int timeout, void *lock); } +301 STD { int sys_thrwakeup(long ident); } +302 STD { int sys_threxit(int rval); } +303 STD { int sys_thrsigdivert(sigset_t sigmask); } +#else +299 UNIMPL +300 UNIMPL +301 UNIMPL +302 UNIMPL +303 UNIMPL +#endif diff --git a/sys/sys/param.h b/sys/sys/param.h index 6e1bfc4d8f3..6618f2b21a6 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -1,4 +1,4 @@ -/* $OpenBSD: param.h,v 1.63 2005/08/09 00:46:12 deraadt Exp $ */ +/* $OpenBSD: param.h,v 1.64 2005/12/03 18:09:09 tedu Exp $ */ /* $NetBSD: param.h,v 1.23 1996/03/17 01:02:29 thorpej Exp $ */ /*- @@ -241,3 +241,4 @@ #define RFCNAMEG (1<<10) /* UNIMPL zero plan9 `name space' */ #define RFCENVG (1<<11) /* UNIMPL zero plan9 `env space' */ #define RFCFDG (1<<12) /* zero fd table */ +#define RFTHREAD (1<<13) /* create a thread, not a process */ diff --git a/sys/sys/proc.h b/sys/sys/proc.h index aecb2689f18..36e76d9212a 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.81 2005/11/21 18:16:46 millert Exp $ */ +/* $OpenBSD: proc.h,v 1.82 2005/12/03 18:09:09 tedu Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -113,6 +113,11 @@ struct emul { extern struct emul *emulsw[]; /* All emuls in system */ extern int nemuls; /* Number of emuls */ +struct twaitnode { + long t_ident; + LIST_ENTRY(twaitnode) t_next; +}; + /* * Description of a process. * @@ -159,6 +164,14 @@ struct proc { pid_t p_oppid; /* Save parent pid during ptrace. XXX */ int p_dupfd; /* Sideways return value from filedescopen. XXX */ + /* threads are processes that sometimes use the parent thread's + * info for userland visibility */ + struct proc *p_thrparent; + LIST_ENTRY(proc) p_thrsib; + LIST_HEAD(, proc) p_thrchildren; + LIST_HEAD(, twaitnode) p_sleepers; + + /* scheduling */ u_int p_estcpu; /* Time averaged value of p_cpticks. */ int p_cpticks; /* Ticks of cpu time. */ @@ -200,6 +213,7 @@ struct proc { struct klist p_klist; /* knotes attached to this process */ /* pad to 256, avoid shifting eproc. */ + sigset_t p_sigdivert; /* Signals to be diverted to thread. */ /* End area that is zeroed on creation. */ #define p_endzero p_startcopy @@ -278,6 +292,8 @@ struct proc { #define P_CONTINUED 0x800000 /* Proc has continued from a stopped state. */ #define P_SWAPIN 0x1000000 /* Swapping in right now */ #define P_BIGLOCK 0x2000000 /* Process needs kernel "big lock" to run */ +#define P_THREAD 0x4000000 /* Only a thread, not a real process */ +#define P_IGNEXITRV 0x8000000 /* For thread kills */ #define P_BITS \ ("\20\01ADVLOCK\02CTTY\03INMEM\04NOCLDSTOP\05PPWAIT\06PROFIL\07SELECT" \ @@ -361,6 +377,10 @@ struct uidinfo *uid_find(uid_t); #define FORK_SHAREVM 0x00000080 #define FORK_SIGHAND 0x00000200 #define FORK_PTRACE 0x00000400 +#define FORK_THREAD 0x00000800 + +#define EXIT_NORMAL 0x00000001 +#define EXIT_THREAD 0x00000002 #define PIDHASH(pid) (&pidhashtbl[(pid) & pidhash]) extern LIST_HEAD(pidhashhead, proc) *pidhashtbl; @@ -432,7 +452,7 @@ void wakeup_n(void *chan, int); void wakeup(void *chan); #define wakeup_one(c) wakeup_n((c), 1) void reaper(void); -void exit1(struct proc *, int); +void exit1(struct proc *, int, int); void exit2(struct proc *); int fork1(struct proc *, int, int, void *, size_t, void (*)(void *), void *, register_t *, struct proc **); diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index c13f02884ba..f31b334d35b 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.86 2005/07/03 20:14:19 drahn Exp $ */ +/* $OpenBSD: syscall.h,v 1.87 2005/12/03 18:09:09 tedu Exp $ */ /* * System call numbers. @@ -670,4 +670,22 @@ /* syscall: "msgctl" ret: "int" args: "int" "int" "struct msqid_ds *" */ #define SYS_msgctl 297 -#define SYS_MAXSYSCALL 298 +/* syscall: "sched_yield" ret: "int" args: */ +#define SYS_sched_yield 298 + +/* syscall: "getthrid" ret: "pid_t" args: */ +#define SYS_getthrid 299 + +/* syscall: "thrsleep" ret: "int" args: "long" "int" "void *" */ +#define SYS_thrsleep 300 + +/* syscall: "thrwakeup" ret: "int" args: "long" */ +#define SYS_thrwakeup 301 + +/* syscall: "threxit" ret: "int" args: "int" */ +#define SYS_threxit 302 + +/* syscall: "thrsigdivert" ret: "int" args: "sigset_t" */ +#define SYS_thrsigdivert 303 + +#define SYS_MAXSYSCALL 304 diff --git a/sys/sys/syscallargs.h b/sys/sys/syscallargs.h index b8519699d95..a76f87c144c 100644 --- a/sys/sys/syscallargs.h +++ b/sys/sys/syscallargs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscallargs.h,v 1.88 2005/07/03 20:14:19 drahn Exp $ */ +/* $OpenBSD: syscallargs.h,v 1.89 2005/12/03 18:09:09 tedu Exp $ */ /* * System call argument lists. @@ -1217,6 +1217,24 @@ struct sys_msgctl_args { syscallarg(struct msqid_ds *) buf; }; +struct sys_thrsleep_args { + syscallarg(long) ident; + syscallarg(int) timeout; + syscallarg(void *) lock; +}; + +struct sys_thrwakeup_args { + syscallarg(long) ident; +}; + +struct sys_threxit_args { + syscallarg(int) rval; +}; + +struct sys_thrsigdivert_args { + syscallarg(sigset_t) sigmask; +}; + /* * System call prototypes. */ @@ -1525,3 +1543,12 @@ int sys_shmctl(struct proc *, void *, register_t *); int sys_msgctl(struct proc *, void *, register_t *); #else #endif +int sys_sched_yield(struct proc *, void *, register_t *); +#ifdef RTHREADS +int sys_getthrid(struct proc *, void *, register_t *); +int sys_thrsleep(struct proc *, void *, register_t *); +int sys_thrwakeup(struct proc *, void *, register_t *); +int sys_threxit(struct proc *, void *, register_t *); +int sys_thrsigdivert(struct proc *, void *, register_t *); +#else +#endif -- cgit v1.2.3