aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_time.h
blob: f4e230655dd19d12b60d073f945963d53cb30d69 (plain) (blame)
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
 * %CopyrightBegin%
 * 
 * Copyright Ericsson AB 2006-2009. All Rights Reserved.
 * 
 * The contents of this file are subject to the Erlang Public License,
 * Version 1.1, (the "License"); you may not use this file except in
 * compliance with the License. You should have received a copy of the
 * Erlang Public License along with this software. If not, it can be
 * retrieved online at http://www.erlang.org/.
 * 
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 * 
 * %CopyrightEnd%
 */

#ifndef ERL_TIME_H__
#define ERL_TIME_H__

extern erts_smp_atomic_t do_time;	/* set at clock interrupt */
extern SysTimeval erts_first_emu_time;

/*
** Timer entry:
*/
typedef struct erl_timer {
    struct erl_timer* next;	/* next entry tiw slot or chain */
    Uint slot;			/* slot in timer wheel */
    Uint count;			/* number of loops remaining */
    int    active;		/* 1=activated, 0=deactivated */
    /* called when timeout */
    void (*timeout)(void*);
    /* called when cancel (may be NULL) */
    void (*cancel)(void*);
    void* arg;        /* argument to timeout/cancel procs */
} ErlTimer;

typedef void (*ErlTimeoutProc)(void*);
typedef void (*ErlCancelProc)(void*);

#ifdef ERTS_SMP
/*
 * Process and port timer
 */
typedef union ErtsSmpPTimer_ ErtsSmpPTimer;
union ErtsSmpPTimer_ {
    struct {
	ErlTimer tm;
	Eterm id;
	void (*timeout_func)(void*);
	ErtsSmpPTimer **timer_ref;
	Uint32 flags;
    } timer;
    ErtsSmpPTimer *next;
};


void erts_create_smp_ptimer(ErtsSmpPTimer **timer_ref,
			    Eterm id,
			    ErlTimeoutProc timeout_func,
			    Uint timeout);
void erts_cancel_smp_ptimer(ErtsSmpPTimer *ptimer);
#endif

/* timer-wheel api */

void erts_init_time(void);
void erts_set_timer(ErlTimer*, ErlTimeoutProc, ErlCancelProc, void*, Uint);
void erts_cancel_timer(ErlTimer*);
void erts_bump_timer(erts_aint_t);
Uint erts_timer_wheel_memory_size(void);
Uint erts_time_left(ErlTimer *);
erts_aint_t erts_next_time(void);

#ifdef DEBUG
void erts_p_slpq(void);
#endif

ERTS_GLB_INLINE erts_aint_t erts_do_time_read_and_reset(void);
ERTS_GLB_INLINE void erts_do_time_add(long);

#if ERTS_GLB_INLINE_INCL_FUNC_DEF

ERTS_GLB_INLINE erts_aint_t erts_do_time_read_and_reset(void) { return erts_smp_atomic_xchg(&do_time, 0L); }
ERTS_GLB_INLINE void erts_do_time_add(long elapsed) { erts_smp_atomic_add(&do_time, elapsed); }

#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */


/* time_sup */

#if (defined(HAVE_GETHRVTIME) || defined(HAVE_CLOCK_GETTIME))
#  ifndef HAVE_ERTS_NOW_CPU
#    define HAVE_ERTS_NOW_CPU
#    ifdef HAVE_GETHRVTIME
#      define erts_start_now_cpu() sys_start_hrvtime()
#      define erts_stop_now_cpu()  sys_stop_hrvtime()
#    endif
#  endif
void erts_get_now_cpu(Uint* megasec, Uint* sec, Uint* microsec);
#endif

void erts_get_timeval(SysTimeval *tv);
long erts_get_time(void);
void erts_get_emu_time(SysTimeval *);

ERTS_GLB_INLINE int erts_cmp_timeval(SysTimeval *t1p, SysTimeval *t2p);

#if ERTS_GLB_INLINE_INCL_FUNC_DEF

ERTS_GLB_INLINE int
erts_cmp_timeval(SysTimeval *t1p, SysTimeval *t2p)
{
    if (t1p->tv_sec == t2p->tv_sec) {
	if (t1p->tv_usec < t2p->tv_usec)
	    return -1;
	else if (t1p->tv_usec > t2p->tv_usec)
	    return 1;
	return 0;
    }
    return t1p->tv_sec < t2p->tv_sec ? -1 : 1;
}

#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */
#endif /* ERL_TIME_H__ */