Subject: tsleep() in vfs_shutdown (update)
To: None <tech-kern@netbsd.org>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: tech-kern
Date: 08/27/2000 22:21:21
--envbJBWh7q8WU6mo
Content-Type: text/plain; charset=us-ascii
Hi,
attached is an updated patch to allow tsleep() in vfs_shutdown() instead of
delay(). Per Jason's comments, setrunnable() & friends now mark processes
SHOLD instead of SRUN when needed. I also renamed stopsched() to
suspendsched() and added a resumesched(), to put back SHOLD processes in the
run queue.
suspendsched()/resumesched() uses a counter, so that it's possible to call
suspendsched() from different places without special care. I added a new
p_flag, P_HOLD, set for processes which should be set SHOLD rather than
SRUN when they become runnable again.
suspendsched() asserts P_HOLD for all processes but curproc and P_SYSTEM
processes. P_HOLD is tested before marking a process SRUN again (can now
be marked SRUN or SHOLD).
I'm not sure about the semantic resumesched() should have when it's called
but the suspend counter is greather than 1 (that is, more than one process
have suspended the sheduler, see the XXX in the code). For now the current
process will keep running but this may not be rigth. Maybe we should tsleep(),
waiting to the suspend counter to be back to 0 ?
I'm waiting for comments. If I don't hear anything before Thursday, 31 I'll
commit this and ask for a pull up (I want this to be in 1.5_BETA, it's really
important for RAIDframe users).
--
Manuel Bouyer, LIP6, Universite Paris VI. Manuel.Bouyer@lip6.fr
--
--envbJBWh7q8WU6mo
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="diff-1.5"
Index: compat/svr4/svr4_lwp.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/svr4/svr4_lwp.c,v
retrieving revision 1.3
diff -u -r1.3 svr4_lwp.c
--- compat/svr4/svr4_lwp.c 2000/05/28 05:49:05 1.3
+++ compat/svr4/svr4_lwp.c 2000/08/27 19:16:16
@@ -253,7 +253,7 @@
if (!CANSIGNAL(p, p->p_cred, pt, 0))
return EPERM;
- pt->p_stat = SRUN;
+ pt->p_stat = (pt->p_flag & P_HOLD) ? SHOLD : SRUN;
return 0;
}
Index: kern/kern_fork.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_fork.c,v
retrieving revision 1.66.2.1
diff -u -r1.66.2.1 kern_fork.c
--- kern/kern_fork.c 2000/07/04 16:05:34 1.66.2.1
+++ kern/kern_fork.c 2000/08/27 19:16:17
@@ -290,7 +290,7 @@
* Increase reference counts on shared objects.
* The p_stats and p_sigacts substructs are set in vm_fork.
*/
- p2->p_flag = P_INMEM | (p1->p_flag & P_SUGID);
+ p2->p_flag = P_INMEM | (p1->p_flag & (P_SUGID | P_HOLD));
p2->p_emul = p1->p_emul;
if (p1->p_flag & P_PROFIL)
startprofclock(p2);
@@ -382,8 +382,11 @@
s = splstatclock();
p2->p_stats->p_start = time;
p2->p_acflag = AFORK;
- p2->p_stat = SRUN;
- setrunqueue(p2);
+ if ((p2->p_flag & P_HOLD) == 0) {
+ p2->p_stat = SRUN;
+ setrunqueue(p2);
+ } else
+ p2->p_stat = SHOLD;
splx(s);
/*
Index: kern/kern_synch.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_synch.c,v
retrieving revision 1.78.2.2
diff -u -r1.78.2.2 kern_synch.c
--- kern/kern_synch.c 2000/08/11 23:10:15 1.78.2.2
+++ kern/kern_synch.c 2000/08/27 19:16:17
@@ -119,6 +119,8 @@
struct callout roundrobin_ch = CALLOUT_INITIALIZER;
struct callout schedcpu_ch = CALLOUT_INITIALIZER;
+int sched_suspended = 0;
+
/*
* Force switch among equal priority processes every 100ms.
*/
@@ -591,17 +593,20 @@
if (p->p_slptime > 1)
updatepri(p);
p->p_slptime = 0;
- p->p_stat = SRUN;
-
- /*
- * Since curpriority is a user priority, p->p_priority
- * is always better than curpriority.
- */
- if (p->p_flag & P_INMEM) {
- setrunqueue(p);
- need_resched();
- } else
- wakeup(&proc0);
+ if ((p->p_flag & P_HOLD) == 0) {
+ p->p_stat = SRUN;
+ /*
+ * Since curpriority is a user priority, p->p_priority
+ * is always better than curpriority.
+ */
+ if (p->p_flag & P_INMEM) {
+ setrunqueue(p);
+ need_resched();
+ } else
+ wakeup(&proc0);
+ } else {
+ p->p_stat = SHOLD;
+ }
}
/*
@@ -715,8 +720,11 @@
s = splstatclock();
p->p_priority = p->p_usrpri;
- p->p_stat = SRUN;
- setrunqueue(p);
+ if ((p->p_flag & P_HOLD) == 0) {
+ p->p_stat = SRUN;
+ setrunqueue(p);
+ } else
+ p->p_stat = SHOLD;
p->p_stats->p_ru.ru_nvcsw++;
mi_switch(p);
splx(s);
@@ -742,8 +750,11 @@
s = splstatclock();
p->p_priority = p->p_usrpri;
- p->p_stat = SRUN;
- setrunqueue(p);
+ if ((p->p_flag & P_HOLD) == 0) {
+ p->p_stat = SRUN;
+ setrunqueue(p);
+ } else
+ p->p_stat = SHOLD;
p->p_stats->p_ru.ru_nivcsw++;
mi_switch(p);
splx(s);
@@ -862,6 +873,7 @@
switch (p->p_stat) {
case 0:
case SRUN:
+ case SHOLD:
case SONPROC:
case SZOMB:
case SDEAD:
@@ -883,9 +895,12 @@
case SIDL:
break;
}
- p->p_stat = SRUN;
- if (p->p_flag & P_INMEM)
- setrunqueue(p);
+ if ((p->p_flag & P_HOLD) == 0) {
+ p->p_stat = SRUN;
+ if (p->p_flag & P_INMEM)
+ setrunqueue(p);
+ } else
+ p->p_stat = SHOLD;
splx(s);
if (p->p_slptime > 1)
updatepri(p);
@@ -959,4 +974,69 @@
resetpriority(p);
if (p->p_priority >= PUSER)
p->p_priority = p->p_usrpri;
+}
+
+/*
+ * Mark all non-system processes as non-runnable, and remove from run queue.
+ */
+void
+suspendsched()
+{
+ int s, i;
+ struct proc *p, *next;
+ s = splclock();
+
+ sched_suspended++;
+ if (sched_suspended > 1) {
+ /* sheduling was already suspended */
+ splx(s);
+ return;
+ }
+ /* mark P_HOLD all processes that aren't P_SYSTEM or curproc */
+ for (p = LIST_FIRST(&allproc); p != NULL; p = next) {
+ next = LIST_NEXT(p, p_list);
+ if (p == curproc || (p->p_flag & P_SYSTEM) != 0)
+ continue;
+ p->p_flag |= P_HOLD;
+ }
+ /* go through the run queues, remove P_HOLD processes */
+ for (i = 0; i < RUNQUE_NQS; i++) {
+ for (p = (struct proc *)&sched_qs[i];
+ p->p_forw != (struct proc *)&sched_qs[i]; p = next) {
+ next = p->p_forw;
+ if ((p->p_flag & P_HOLD) != 0) {
+ remrunqueue(p);
+ p->p_stat = SHOLD;
+ }
+ }
+ }
+ splx(s);
+}
+
+/* resume scheduling, replace all suspended processes on a run queue */
+void
+resumesched()
+{
+ int s;
+ struct proc *p, *next;
+ s = splclock();
+
+ sched_suspended--;
+ if (sched_suspended < 0)
+ panic("resumesched");
+ if (sched_suspended > 0) {
+ /* someone still wants the sheduling to be suspended */
+ /* XXX should we mark curproc P_HOLD as well ? */
+ splx(s);
+ return;
+ }
+ for (p = LIST_FIRST(&allproc); p != NULL; p = next) {
+ next = LIST_NEXT(p, p_list);
+ p->p_flag &= ~P_HOLD;
+ if (p->p_stat == SHOLD) {
+ p->p_stat = SRUN;
+ setrunqueue(p);
+ }
+ }
+ splx(s);
}
Index: kern/vfs_subr.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/vfs_subr.c,v
retrieving revision 1.128.2.3
diff -u -r1.128.2.3 vfs_subr.c
--- kern/vfs_subr.c 2000/07/20 00:14:40 1.128.2.3
+++ kern/vfs_subr.c 2000/08/27 19:16:17
@@ -88,6 +88,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
+#include <sys/kernel.h>
#include <sys/mount.h>
#include <sys/time.h>
#include <sys/fcntl.h>
@@ -2352,7 +2353,7 @@
vfs_shutdown()
{
struct buf *bp;
- int iter, nbusy, dcount, s;
+ int iter, nbusy, nbusy_prev = 0, dcount, s;
struct proc *p = curproc;
/* XXX we're certainly not running in proc0's context! */
@@ -2361,7 +2362,8 @@
printf("syncing disks... ");
- /* XXX Should suspend scheduling. */
+ /* remove user process from run queue */
+ suspendsched();
(void) spl0();
/* avoid coming back this way again if we panic. */
@@ -2371,7 +2373,7 @@
/* Wait for sync to finish. */
dcount = 10000;
- for (iter = 0; iter < 20; iter++) {
+ for (iter = 0; iter < 20;) {
nbusy = 0;
for (bp = &buf[nbuf]; --bp >= buf; ) {
if ((bp->b_flags & (B_BUSY|B_INVAL|B_READ)) == B_BUSY)
@@ -2398,8 +2400,15 @@
}
if (nbusy == 0)
break;
+ if (nbusy_prev == 0)
+ nbusy_prev = nbusy;
printf("%d ", nbusy);
- DELAY(40000 * iter);
+ tsleep(&nbusy, PRIBIO, "bflush",
+ (iter == 0) ? 1 : hz / 25 * iter);
+ if (nbusy >= nbusy_prev) /* we didn't flush anything */
+ iter++;
+ else
+ nbusy_prev = nbusy;
}
if (nbusy) {
fail:
Index: sys/proc.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/proc.h,v
retrieving revision 1.98.2.1
diff -u -r1.98.2.1 proc.h
--- sys/proc.h 2000/08/11 23:07:41 1.98.2.1
+++ sys/proc.h 2000/08/27 19:16:17
@@ -238,29 +238,31 @@
#define SZOMB 5 /* Awaiting collection by parent. */
#define SDEAD 6 /* Process is almost a zombie. */
#define SONPROC 7 /* Process is currently on a CPU */
+#define SHOLD 8 /* Process is runnable but suspended */
#define P_ZOMBIE(p) ((p)->p_stat == SZOMB || (p)->p_stat == SDEAD)
/* These flags are kept in p_flag. */
-#define P_ADVLOCK 0x00001 /* Process may hold a POSIX advisory lock. */
-#define P_CONTROLT 0x00002 /* Has a controlling terminal. */
-#define P_INMEM 0x00004 /* Loaded into memory. */
-#define P_NOCLDSTOP 0x00008 /* No SIGCHLD when children stop. */
-#define P_PPWAIT 0x00010 /* Parent is waiting for child to exec/exit. */
-#define P_PROFIL 0x00020 /* Has started profiling. */
-#define P_SELECT 0x00040 /* Selecting; wakeup/waiting danger. */
-#define P_SINTR 0x00080 /* Sleep is interruptible. */
-#define P_SUGID 0x00100 /* Had set id privileges since last exec. */
-#define P_SYSTEM 0x00200 /* System proc: no sigs, stats or swapping. */
-#define P_TIMEOUT 0x00400 /* Timing out during sleep. */
-#define P_TRACED 0x00800 /* Debugged process being traced. */
-#define P_WAITED 0x01000 /* Debugging process has waited for child. */
-#define P_WEXIT 0x02000 /* Working on exiting. */
-#define P_EXEC 0x04000 /* Process called exec. */
-#define P_OWEUPC 0x08000 /* Owe process an addupc() call at next ast. */
-#define P_FSTRACE 0x10000 /* Debugger process being traced by procfs */
-#define P_NOCLDWAIT 0x20000 /* No zombies if child dies */
-#define P_32 0x40000 /* 32-bit process -- only used on 64-bit kernels */
+#define P_ADVLOCK 0x000001 /* Process may hold a POSIX advisory lock. */
+#define P_CONTROLT 0x000002 /* Has a controlling terminal. */
+#define P_INMEM 0x000004 /* Loaded into memory. */
+#define P_NOCLDSTOP 0x000008 /* No SIGCHLD when children stop. */
+#define P_PPWAIT 0x000010 /* Parent is waiting for child to exec/exit. */
+#define P_PROFIL 0x000020 /* Has started profiling. */
+#define P_SELECT 0x000040 /* Selecting; wakeup/waiting danger. */
+#define P_SINTR 0x000080 /* Sleep is interruptible. */
+#define P_SUGID 0x000100 /* Had set id privileges since last exec. */
+#define P_SYSTEM 0x000200 /* System proc: no sigs, stats or swapping. */
+#define P_TIMEOUT 0x000400 /* Timing out during sleep. */
+#define P_TRACED 0x000800 /* Debugged process being traced. */
+#define P_WAITED 0x001000 /* Debugging process has waited for child. */
+#define P_WEXIT 0x002000 /* Working on exiting. */
+#define P_EXEC 0x004000 /* Process called exec. */
+#define P_OWEUPC 0x008000 /* Owe process an addupc() call at next ast. */
+#define P_FSTRACE 0x010000 /* Debugger process being traced by procfs */
+#define P_NOCLDWAIT 0x020000 /* No zombies if child dies */
+#define P_32 0x040000 /* 32-bit process -- only used on 64-bit kernels */
+#define P_HOLD 0x100000 /* process scheduling is suspended */
/*
* Macro to compute the exit signal to be delivered.
@@ -386,6 +388,8 @@
void resetpriority __P((struct proc *));
void setrunnable __P((struct proc *));
void setrunqueue __P((struct proc *));
+void suspendsched __P((void));
+void resumesched __P((void));
int ltsleep __P((void *chan, int pri, const char *wmesg, int timo,
__volatile struct simplelock *));
void unsleep __P((struct proc *));
--envbJBWh7q8WU6mo
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff-current
Index: compat/svr4/svr4_lwp.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/svr4/svr4_lwp.c,v
retrieving revision 1.3
diff -u -r1.3 svr4_lwp.c
--- compat/svr4/svr4_lwp.c 2000/05/28 05:49:05 1.3
+++ compat/svr4/svr4_lwp.c 2000/08/27 20:04:40
@@ -253,7 +253,7 @@
if (!CANSIGNAL(p, p->p_cred, pt, 0))
return EPERM;
- pt->p_stat = SRUN;
+ pt->p_stat = (pt->p_flag & P_HOLD) ? SHOLD : SRUN;
return 0;
}
Index: kern/kern_fork.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_fork.c,v
retrieving revision 1.72
diff -u -r1.72 kern_fork.c
--- kern/kern_fork.c 2000/08/25 02:55:49 1.72
+++ kern/kern_fork.c 2000/08/27 20:04:40
@@ -276,7 +276,7 @@
* Increase reference counts on shared objects.
* The p_stats and p_sigacts substructs are set in vm_fork.
*/
- p2->p_flag = P_INMEM | (p1->p_flag & P_SUGID);
+ p2->p_flag = P_INMEM | (p1->p_flag & (P_SUGID | P_HOLD));
p2->p_emul = p1->p_emul;
if (p1->p_flag & P_PROFIL)
startprofclock(p2);
@@ -368,8 +368,11 @@
s = splstatclock();
p2->p_stats->p_start = time;
p2->p_acflag = AFORK;
- p2->p_stat = SRUN;
- setrunqueue(p2);
+ if ((p2->p_flag & P_HOLD) == 0) {
+ p2->p_stat = SRUN;
+ setrunqueue(p2);
+ } else
+ p2->p_stat = SHOLD;
splx(s);
/*
Index: kern/kern_synch.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_synch.c,v
retrieving revision 1.90
diff -u -r1.90 kern_synch.c
--- kern/kern_synch.c 2000/08/26 19:26:43 1.90
+++ kern/kern_synch.c 2000/08/27 20:04:40
@@ -123,6 +123,8 @@
struct callout schedcpu_ch = CALLOUT_INITIALIZER;
+int sched_suspended = 0;
+
/*
* Force switch among equal priority processes every 100ms.
* Called from hardclock every hz/10 == rrticks hardclock ticks.
@@ -570,18 +572,21 @@
if (p->p_slptime > 1)
updatepri(p);
p->p_slptime = 0;
- p->p_stat = SRUN;
-
- /*
- * Since curpriority is a user priority, p->p_priority
- * is always better than curpriority.
- */
- if (p->p_flag & P_INMEM) {
- setrunqueue(p);
- KASSERT(p->p_cpu != NULL);
- need_resched(p->p_cpu);
- } else
- sched_wakeup(&proc0);
+ if ((p->p_flag & P_HOLD) == 0) {
+ p->p_stat = SRUN;
+ /*
+ * Since curpriority is a user priority, p->p_priority
+ * is always better than curpriority.
+ */
+ if (p->p_flag & P_INMEM) {
+ setrunqueue(p);
+ KASSERT(p->p_cpu != NULL);
+ need_resched(p->p_cpu);
+ } else
+ wakeup(&proc0);
+ } else {
+ p->p_stat = SHOLD;
+ }
}
#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
@@ -722,8 +727,11 @@
SCHED_LOCK(s);
p->p_priority = p->p_usrpri;
- p->p_stat = SRUN;
- setrunqueue(p);
+ if ((p->p_flag & P_HOLD) == 0) {
+ p->p_stat = SRUN;
+ setrunqueue(p);
+ } else
+ p->p_stat = SHOLD;
p->p_stats->p_ru.ru_nvcsw++;
mi_switch(p);
SCHED_ASSERT_UNLOCKED();
@@ -750,8 +758,11 @@
SCHED_LOCK(s);
p->p_priority = p->p_usrpri;
- p->p_stat = SRUN;
- setrunqueue(p);
+ if ((p->p_flag & P_HOLD) == 0) {
+ p->p_stat = SRUN;
+ setrunqueue(p);
+ } else
+ p->p_stat = SHOLD;
p->p_stats->p_ru.ru_nivcsw++;
mi_switch(p);
SCHED_ASSERT_UNLOCKED();
@@ -903,6 +914,7 @@
switch (p->p_stat) {
case 0:
case SRUN:
+ case SHOLD:
case SONPROC:
case SZOMB:
case SDEAD:
@@ -924,10 +936,12 @@
case SIDL:
break;
}
- p->p_stat = SRUN;
- if (p->p_flag & P_INMEM)
- setrunqueue(p);
-
+ if ((p->p_flag & P_HOLD) == 0) {
+ p->p_stat = SRUN;
+ if (p->p_flag & P_INMEM)
+ setrunqueue(p);
+ } else
+ p->p_stat = SHOLD;
if (p->p_slptime > 1)
updatepri(p);
p->p_slptime = 0;
@@ -998,4 +1012,69 @@
if (p->p_priority >= PUSER)
p->p_priority = p->p_usrpri;
+}
+
+/*
+ * Mark all non-system processes as non-runnable, and remove from run queue.
+ */
+void
+suspendsched()
+{
+ int s, i;
+ struct proc *p, *next;
+
+ SCHED_LOCK(s);
+ sched_suspended++;
+ if (sched_suspended > 1) {
+ /* sheduling was already suspended */
+ SCHED_UNLOCK(s);
+ return;
+ }
+ /* mark P_HOLD all processes that aren't P_SYSTEM or curproc */
+ for (p = LIST_FIRST(&allproc); p != NULL; p = next) {
+ next = LIST_NEXT(p, p_list);
+ if (p == curproc || (p->p_flag & P_SYSTEM) != 0)
+ continue;
+ p->p_flag |= P_HOLD;
+ }
+ /* go through the run queues, remove P_HOLD processes */
+ for (i = 0; i < RUNQUE_NQS; i++) {
+ for (p = (struct proc *)&sched_qs[i];
+ p->p_forw != (struct proc *)&sched_qs[i]; p = next) {
+ next = p->p_forw;
+ if ((p->p_flag & P_HOLD) != 0) {
+ remrunqueue(p);
+ p->p_stat = SHOLD;
+ }
+ }
+ }
+ SCHED_UNLOCK(s);
+}
+
+/* resume scheduling, replace all suspended processes on a run queue */
+void
+resumesched()
+{
+ int s;
+ struct proc *p, *next;
+
+ SCHED_LOCK(s);
+ sched_suspended--;
+ if (sched_suspended < 0)
+ panic("resumesched");
+ if (sched_suspended > 0) {
+ /* someone still wants the sheduling to be suspended */
+ /* XXX should we mark curproc P_HOLD as well ? */
+ SCHED_UNLOCK(s);
+ return;
+ }
+ for (p = LIST_FIRST(&allproc); p != NULL; p = next) {
+ next = LIST_NEXT(p, p_list);
+ p->p_flag &= ~P_HOLD;
+ if (p->p_stat == SHOLD) {
+ p->p_stat = SRUN;
+ setrunqueue(p);
+ }
+ }
+ SCHED_UNLOCK(s);
}
Index: kern/vfs_subr.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/vfs_subr.c,v
retrieving revision 1.137
diff -u -r1.137 vfs_subr.c
--- kern/vfs_subr.c 2000/08/21 06:42:57 1.137
+++ kern/vfs_subr.c 2000/08/27 20:04:42
@@ -88,6 +88,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
+#include <sys/kernel.h>
#include <sys/mount.h>
#include <sys/time.h>
#include <sys/fcntl.h>
@@ -2347,7 +2348,7 @@
vfs_shutdown()
{
struct buf *bp;
- int iter, nbusy, dcount, s;
+ int iter, nbusy, nbusy_prev = 0, dcount, s;
struct proc *p = curproc;
/* XXX we're certainly not running in proc0's context! */
@@ -2356,7 +2357,8 @@
printf("syncing disks... ");
- /* XXX Should suspend scheduling. */
+ /* remove user process from run queue */
+ suspendsched();
(void) spl0();
/* avoid coming back this way again if we panic. */
@@ -2366,7 +2368,7 @@
/* Wait for sync to finish. */
dcount = 10000;
- for (iter = 0; iter < 20; iter++) {
+ for (iter = 0; iter < 20;) {
nbusy = 0;
for (bp = &buf[nbuf]; --bp >= buf; ) {
if ((bp->b_flags & (B_BUSY|B_INVAL|B_READ)) == B_BUSY)
@@ -2393,8 +2395,15 @@
}
if (nbusy == 0)
break;
+ if (nbusy_prev == 0)
+ nbusy_prev = nbusy;
printf("%d ", nbusy);
- DELAY(40000 * iter);
+ tsleep(&nbusy, PRIBIO, "bflush",
+ (iter == 0) ? 1 : hz / 25 * iter);
+ if (nbusy >= nbusy_prev) /* we didn't flush anything */
+ iter++;
+ else
+ nbusy_prev = nbusy;
}
if (nbusy) {
fail:
Index: sys/proc.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/proc.h,v
retrieving revision 1.102
diff -u -r1.102 proc.h
--- sys/proc.h 2000/08/22 17:28:29 1.102
+++ sys/proc.h 2000/08/27 20:04:42
@@ -238,30 +238,32 @@
#define SZOMB 5 /* Awaiting collection by parent. */
#define SDEAD 6 /* Process is almost a zombie. */
#define SONPROC 7 /* Process is currently on a CPU */
+#define SHOLD 8 /* Process is runnable but suspended */
#define P_ZOMBIE(p) ((p)->p_stat == SZOMB || (p)->p_stat == SDEAD)
/* These flags are kept in p_flag. */
-#define P_ADVLOCK 0x00001 /* Process may hold a POSIX advisory lock. */
-#define P_CONTROLT 0x00002 /* Has a controlling terminal. */
-#define P_INMEM 0x00004 /* Loaded into memory. */
-#define P_NOCLDSTOP 0x00008 /* No SIGCHLD when children stop. */
-#define P_PPWAIT 0x00010 /* Parent is waiting for child to exec/exit. */
-#define P_PROFIL 0x00020 /* Has started profiling. */
-#define P_SELECT 0x00040 /* Selecting; wakeup/waiting danger. */
-#define P_SINTR 0x00080 /* Sleep is interruptible. */
-#define P_SUGID 0x00100 /* Had set id privileges since last exec. */
-#define P_SYSTEM 0x00200 /* System proc: no sigs, stats or swapping. */
-#define P_TIMEOUT 0x00400 /* Timing out during sleep. */
-#define P_TRACED 0x00800 /* Debugged process being traced. */
-#define P_WAITED 0x01000 /* Debugging process has waited for child. */
-#define P_WEXIT 0x02000 /* Working on exiting. */
-#define P_EXEC 0x04000 /* Process called exec. */
-#define P_OWEUPC 0x08000 /* Owe process an addupc() call at next ast. */
-#define P_FSTRACE 0x10000 /* Debugger process being traced by procfs */
-#define P_NOCLDWAIT 0x20000 /* No zombies if child dies */
-#define P_32 0x40000 /* 32-bit process (used on 64-bit kernels) */
-#define P_BIGLOCK 0x80000 /* Process needs kernel "big lock" to run */
+#define P_ADVLOCK 0x000001 /* Process may hold a POSIX advisory lock. */
+#define P_CONTROLT 0x000002 /* Has a controlling terminal. */
+#define P_INMEM 0x000004 /* Loaded into memory. */
+#define P_NOCLDSTOP 0x000008 /* No SIGCHLD when children stop. */
+#define P_PPWAIT 0x000010 /* Parent is waiting for child to exec/exit. */
+#define P_PROFIL 0x000020 /* Has started profiling. */
+#define P_SELECT 0x000040 /* Selecting; wakeup/waiting danger. */
+#define P_SINTR 0x000080 /* Sleep is interruptible. */
+#define P_SUGID 0x000100 /* Had set id privileges since last exec. */
+#define P_SYSTEM 0x000200 /* System proc: no sigs, stats or swapping. */
+#define P_TIMEOUT 0x000400 /* Timing out during sleep. */
+#define P_TRACED 0x000800 /* Debugged process being traced. */
+#define P_WAITED 0x001000 /* Debugging process has waited for child. */
+#define P_WEXIT 0x002000 /* Working on exiting. */
+#define P_EXEC 0x004000 /* Process called exec. */
+#define P_OWEUPC 0x008000 /* Owe process an addupc() call at next ast. */
+#define P_FSTRACE 0x010000 /* Debugger process being traced by procfs */
+#define P_NOCLDWAIT 0x020000 /* No zombies if child dies */
+#define P_32 0x040000 /* 32-bit process (used on 64-bit kernels) */
+#define P_BIGLOCK 0x080000 /* Process needs kernel "big lock" to run */
+#define P_HOLD 0x100000 /* process scheduling is suspended */
/*
@@ -388,6 +390,8 @@
void resetpriority __P((struct proc *));
void setrunnable __P((struct proc *));
void setrunqueue __P((struct proc *));
+void suspendsched __P((void));
+void resumesched __P((void));
int ltsleep __P((void *chan, int pri, const char *wmesg, int timo,
__volatile struct simplelock *));
void unsleep __P((struct proc *));
--envbJBWh7q8WU6mo--