1 /* ------------------------ thread.c -------------------------- */
5 * This routine uses a different meaning of "blockInts". Formerly, it was just
6 * "don't reschedule if you don't have to". Now it is "don't do ANY
7 * rescheduling actions due to an expired timer". An alternative would be to
8 * block SIGALARM during critical sections (by means of sigprocmask). But
9 * this would be required quite often (for every outmost intsDisable(),
10 * intsRestore()) and therefore would be much more expensive than just
11 * setting an int flag which - sometimes - might cause an additional
16 alarmException(int sig)
21 /* Re-enable signal - necessary for SysV */
22 signal(sig, (SIG_T)alarmException);
25 * If ints are blocked, this might indicate an inconsistent state of
26 * one of the thread queues (either alarmList or threadQhead/tail).
27 * We better don't touch one of them in this case and come back later.
36 /* Wake all the threads which need waking */
38 while (alarmList != 0 && alarmList->PrivateInfo->time <= time) {
40 alarmList = alarmList->next;
46 MALARM(alarmList->PrivateInfo->time - time);
50 * The next bit is rather tricky. If we don't reschedule then things
51 * are fine, we exit this handler and everything continues correctly.
52 * On the otherhand, if we do reschedule, we will schedule the new
53 * thread with alarms blocked which is wrong. However, we cannot
54 * unblock them here incase we have just set an alarm which goes
55 * off before the reschedule takes place (and we enter this routine
56 * recusively which isn't good). So, we set a flag indicating alarms
57 * are blocked, and allow the rescheduler to unblock the alarm signal
58 * after the context switch has been made. At this point it's safe.
66 * How many stack frames have I invoked?
69 framesThread(thread* tid)
72 THREADFRAMES(tid, count);