1 /* ------------------------ thread.c -------------------------- */
4 * Put a thread to sleep.
7 sleepThread(int64 time)
11 /* Sleep for no time */
18 /* Get absolute time */
19 currentThread->PrivateInfo->time = time + currentTime();
21 /* Find place in alarm list */
22 for (tidp = &alarmList; (*tidp) != 0; tidp = &(*tidp)->next) {
23 if ((*tidp)->PrivateInfo->time > currentThread->PrivateInfo->time) {
28 /* If I'm head of alarm list, restart alarm */
29 if (tidp == &alarmList) {
33 /* Suspend thread on it */
34 suspendOnQThread(currentThread, tidp);
41 * This routine uses a different meaning of "blockInts". Formerly, it was just
42 * "don't reschedule if you don't have to". Now it is "don't do ANY
43 * rescheduling actions due to an expired timer". An alternative would be to
44 * block SIGALARM during critical sections (by means of sigprocmask). But
45 * this would be required quite often (for every outmost intsDisable(),
46 * intsRestore()) and therefore would be much more expensive than just
47 * setting an int flag which - sometimes - might cause an additional
52 alarmException(int sig)
57 /* Re-enable signal - necessary for SysV */
58 signal(sig, (SIG_T)alarmException);
61 * If ints are blocked, this might indicate an inconsistent state of
62 * one of the thread queues (either alarmList or threadQhead/tail).
63 * We better don't touch one of them in this case and come back later.
72 /* Wake all the threads which need waking */
74 while (alarmList != 0 && alarmList->PrivateInfo->time <= time) {
76 alarmList = alarmList->next;
82 MALARM(alarmList->PrivateInfo->time - time);
86 * The next bit is rather tricky. If we don't reschedule then things
87 * are fine, we exit this handler and everything continues correctly.
88 * On the otherhand, if we do reschedule, we will schedule the new
89 * thread with alarms blocked which is wrong. However, we cannot
90 * unblock them here incase we have just set an alarm which goes
91 * off before the reschedule takes place (and we enter this routine
92 * recusively which isn't good). So, we set a flag indicating alarms
93 * are blocked, and allow the rescheduler to unblock the alarm signal
94 * after the context switch has been made. At this point it's safe.
102 * How many stack frames have I invoked?
105 framesThread(thread* tid)
108 THREADFRAMES(tid, count);