summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2005-12-03 18:09:10 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2005-12-03 18:09:10 +0000
commitc70b5cef9cd869b5048eb62edb340396b02e4db0 (patch)
tree0683210c43a51394ea6f6bca3962c42be65f891c /sys
parentb1ebc44477794b7e2189d2bc0b2251eb10230ff4 (diff)
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
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/init_main.c6
-rw-r--r--sys/kern/init_sysent.c27
-rw-r--r--sys/kern/kern_exec.c4
-rw-r--r--sys/kern/kern_exit.c66
-rw-r--r--sys/kern/kern_fork.c16
-rw-r--r--sys/kern/kern_kthread.c4
-rw-r--r--sys/kern/kern_proc.c10
-rw-r--r--sys/kern/kern_prot.c20
-rw-r--r--sys/kern/kern_sig.c30
-rw-r--r--sys/kern/kern_synch.c93
-rw-r--r--sys/kern/syscalls.c16
-rw-r--r--sys/kern/syscalls.master16
-rw-r--r--sys/sys/param.h3
-rw-r--r--sys/sys/proc.h24
-rw-r--r--sys/sys/syscall.h22
-rw-r--r--sys/sys/syscallargs.h29
16 files changed, 356 insertions, 30 deletions
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.
@@ -793,5 +793,30 @@ struct sysent sysent[] = {
{ 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 <uvm/uvm_extern.h>
#include <sys/sched.h>
#include <sys/timeout.h>
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
+#include <sys/pool.h>
+
+#include <machine/spinlock.h>
#ifdef KTRACE
#include <sys/ktrace.h>
@@ -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.
@@ -407,4 +407,18 @@ char *syscallnames[] = {
#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