a4fb2b5b585bb5810940666f22dcef09e6fb2649
[ghc.git] / rts / posix / itimer / TimerCreate.c
1 /* -----------------------------------------------------------------------------
2 *
3 * (c) The GHC Team, 1995-2007
4 *
5 * Interval timer for profiling and pre-emptive scheduling.
6 *
7 * ---------------------------------------------------------------------------*/
8
9 #include "PosixSource.h"
10 #include "Rts.h"
11
12 #include "Ticker.h"
13 #include "posix/Itimer.h"
14 #include "Proftimer.h"
15 #include "Schedule.h"
16 #include "posix/Clock.h"
17 #include "posix/Signals.h"
18
19 #ifdef HAVE_SIGNAL_H
20 # include <signal.h>
21 #endif
22
23 #include <string.h>
24
25 static Time itimer_interval = DEFAULT_TICK_INTERVAL;
26 static timer_t timer;
27
28 void
29 initTicker (Time interval, TickProc handle_tick)
30 {
31 itimer_interval = interval;
32
33 struct sigevent ev;
34
35 // Keep programs like valgrind happy
36 memset(&ev, 0, sizeof(ev));
37
38 ev.sigev_notify = SIGEV_SIGNAL;
39 ev.sigev_signo = SIGVTALRM;
40
41 if (timer_create(CLOCK_ID, &ev, &timer) != 0) {
42 sysErrorBelch("timer_create");
43 stg_exit(EXIT_FAILURE);
44 }
45
46 install_vtalrm_handler(SIGVTALRM, handle_tick);
47 }
48
49 void
50 startTicker(void)
51 {
52 struct itimerspec it;
53
54 it.it_value.tv_sec = TimeToSeconds(itimer_interval);
55 it.it_value.tv_nsec = TimeToNS(itimer_interval) % 1000000000;
56 it.it_interval = it.it_value;
57
58 if (timer_settime(timer, 0, &it, NULL) != 0) {
59 sysErrorBelch("timer_settime");
60 stg_exit(EXIT_FAILURE);
61 }
62 }
63
64 void
65 stopTicker(void)
66 {
67 struct itimerspec it;
68
69 it.it_value.tv_sec = 0;
70 it.it_value.tv_nsec = 0;
71 it.it_interval = it.it_value;
72
73 if (timer_settime(timer, 0, &it, NULL) != 0) {
74 sysErrorBelch("timer_settime");
75 stg_exit(EXIT_FAILURE);
76 }
77 }
78
79 void
80 exitTicker (rtsBool wait STG_UNUSED)
81 {
82 // Before deleting the timer set the signal to ignore to avoid the
83 // possibility of the signal being delivered after the timer is deleted.
84 signal(SIGVTALRM, SIG_IGN);
85 timer_delete(timer);
86 // ignore errors - we don't really care if it fails.
87 }
88
89 int
90 rtsTimerSignal(void)
91 {
92 return SIGVTALRM;
93 }