summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/core/timer.h11
-rw-r--r--src/Makefile.am2
-rw-r--r--src/gb/gprs_bssgp.c8
-rw-r--r--src/gb/gprs_ns.c4
-rw-r--r--src/logging.c3
-rw-r--r--src/timer.c8
-rw-r--r--src/timer_gettimeofday.c58
-rw-r--r--src/vty/command.c2
-rw-r--r--tests/gb/bssgp_fc_test.c4
-rw-r--r--tests/timer/timer_test.c4
10 files changed, 87 insertions, 17 deletions
diff --git a/include/osmocom/core/timer.h b/include/osmocom/core/timer.h
index 6730bfe1..dbda13f2 100644
--- a/include/osmocom/core/timer.h
+++ b/include/osmocom/core/timer.h
@@ -29,6 +29,7 @@
#pragma once
#include <sys/time.h>
+#include <stdbool.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/linuxrbtree.h>
@@ -83,4 +84,14 @@ void osmo_timers_prepare(void);
int osmo_timers_update(void);
int osmo_timers_check(void);
+int osmo_gettimeofday(struct timeval *tv, struct timezone *tz);
+
+/**
+ * timer override
+ */
+
+extern bool osmo_gettimeofday_override;
+extern struct timeval osmo_gettimeofday_override_time;
+void osmo_gettimeofday_override_add(time_t secs, suseconds_t usecs);
+
/*! @} */
diff --git a/src/Makefile.am b/src/Makefile.am
index 7a6f464d..74bdb213 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,7 +8,7 @@ AM_CFLAGS = -Wall $(TALLOC_CFLAGS)
lib_LTLIBRARIES = libosmocore.la
libosmocore_la_LIBADD = $(BACKTRACE_LIB) $(TALLOC_LIBS)
-libosmocore_la_SOURCES = timer.c select.c signal.c msgb.c bits.c \
+libosmocore_la_SOURCES = timer.c timer_gettimeofday.c select.c signal.c msgb.c bits.c \
bitvec.c bitcomp.c statistics.c fsm.c \
write_queue.c utils.c socket.c \
logging.c logging_syslog.c rate_ctr.c \
diff --git a/src/gb/gprs_bssgp.c b/src/gb/gprs_bssgp.c
index 3ad2f297..1ee942f2 100644
--- a/src/gb/gprs_bssgp.c
+++ b/src/gb/gprs_bssgp.c
@@ -603,7 +603,7 @@ static void fc_timer_cb(void *data)
fc->queue_depth--;
/* record the time we transmitted this PDU */
- gettimeofday(&time_now, NULL);
+ osmo_gettimeofday(&time_now, NULL);
fc->time_last_pdu = time_now;
/* call the output callback for this FC instance */
@@ -688,7 +688,7 @@ static int bssgp_fc_needs_queueing(struct bssgp_flow_control *fc, uint32_t pdu_l
/* compute number of centi-seconds that have elapsed since transmitting
* the last PDU (Tc - Tp) */
- gettimeofday(&time_now, NULL);
+ osmo_gettimeofday(&time_now, NULL);
timersub(&time_now, &fc->time_last_pdu, &time_diff);
csecs_elapsed = time_diff.tv_sec*100 + time_diff.tv_usec/10000;
@@ -747,7 +747,7 @@ int bssgp_fc_in(struct bssgp_flow_control *fc, struct msgb *msg,
return fc_enqueue(fc, msg, llc_pdu_len, priv);
} else {
/* record the time we transmitted this PDU */
- gettimeofday(&time_now, NULL);
+ osmo_gettimeofday(&time_now, NULL);
fc->time_last_pdu = time_now;
return fc->out_cb(priv, msg, llc_pdu_len, NULL);
}
@@ -766,7 +766,7 @@ void bssgp_fc_init(struct bssgp_flow_control *fc,
fc->bucket_leak_rate = bucket_leak_rate;
fc->max_queue_depth = max_queue_depth;
INIT_LLIST_HEAD(&fc->queue);
- gettimeofday(&fc->time_last_pdu, NULL);
+ osmo_gettimeofday(&fc->time_last_pdu, NULL);
}
/* Initialize the Flow Control parameters for a new MS according to
diff --git a/src/gb/gprs_ns.c b/src/gb/gprs_ns.c
index 6879c708..18845d4b 100644
--- a/src/gb/gprs_ns.c
+++ b/src/gb/gprs_ns.c
@@ -556,7 +556,7 @@ static void nsvc_start_timer(struct gprs_nsvc *nsvc, enum nsvc_timer_mode mode)
if (osmo_timer_pending(&nsvc->timer))
osmo_timer_del(&nsvc->timer);
- gettimeofday(&nsvc->timer_started, NULL);
+ osmo_gettimeofday(&nsvc->timer_started, NULL);
nsvc->timer_mode = mode;
osmo_timer_schedule(&nsvc->timer, seconds, 0);
}
@@ -564,7 +564,7 @@ static void nsvc_start_timer(struct gprs_nsvc *nsvc, enum nsvc_timer_mode mode)
static int nsvc_timer_elapsed_ms(struct gprs_nsvc *nsvc)
{
struct timeval now, elapsed;
- gettimeofday(&now, NULL);
+ osmo_gettimeofday(&now, NULL);
timersub(&now, &nsvc->timer_started, &elapsed);
return 1000 * elapsed.tv_sec + elapsed.tv_usec / 1000;
diff --git a/src/logging.c b/src/logging.c
index 8a101337..9e30d5f8 100644
--- a/src/logging.c
+++ b/src/logging.c
@@ -44,6 +44,7 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/logging.h>
+#include <osmocom/core/timer.h>
#include <osmocom/vty/logging.h> /* for LOGGING_STR. */
@@ -268,7 +269,7 @@ static void _output(struct log_target *target, unsigned int subsys,
if (target->print_ext_timestamp) {
struct tm tm;
struct timeval tv;
- gettimeofday(&tv, NULL);
+ osmo_gettimeofday(&tv, NULL);
localtime_r(&tv.tv_sec, &tm);
ret = snprintf(buf + offset, rem, "%04d%02d%02d%02d%02d%02d%03d ",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
diff --git a/src/timer.c b/src/timer.c
index 0358b89e..10a0b95d 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -91,7 +91,7 @@ osmo_timer_schedule(struct osmo_timer_list *timer, int seconds, int microseconds
{
struct timeval current_time;
- gettimeofday(&current_time, NULL);
+ osmo_gettimeofday(&current_time, NULL);
timer->timeout.tv_sec = seconds;
timer->timeout.tv_usec = microseconds;
timeradd(&timer->timeout, &current_time, &timer->timeout);
@@ -143,7 +143,7 @@ int osmo_timer_remaining(const struct osmo_timer_list *timer,
struct timeval current_time;
if (!now)
- gettimeofday(&current_time, NULL);
+ osmo_gettimeofday(&current_time, NULL);
else
current_time = *now;
@@ -193,7 +193,7 @@ void osmo_timers_prepare(void)
struct rb_node *node;
struct timeval current;
- gettimeofday(&current, NULL);
+ osmo_gettimeofday(&current, NULL);
node = rb_first(&timer_root);
if (node) {
@@ -214,7 +214,7 @@ int osmo_timers_update(void)
struct osmo_timer_list *this;
int work = 0;
- gettimeofday(&current_time, NULL);
+ osmo_gettimeofday(&current_time, NULL);
INIT_LLIST_HEAD(&timer_eviction_list);
for (node = rb_first(&timer_root); node; node = rb_next(node)) {
diff --git a/src/timer_gettimeofday.c b/src/timer_gettimeofday.c
new file mode 100644
index 00000000..81a1598d
--- /dev/null
+++ b/src/timer_gettimeofday.c
@@ -0,0 +1,58 @@
+/*
+ * (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * Authors: Neels Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+/*! \addtogroup timer
+ * @{
+ */
+
+/*! \file timer_gettimeofday.c
+ */
+
+#include <stdbool.h>
+#include <sys/time.h>
+
+bool osmo_gettimeofday_override = false;
+struct timeval osmo_gettimeofday_override_time = { 23, 424242 };
+
+/*! \brief shim around gettimeofday to be able to set the time manually.
+ * To override, set osmo_gettimeofday_override == true and set the desired
+ * current time in osmo_gettimeofday_override_time. */
+int osmo_gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+ if (osmo_gettimeofday_override) {
+ *tv = osmo_gettimeofday_override_time;
+ return 0;
+ }
+
+ return gettimeofday(tv, tz);
+}
+
+/*! \brief convenience function to advance the fake time.
+ * Add the given values to osmo_gettimeofday_override_time. */
+void osmo_gettimeofday_override_add(time_t secs, suseconds_t usecs)
+{
+ struct timeval val = { secs, usecs };
+ timeradd(&osmo_gettimeofday_override_time, &val,
+ &osmo_gettimeofday_override_time);
+}
+
+/*! @} */
diff --git a/src/vty/command.c b/src/vty/command.c
index 483ca801..9d8bf314 100644
--- a/src/vty/command.c
+++ b/src/vty/command.c
@@ -637,7 +637,7 @@ static char *zencrypt(const char *passwd)
struct timeval tv;
char *crypt(const char *, const char *);
- gettimeofday(&tv, 0);
+ osmo_gettimeofday(&tv, 0);
to64(&salt[0], random(), 3);
to64(&salt[3], tv.tv_usec, 3);
diff --git a/tests/gb/bssgp_fc_test.c b/tests/gb/bssgp_fc_test.c
index ad8f83d6..d77f141a 100644
--- a/tests/gb/bssgp_fc_test.c
+++ b/tests/gb/bssgp_fc_test.c
@@ -22,7 +22,7 @@ int get_centisec_diff(void)
{
struct timeval tv;
struct timeval now;
- gettimeofday(&now, NULL);
+ osmo_gettimeofday(&now, NULL);
timersub(&now, &tv_start, &tv);
@@ -73,7 +73,7 @@ static void test_fc(uint32_t bucket_size_max, uint32_t bucket_leak_rate,
bssgp_fc_init(fc, bucket_size_max, bucket_leak_rate, max_queue_depth,
fc_out_cb);
- gettimeofday(&tv_start, NULL);
+ osmo_gettimeofday(&tv_start, NULL);
for (i = 0; i < pdu_count; i++) {
fc_in(fc, pdu_len);
diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c
index 1aeab454..6308113c 100644
--- a/tests/timer/timer_test.c
+++ b/tests/timer/timer_test.c
@@ -87,7 +87,7 @@ static void main_timer_fired(void *data)
fprintf(stderr, "timer_test: OOM!\n");
return;
}
- gettimeofday(&v->start, NULL);
+ osmo_gettimeofday(&v->start, NULL);
v->timer.cb = secondary_timer_fired;
v->timer.data = v;
unsigned int seconds = (random() % 10) + 1;
@@ -108,7 +108,7 @@ static void secondary_timer_fired(void *data)
struct test_timer *v = data, *this, *tmp;
struct timeval current, res, precision = { 1, 0 };
- gettimeofday(&current, NULL);
+ osmo_gettimeofday(&current, NULL);
timersub(&current, &v->stop, &res);
if (timercmp(&res, &precision, >)) {