Added SILC Timer API.
[silc.git] / lib / silcutil / silctimer.c
1 /*
2
3   silctimer.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2007 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 #include "silc.h"
21
22 /* Start timer */
23
24 void silc_timer_start(SilcTimer timer)
25 {
26   struct timeval curtime;
27
28   memset(timer, 0, sizeof(timer));
29
30   silc_gettimeofday(&curtime);
31   timer->start_sec = curtime.tv_sec;
32   timer->start_usec = curtime.tv_usec;
33
34   timer->running = TRUE;
35 }
36
37 /* Stop timer */
38
39 void silc_timer_stop(SilcTimer timer)
40 {
41   struct timeval curtime;
42
43   silc_gettimeofday(&curtime);
44
45   if (curtime.tv_usec < timer->start_usec) {
46     curtime.tv_sec--;
47     curtime.tv_usec += 1000000L;
48   }
49   timer->timer_sec = curtime.tv_sec - timer->start_sec;
50   timer->timer_usec = curtime.tv_usec - timer->start_usec;
51
52   timer->running = FALSE;
53 }
54
55 /* Continue stopped timer */
56
57 void silc_timer_continue(SilcTimer timer)
58 {
59   struct timeval curtime;
60
61   if (timer->running)
62     return;
63
64   silc_gettimeofday(&curtime);
65
66   if (curtime.tv_usec < timer->timer_usec) {
67     curtime.tv_sec--;
68     curtime.tv_usec += 1000000L;
69   }
70   timer->start_sec = curtime.tv_sec - timer->timer_sec;
71   timer->start_usec = curtime.tv_usec - timer->timer_usec;
72
73   timer->running = TRUE;
74 }
75
76 /* Return timer value */
77
78 void silc_timer_value(SilcTimer timer,
79                       SilcUInt64 *elapsed_time_seconds,
80                       SilcUInt32 *elapsed_time_microseconds)
81 {
82   if (timer->running) {
83     struct timeval curtime;
84
85     silc_gettimeofday(&curtime);
86
87     if (curtime.tv_usec < timer->start_usec) {
88       curtime.tv_sec--;
89       curtime.tv_usec += 1000000L;
90     }
91     timer->timer_sec = curtime.tv_sec - timer->start_sec;
92     timer->timer_usec = curtime.tv_usec - timer->start_usec;
93   }
94
95   if (elapsed_time_seconds)
96     *elapsed_time_seconds = timer->timer_sec;
97   if (elapsed_time_microseconds)
98     *elapsed_time_microseconds = timer->timer_usec;
99 }
100
101 /* Return timer value */
102
103 void silc_timer_value_time(SilcTimer timer, SilcTime ret_time)
104 {
105   SilcUInt64 sec;
106   SilcUInt32 usec;
107
108   silc_timer_value(timer, &sec, &usec);
109   sec = ((timer->start_sec + sec) * (SilcUInt64)1000);
110   sec += ((timer->start_usec + usec) / 1000);
111   silc_time_value(sec, ret_time);
112 }
113
114 /* Return start time */
115
116 void silc_timer_start_time(SilcTimer timer, SilcTime ret_start_time)
117 {
118   silc_time_value(((timer->start_sec * (SilcUInt64)1000) +
119                    (timer->start_usec / 1000)), ret_start_time);
120 }
121
122 /* Return TRUE if timer is running */
123
124 SilcBool silc_timer_is_running(SilcTimer timer)
125 {
126   return timer->running;
127 }