blob: fce30c080e49e1cdd26e7ea89cbca9e62cb6d928 [file] [log] [blame]
Everton Marques871dbcf2009-08-11 15:43:05 -03001/*
2 PIM for Quagga
3 Copyright (C) 2008 Everton da Silva Marques
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; see the file COPYING; if not, write to the
17 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
18 MA 02110-1301 USA
19
20 $QuaggaId: $Format:%an, %ai, %h$ $
21*/
22
23#include <string.h>
24#include <sys/time.h>
25#include <time.h>
26
27#include <zebra.h>
28#include "log.h"
29#include "thread.h"
30
31#include "pim_time.h"
32
Everton Marques3de4ae92014-02-13 14:28:26 -020033#ifndef PIM_GETTIME_USE_GETTIMEOFDAY
Everton Marques0ef36d82010-03-11 14:47:42 -030034static int pim_gettime(int clk_id, struct timeval *tv)
Everton Marques871dbcf2009-08-11 15:43:05 -030035{
Everton Marques0ef36d82010-03-11 14:47:42 -030036 struct timespec ts;
Everton Marquesf9e05e52010-03-11 11:17:33 -030037 int result;
38
Everton Marques0ef36d82010-03-11 14:47:42 -030039#ifdef PIM_USE_QUAGGA_GETTIME
40 result = quagga_gettime(clk_id, tv);
Everton Marquesf9e05e52010-03-11 11:17:33 -030041 if (result) {
Everton Marques0ef36d82010-03-11 14:47:42 -030042 zlog_err("%s: quagga_gettime(clk_id=%d) failure: errno=%d: %s",
43 __PRETTY_FUNCTION__, clk_id,
Everton Marquesf9e05e52010-03-11 11:17:33 -030044 errno, safe_strerror(errno));
45 }
Everton Marques0ef36d82010-03-11 14:47:42 -030046#else
47 result = clock_gettime(clk_id, &ts);
48 if (result) {
49 zlog_err("%s: clock_gettime(clk_id=%d) failure: errno=%d: %s",
50 __PRETTY_FUNCTION__, clk_id,
51 errno, safe_strerror(errno));
52 return result;
53 }
54 if (tv) {
55 tv->tv_sec = ts.tv_sec;
56 tv->tv_usec = 1000 * ts.tv_nsec;
57 }
58#endif
Everton Marquesf9e05e52010-03-11 11:17:33 -030059
60 return result;
61}
David Lamparter105ad862012-02-16 04:50:35 +000062#endif
Everton Marquesf9e05e52010-03-11 11:17:33 -030063
64static int gettime_monotonic(struct timeval *tv)
65{
66 int result;
67
Everton Marques0ef36d82010-03-11 14:47:42 -030068#ifdef PIM_GETTIME_USE_GETTIMEOFDAY
69 result = gettimeofday(tv, 0);
70 if (result) {
71 zlog_err("%s: gettimeofday() failure: errno=%d: %s",
72 __PRETTY_FUNCTION__,
73 errno, safe_strerror(errno));
74 }
75#elif defined(PIM_USE_QUAGGA_GETTIME)
Everton Marquesf9e05e52010-03-11 11:17:33 -030076 result = pim_gettime(QUAGGA_CLK_MONOTONIC, tv);
77 if (result) {
78 zlog_err("%s: pim_gettime(QUAGGA_CLK_MONOTONIC=%d) failure: errno=%d: %s",
Everton Marques0ef36d82010-03-11 14:47:42 -030079 __PRETTY_FUNCTION__, QUAGGA_CLK_MONOTONIC,
80 errno, safe_strerror(errno));
81 }
82#else
83 result = pim_gettime(CLOCK_MONOTONIC, tv);
84 if (result) {
85 zlog_err("%s: pim_gettime(CLOCK_MONOTONIC=%d) failure: errno=%d: %s",
Everton Marquesf9e05e52010-03-11 11:17:33 -030086 __PRETTY_FUNCTION__, CLOCK_MONOTONIC,
87 errno, safe_strerror(errno));
88 }
Everton Marques0ef36d82010-03-11 14:47:42 -030089#endif
Everton Marquesf9e05e52010-03-11 11:17:33 -030090
91 return result;
Everton Marques871dbcf2009-08-11 15:43:05 -030092}
93
94/*
95 pim_time_monotonic_sec():
96 number of seconds since some unspecified starting point
97*/
98int64_t pim_time_monotonic_sec()
99{
100 struct timeval now_tv;
101
Everton Marquesf9e05e52010-03-11 11:17:33 -0300102 if (gettime_monotonic(&now_tv)) {
103 zlog_err("%s: gettime_monotonic() failure: errno=%d: %s",
Everton Marques871dbcf2009-08-11 15:43:05 -0300104 __PRETTY_FUNCTION__,
Everton Marquese96f0af2009-08-11 15:48:02 -0300105 errno, safe_strerror(errno));
Everton Marques871dbcf2009-08-11 15:43:05 -0300106 return -1;
107 }
108
109 return now_tv.tv_sec;
110}
111
112/*
113 pim_time_monotonic_dsec():
114 number of deciseconds since some unspecified starting point
115*/
116int64_t pim_time_monotonic_dsec()
117{
118 struct timeval now_tv;
119 int64_t now_dsec;
120
Everton Marquesf9e05e52010-03-11 11:17:33 -0300121 if (gettime_monotonic(&now_tv)) {
122 zlog_err("%s: gettime_monotonic() failure: errno=%d: %s",
Everton Marques871dbcf2009-08-11 15:43:05 -0300123 __PRETTY_FUNCTION__,
Everton Marquese96f0af2009-08-11 15:48:02 -0300124 errno, safe_strerror(errno));
Everton Marques871dbcf2009-08-11 15:43:05 -0300125 return -1;
126 }
127
128 now_dsec = ((int64_t) now_tv.tv_sec) * 10 + ((int64_t) now_tv.tv_usec) / 100000;
129
130 return now_dsec;
131}
132
133int pim_time_mmss(char *buf, int buf_size, long sec)
134{
135 long mm;
136 int wr;
137
138 zassert(buf_size >= 5);
139
140 mm = sec / 60;
141 sec %= 60;
142
143 wr = snprintf(buf, buf_size, "%02ld:%02ld", mm, sec);
144
145 return wr != 8;
146}
147
148static int pim_time_hhmmss(char *buf, int buf_size, long sec)
149{
150 long hh;
151 long mm;
152 int wr;
153
154 zassert(buf_size >= 8);
155
156 hh = sec / 3600;
157 sec %= 3600;
158 mm = sec / 60;
159 sec %= 60;
160
161 wr = snprintf(buf, buf_size, "%02ld:%02ld:%02ld", hh, mm, sec);
162
163 return wr != 8;
164}
165
166void pim_time_timer_to_mmss(char *buf, int buf_size, struct thread *t_timer)
167{
168 if (t_timer) {
169 pim_time_mmss(buf, buf_size,
170 thread_timer_remain_second(t_timer));
171 }
172 else {
173 snprintf(buf, buf_size, "--:--");
174 }
175}
176
177void pim_time_timer_to_hhmmss(char *buf, int buf_size, struct thread *t_timer)
178{
179 if (t_timer) {
180 pim_time_hhmmss(buf, buf_size,
181 thread_timer_remain_second(t_timer));
182 }
183 else {
184 snprintf(buf, buf_size, "--:--:--");
185 }
186}
187
188void pim_time_uptime(char *buf, int buf_size, int64_t uptime_sec)
189{
190 zassert(buf_size >= 8);
191
192 pim_time_hhmmss(buf, buf_size, uptime_sec);
193}
194
Everton Marquesff752d42010-03-17 10:34:24 -0300195void pim_time_uptime_begin(char *buf, int buf_size, int64_t now, int64_t begin)
196{
197 if (begin > 0)
198 pim_time_uptime(buf, buf_size, now - begin);
199 else
200 snprintf(buf, buf_size, "--:--:--");
201}
202
Everton Marques871dbcf2009-08-11 15:43:05 -0300203long pim_time_timer_remain_msec(struct thread *t_timer)
204{
205 /* FIXME: Actually fetch msec resolution from thread */
206
207 /* no timer thread running means timer has expired: return 0 */
208
209 return t_timer ?
210 1000 * thread_timer_remain_second(t_timer) :
211 0;
212}