revise sys_thrsleep
0 answers - 4721 bytes -

this is quite a bit simpler, and most importantly fixes a memory leak that
can happen when thrsleep is interrupted (the free only happens in the
thrwakeup syscall). the previous implementation had the advantage in that
it could be converted from linked list to tree fairly easily, but i'd
rather just get it right for now. no userland visible changes.
Index: kern/init_main.c
RCS file: /cvs/src/sys/kern/init_main.c,v
retrieving revision 1.126
diff -u -r1.126 init_main.c
kern/init_main.c3 Dec 2005 18:09:08 -00001.126
kern/init_main.c20 Dec 2005 04:31:50 -0000
@@ -272,7 +272,6 @@
p->p_thrparent = p;
LIST_INIT(&p->p_thrchildren);
-LIST_INIT(&p->p_sleepers);
p->p_flag = P_INMEM | P_SYSTEM | P_NCLDWAIT;
p->p_stat = SNPRC;
Index: kern/kern_fork.c
RCS file: /cvs/src/sys/kern/kern_fork.c,v
retrieving revision 1.80
diff -u -r1.80 kern_fork.c
kern/kern_fork.c4 Dec 2005 21:21:46 -00001.80
kern/kern_fork.c20 Dec 2005 04:31:50 -0000
@@ -294,7 +294,6 @@
}
LIST_INIT(&p2->p_thrchildren);
-LIST_INIT(&p2->p_sleepers);
#ifdef KTRACE
/*
Index: kern/kern_proc.c
RCS file: /cvs/src/sys/kern/kern_proc.c,v
retrieving revision 1.30
diff -u -r1.30 kern_proc.c
kern/kern_proc.c4 Dec 2005 05:49:12 -00001.30
kern/kern_proc.c20 Dec 2005 04:31:51 -0000
@@ -81,10 +81,6 @@
void
procinit(void)
{
-#ifdef RTHREADS
-extern struct pool sleeper_pool;
-#endif
-
LIST_INIT(&allproc);
LIST_INIT(&zombproc);
@@ -107,10 +103,6 @@
&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
}
/*
Index: kern/kern_synch.c
RCS file: /cvs/src/sys/kern/kern_synch.c,v
retrieving revision 1.71
diff -u -r1.71 kern_synch.c
kern/kern_synch.c14 Dec 2005 06:54:38 -00001.71
kern/kern_synch.c20 Dec 2005 04:31:52 -0000
@@ -378,8 +378,6 @@
#ifdef RTHREADS
-struct pool sleeper_pool;
-
int
sys_thrsleep(struct proc *p, void *v, register_t *revtal)
{
@@ -388,23 +386,9 @@
int timo = SCARG(uap, timeout);
_spinlock_lock_t *lock = SCARG(uap, lock);
_spinlock_lock_t unlocked = _SPINLCK_UNLCKED;
-
-struct twaitnode *n, *n2;
int error;
-n = pool_get(&sleeper_pool, PR_WAITK);
-n->t_ident = ident;
-/* we may have slept */
-LIST_FREACH(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);
-}
+p->p_thrslpid = ident;
if (lock)
copyout(&unlocked, lock, sizeof(unlocked));
@@ -414,7 +398,7 @@
timo = timo / (1000 / hz);
if (timo < 0)
timo = 0;
-error = tsleep(n, PUSER | PCATCH, "thrsleep", timo);
+error = tsleep(&p->p_thrslpid, PUSER | PCATCH, "thrsleep", timo);
return (error);
@@ -425,19 +409,23 @@
{
struct sys_thrwakeup_args *uap = v;
long ident = (long)SCARG(uap, ident);
-struct twaitnode *n;
+struct proc *q;
+int found = 0;
-LIST_FREACH(n, &p->p_thrparent->p_sleepers, t_next) {
-if (n->t_ident == ident) {
-LIST_REMVE(n, t_next);
-break;
+/* have to check the parent, it's not in the thread list */
+if (p->p_thrparent->p_thrslpid == ident) {
+wakeup(&p->p_thrparent->p_thrslpid);
+found = 1;
+}
+LIST_FREACH(q, &p->p_thrparent->p_thrchildren, p_thrsib) {
+if (q->p_thrslpid == ident) {
+wakeup(&q->p_thrslpid);
+q->p_thrslpid = 0;
+found = 1;
}
}
-if (!n)
+if (!found)
return (ESRCH);
-wakeup(n);
-pool_put(&sleeper_pool, n);
-yield();
return (0);
}
Index: sys/proc.h
RCS file: /cvs/src/sys/sys/proc.h,v
retrieving revision 1.83
diff -u -r1.83 proc.h
sys/proc.h7 Dec 2005 19:04:50 -00001.83
sys/proc.h20 Dec 2005 04:31:52 -0000
@@ -113,11 +113,6 @@
extern struct emul *emulsw[];/* All emuls in system */
extern int nemuls;/* Number of emuls */
-structtwaitnode {
-long t_ident;
-LIST_ENTRY(twaitnode) t_next;
-};
-
/*
* Description of a process.
*
@@ -170,7 +165,7 @@
structproc *p_thrparent;
LIST_ENTRY(proc) p_thrsib;
LIST_HEAD(, proc) p_thrchildren;
-LIST_HEAD(, twaitnode) p_sleepers;
+long p_thrslpid;/* for thrsleep syscall */
/* scheduling */