restore input stack types changed by <init> call
[cacao.git] / threads / notyet.c
1 /* ------------------------ thread.c -------------------------- */
2
3 /*
4  * Handle alarm.
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
12  * setitimer call.
13  */
14 static
15 void
16 alarmException(int sig)
17 {
18     thread* tid;
19     int64 time;
20
21     /* Re-enable signal - necessary for SysV */
22     signal(sig, (SIG_T)alarmException);
23
24     /*
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.
28      */
29     if (blockInts > 0) {
30         MALARM(50);
31         return;
32     }
33
34     intsDisable();
35
36     /* Wake all the threads which need waking */
37     time = currentTime();
38     while (alarmList != 0 && alarmList->PrivateInfo->time <= time) {
39         tid = alarmList;
40         alarmList = alarmList->next;
41         iresumeThread(tid);
42     }
43
44     /* Restart alarm */
45     if (alarmList != 0) {
46         MALARM(alarmList->PrivateInfo->time - time);
47     }
48
49     /*
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.
59      */
60     alarmBlocked = true;
61     intsRestore();
62     alarmBlocked = false;
63 }
64
65 /*
66  * How many stack frames have I invoked?
67  */
68 long
69 framesThread(thread* tid)
70 {
71     long count;
72     THREADFRAMES(tid, count);
73     return (count);
74 }