Make empth_wakeup() and empth_terminate() wake up empth_sleep(), and

empth_sleep() return whether that happened:
[EMPTH_LWP] (lwpWakeupSleep): New, factored out of lwpSelect().
[EMPTH_LWP] (lwpSelect): Use it.
[EMPTH_LWP] (lwpWakeup): New.  Call lwpWakeupFd() if sleeping in
lwpSleepFd(), lwpWakeupSleep() if sleeping in lwpSleepUntil().
[EMPTH_LWP] (lwpTerminate, empth_wakeup): Use it rather than
lwpWakeupFd().
[EMPTH_LWP] (lwpWakeupFd): Internal linkage.
[EMPTH_LWP] (lwpSleepUntil): Reset member runtime, so that lwpWakeup()
can test it reliably.  Return how sleep woke up.
[EMPTH_LWP] (empth_sleep): Return value of lwpSleepUntil().
[EMPTH_POSIX] (EMPTH_INTR): New.
[EMPTH_POSIX] (empth_wakeup): Set state to it.
[EMPTH_POSIX] (empth_restorectx): Clear state.
[EMPTH_POSIX] (empth_sleep): Don't re-seleep when state is not clear,
i.e. thread was woken up prematurely.  Return how sleep woke up.
[EMPTH_W32] (empth_sleep): Implement by waiting on hThreadEvent with a
timeout rather than a straight Sleep().  Return how sleep woke up.
This commit is contained in:
Markus Armbruster 2007-02-08 11:26:43 +00:00
parent fe2de3d743
commit cea39829af
7 changed files with 80 additions and 45 deletions

View file

@ -30,6 +30,7 @@
*
* Known contributors to this file:
* Dave Pare, 1994
* Markus Armbruster, 2007
*/
#include <config.h>
@ -107,7 +108,7 @@ lwpSleepFd(int fd, int mask)
lwpReschedule();
}
void
static void
lwpWakeupFd(struct lwpProc *proc)
{
if (proc->fd < 0)
@ -122,9 +123,44 @@ lwpWakeupFd(struct lwpProc *proc)
lwpReady(proc);
}
static void
lwpWakeupSleep(void)
{
time_t now;
struct lwpQueue save;
struct lwpProc *proc;
if (LwpDelayq.head) {
now = time(NULL);
save.tail = save.head = 0;
while (NULL != (proc = lwpGetFirst(&LwpDelayq))) {
if (now >= proc->runtime) {
lwpStatus(proc, "sleep done");
lwpReady(proc);
} else {
lwpAddTail(&save, proc);
}
}
LwpDelayq = save;
}
}
void
lwpWakeup(struct lwpProc *proc)
{
if (proc->fd >= 0)
lwpWakeupFd(proc);
else if (proc->runtime != (time_t)-1) {
proc->runtime = 0;
lwpWakeupSleep();
}
}
int
lwpSleepUntil(time_t until)
{
int res;
lwpStatus(LwpCurrent, "sleeping for %ld sec",
(long)(until - time(NULL)));
LwpCurrent->runtime = until;
@ -134,6 +170,9 @@ lwpSleepUntil(time_t until)
}
lwpAddTail(&LwpDelayq, LwpCurrent);
lwpReschedule();
res = LwpCurrent->runtime ? 0 : -1;
LwpCurrent->runtime = (time_t)-1;
return res;
}
/*ARGSUSED*/
@ -149,7 +188,6 @@ lwpSelect(void *arg)
time_t delta;
struct lwpProc *proc;
struct timeval tv;
struct lwpQueue save;
lwpStatus(us, "starting select loop");
FD_ZERO(&readmask);
@ -194,20 +232,7 @@ lwpSelect(void *arg)
continue;
}
if (LwpDelayq.head) {
/* sleeping proecss activity */
time(&now);
save.tail = save.head = 0;
while (NULL != (proc = lwpGetFirst(&LwpDelayq))) {
if (now >= proc->runtime) {
lwpStatus(proc, "sleep done");
lwpReady(proc);
} else {
lwpAddTail(&save, proc);
}
}
LwpDelayq = save;
}
lwpWakeupSleep();
if (n > 0) {
/* file descriptor activity */
for (fd = 0; fd <= LwpMaxfd; fd++) {