Added SILC Timer API.
[silc.git] / lib / silcutil / silctimer.c
diff --git a/lib/silcutil/silctimer.c b/lib/silcutil/silctimer.c
new file mode 100644 (file)
index 0000000..9037127
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+
+  silctimer.c
+
+  Author: Pekka Riikonen <priikone@silcnet.org>
+
+  Copyright (C) 2007 Pekka Riikonen
+
+  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; version 2 of the License.
+
+  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.
+
+*/
+
+#include "silc.h"
+
+/* Start timer */
+
+void silc_timer_start(SilcTimer timer)
+{
+  struct timeval curtime;
+
+  memset(timer, 0, sizeof(timer));
+
+  silc_gettimeofday(&curtime);
+  timer->start_sec = curtime.tv_sec;
+  timer->start_usec = curtime.tv_usec;
+
+  timer->running = TRUE;
+}
+
+/* Stop timer */
+
+void silc_timer_stop(SilcTimer timer)
+{
+  struct timeval curtime;
+
+  silc_gettimeofday(&curtime);
+
+  if (curtime.tv_usec < timer->start_usec) {
+    curtime.tv_sec--;
+    curtime.tv_usec += 1000000L;
+  }
+  timer->timer_sec = curtime.tv_sec - timer->start_sec;
+  timer->timer_usec = curtime.tv_usec - timer->start_usec;
+
+  timer->running = FALSE;
+}
+
+/* Continue stopped timer */
+
+void silc_timer_continue(SilcTimer timer)
+{
+  struct timeval curtime;
+
+  if (timer->running)
+    return;
+
+  silc_gettimeofday(&curtime);
+
+  if (curtime.tv_usec < timer->timer_usec) {
+    curtime.tv_sec--;
+    curtime.tv_usec += 1000000L;
+  }
+  timer->start_sec = curtime.tv_sec - timer->timer_sec;
+  timer->start_usec = curtime.tv_usec - timer->timer_usec;
+
+  timer->running = TRUE;
+}
+
+/* Return timer value */
+
+void silc_timer_value(SilcTimer timer,
+                     SilcUInt64 *elapsed_time_seconds,
+                     SilcUInt32 *elapsed_time_microseconds)
+{
+  if (timer->running) {
+    struct timeval curtime;
+
+    silc_gettimeofday(&curtime);
+
+    if (curtime.tv_usec < timer->start_usec) {
+      curtime.tv_sec--;
+      curtime.tv_usec += 1000000L;
+    }
+    timer->timer_sec = curtime.tv_sec - timer->start_sec;
+    timer->timer_usec = curtime.tv_usec - timer->start_usec;
+  }
+
+  if (elapsed_time_seconds)
+    *elapsed_time_seconds = timer->timer_sec;
+  if (elapsed_time_microseconds)
+    *elapsed_time_microseconds = timer->timer_usec;
+}
+
+/* Return timer value */
+
+void silc_timer_value_time(SilcTimer timer, SilcTime ret_time)
+{
+  SilcUInt64 sec;
+  SilcUInt32 usec;
+
+  silc_timer_value(timer, &sec, &usec);
+  sec = ((timer->start_sec + sec) * (SilcUInt64)1000);
+  sec += ((timer->start_usec + usec) / 1000);
+  silc_time_value(sec, ret_time);
+}
+
+/* Return start time */
+
+void silc_timer_start_time(SilcTimer timer, SilcTime ret_start_time)
+{
+  silc_time_value(((timer->start_sec * (SilcUInt64)1000) +
+                  (timer->start_usec / 1000)), ret_start_time);
+}
+
+/* Return TRUE if timer is running */
+
+SilcBool silc_timer_is_running(SilcTimer timer)
+{
+  return timer->running;
+}