#define P_STOPPED 4 /* Sleeping, don't wake up for signal */
#define P_FORKING 5 /* In process of forking; do not mess with */
#define P_ZOMBIE 6 /* Exited. */
+#define P_NOSLEEP 7 /* In an internal state where sleep is forbidden */
/* 0 is used to mean 'check we could signal this process' */
* event equal to the process's own ptab address is a wait().
*/
+
void psleep(void *event)
{
irqflags_t irq = di();
#ifdef DEBUG
kprintf("psleep(0x%p)", event);
#endif
-
switch (udata.u_ptab->p_status) {
case P_SLEEP: // echo output from devtty happens while processes are still sleeping but in-context
case P_STOPPED: // coming to a halt
return 1;
}
-static uint8_t in_execve;
-
arg_t _execve(void)
{
staticfast inoptr ino;
goto nogood2;
}
- /* We can't allow multiple execs to occur beyond this point at once
- otherwise we may deadlock out of buffers. As we already assume
- synchronous block I/O on 8bit boxes this isn't really a hit at all */
- while(in_execve)
- psleep(&in_execve);
- in_execve = 1;
-
+ udata.u_ptab->p_status = P_NOSLEEP;
/* Gather the arguments, and put them in temporary buffers. */
abuf = (struct s_argblk *) tmpbuf();
/* Put environment in another buffer. */
udata.u_isp = nenvp - 2;
// Start execution (never returns)
- in_execve = 0;
- wakeup(&in_execve);
+ udata.u_ptab->p_status = P_RUNNING;
doexec(progload);
// tidy up in various failure modes:
nogood3:
+ udata.u_ptab->p_status = P_RUNNING;
brelse(abuf);
brelse(ebuf);
- in_execve = 0;
- wakeup(&in_execve);
- nogood2:
+nogood2:
brelse(buf);
- nogood:
+nogood:
i_deref(ino);
return (-1);
}