File: timer.h

package info (click to toggle)
keepalived 1%3A2.3.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,928 kB
  • sloc: ansic: 68,122; sh: 1,868; makefile: 770; python: 35; xml: 13
file content (153 lines) | stat: -rw-r--r-- 4,280 bytes parent folder | download | duplicates (3)
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
 * Soft:        Keepalived is a failover program for the LVS project
 *              <www.linuxvirtualserver.org>. It monitor & manipulate
 *              a loadbalanced server pool using multi-layer checks.
 *
 * Part:        timer.c include file.
 *
 * Author:      Alexandre Cassen, <acassen@linux-vs.org>
 *
 *              This program is distributed in the hope that it will be useful,
 *              but WITHOUT ANY WARRANTY; without even the implied warranty of
 *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *              See the GNU General Public License for more details.
 *
 *              This program is free software; you can redistribute it and/or
 *              modify it under the terms of the GNU General Public License
 *              as published by the Free Software Foundation; either version
 *              2 of the License, or (at your option) any later version.
 *
 * Copyright (C) 2001-2017 Alexandre Cassen, <acassen@gmail.com>
 */

#ifndef _TIMER_H
#define _TIMER_H

#include <sys/time.h>
#include <limits.h>
#include <string.h>
#include <stdbool.h>

typedef struct timeval timeval_t;

/* Global vars */
extern timeval_t time_now;

#ifdef _TIMER_CHECK_
extern bool do_timer_check;
#endif

/* Some defines */
#define TIMER_HZ		1000000
#define	TIMER_HZ_DIGITS		6
#define TIMER_HZ_FLOAT		1000000.0F
#define TIMER_HZ_DOUBLE		((double)1000000.0F)
#define TIMER_CENTI_HZ		10000
#define TIMER_MAX_SEC		1000U
#define TIMER_NEVER		ULONG_MAX	/* Used with time intervals in TIMER_HZ units */
#define TIMER_DISABLED		LONG_MIN	/* Value in timeval_t tv_sec */

#define	NSEC_PER_SEC		1000000000	/* nanoseconds per second. Avoids typos by having a definition */

#ifdef _TIMER_CHECK_
#define timer_now()	timer_now_r((__FILE__), (__func__), (__LINE__))
#define set_time_now()	set_time_now_r((__FILE__), (__func__), (__LINE__))
#endif

#define RB_TIMER_CMP(obj, nnn)					\
static inline int						\
obj##_timer_cmp(const timeval_t *sands, const rb_node_t *a)	\
{								\
	const obj##_t *r1 = rb_entry_const(a, obj##_t, nnn);	\
								\
	if (sands->tv_sec == TIMER_DISABLED) {			\
		if (r1->sands.tv_sec == TIMER_DISABLED)		\
			return 0;				\
		return 1;					\
	}							\
								\
	if (r1->sands.tv_sec == TIMER_DISABLED)			\
		return -1;					\
								\
	if (sands->tv_sec != r1->sands.tv_sec)			\
		return sands->tv_sec - r1->sands.tv_sec;	\
								\
	return sands->tv_usec - r1->sands.tv_usec;		\
}

#define RB_TIMER_LESS(obj, nnn)					\
static inline bool						\
obj##_timer_less(rb_node_t *a, const rb_node_t *b)		\
{								\
	const obj##_t *r1 = rb_entry_const(a, obj##_t, nnn);	\
	const obj##_t *r2 = rb_entry_const(b, obj##_t, nnn);	\
								\
	if (r1->sands.tv_sec == TIMER_DISABLED)			\
		return false;					\
								\
	if (r2->sands.tv_sec == TIMER_DISABLED)			\
		return true;					\
								\
	if (r1->sands.tv_sec != r2->sands.tv_sec)		\
		return r1->sands.tv_sec < r2->sands.tv_sec;	\
								\
	return r1->sands.tv_usec < r2->sands.tv_usec;		\
}

/* timer sub from current time */
static inline timeval_t
timer_sub_now(timeval_t a)
{
	timersub(&a, &time_now, &a);

	return a;
}

/* timer add to current time */
static inline timeval_t
timer_add_now(timeval_t a)
{
	timeradd(&time_now, &a, &a);

	return a;
}

/* Returns true if time a + diff_hz < time_now */
static inline bool
timer_cmp_now_diff(timeval_t a, unsigned long diff_hz)
{
	timeval_t b = { .tv_sec = diff_hz / TIMER_HZ, .tv_usec = diff_hz % TIMER_HZ };

	timeradd(&b, &a, &b);

	return !!timercmp(&b, &time_now, <);
}

/* Return time as unsigned long */
static inline unsigned long
timer_long(timeval_t a)
{
	return (unsigned long)a.tv_sec * TIMER_HZ + (unsigned long)a.tv_usec;
}

#ifdef _INCLUDE_UNUSED_CODE_
/* print timer value */
static inline void
timer_dump(timeval_t a)
{
	printf("=> %lu (usecs)\n", timer_tol(a));
}
#endif

/* prototypes */
#ifdef _TIMER_CHECK_
extern timeval_t timer_now_r(const char *, const char *, int);
extern timeval_t set_time_now_r(const char *, const char *, int);
#else
extern timeval_t timer_now(void);
extern timeval_t set_time_now(void);
#endif
extern timeval_t timer_add_long(timeval_t, unsigned long) __attribute__((const));
extern timeval_t timer_sub_long(timeval_t, unsigned long) __attribute__((const));

#endif