summaryrefslogtreecommitdiff
path: root/rts/posix/ticker/Setitimer.c
blob: 816d603db3413fbd3d1d119e3f910d2e5acd32b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/* -----------------------------------------------------------------------------
 *
 * (c) The GHC Team, 1995-2007
 *
 * Interval timer for profiling and pre-emptive scheduling.
 *
 * ---------------------------------------------------------------------------*/

#include "rts/PosixSource.h"
#include "Rts.h"

#include "Ticker.h"
#include "Proftimer.h"
#include "Schedule.h"
#include "posix/Clock.h"
#include "posix/Signals.h"

/* As recommended in the autoconf manual */
# if defined(TIME_WITH_SYS_TIME)
#  include <sys/time.h>
#  include <time.h>
# else
#  if defined(HAVE_SYS_TIME_H)
#   include <sys/time.h>
#  else
#   include <time.h>
#  endif
# endif

#if defined(HAVE_SIGNAL_H)
# include <signal.h>
#endif

#include <string.h>

static Time itimer_interval = DEFAULT_TICK_INTERVAL;

void
initTicker (Time interval, TickProc handle_tick)
{
    itimer_interval = interval;
    install_vtalrm_handler(SIGALRM, handle_tick);
}

void
startTicker(void)
{
    struct itimerval it;

    it.it_value.tv_sec = TimeToSeconds(itimer_interval);
    it.it_value.tv_usec = TimeToUS(itimer_interval) % 1000000;
    it.it_interval = it.it_value;

    if (setitimer(ITIMER_REAL, &it, NULL) != 0) {
        sysErrorBelch("setitimer");
        stg_exit(EXIT_FAILURE);
    }
}

void
stopTicker(void)
{
    struct itimerval it;

    it.it_value.tv_sec = 0;
    it.it_value.tv_usec = 0;
    it.it_interval = it.it_value;

    if (setitimer(ITIMER_REAL, &it, NULL) != 0) {
        sysErrorBelch("setitimer");
        stg_exit(EXIT_FAILURE);
    }
}

void
exitTicker (bool wait STG_UNUSED)
{
    return;
}

int
rtsTimerSignal(void)
{
    return SIGALRM;
    // Using SIGALRM can leads to problems, see #850.  But we have no
    // option if timer_create() is not available.
}