-
-
Notifications
You must be signed in to change notification settings - Fork 80
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
timer: Introduce osmo_clock_gettime to override clock_gettime
Change-Id: I5bebc6e01fc9d238065bc2517058f0ba85620349
- Loading branch information
Showing
8 changed files
with
255 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,7 @@ | |
#pragma once | ||
|
||
#include <sys/time.h> | ||
#include <time.h> | ||
#include <stdbool.h> | ||
|
||
#include <osmocom/core/linuxlist.h> | ||
|
@@ -87,6 +88,7 @@ int osmo_timers_update(void); | |
int osmo_timers_check(void); | ||
|
||
int osmo_gettimeofday(struct timeval *tv, struct timezone *tz); | ||
int osmo_clock_gettime(clockid_t clk_id, struct timespec *tp); | ||
|
||
/* | ||
* timer override | ||
|
@@ -96,4 +98,8 @@ extern bool osmo_gettimeofday_override; | |
extern struct timeval osmo_gettimeofday_override_time; | ||
void osmo_gettimeofday_override_add(time_t secs, suseconds_t usecs); | ||
|
||
void osmo_clock_override_enable(clockid_t clk_id, bool enable); | ||
void osmo_clock_override_add(clockid_t clk_id, time_t secs, long nsecs); | ||
struct timespec *osmo_clock_override_gettimespec(clockid_t clk_id); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
pespin
Author
Contributor
|
||
|
||
/*! @} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
/* | ||
* (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de> | ||
* All Rights Reserved | ||
* | ||
* Authors: Pau Espin Pedrol <pespin@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_clockgettime.c | ||
* Overriding Time: osmo_clock_gettime() | ||
* - Useful to write and reproduce tests that depend on specific time | ||
* factors. This API allows to fake the timespec provided by `clock_gettime()` | ||
* by using a small shim osmo_clock_gettime(). | ||
* - Choose the clock you want to override, for instance CLOCK_MONOTONIC. | ||
* - If the clock override is disabled (default) for a given clock, | ||
* osmo_clock_gettime() will do the same as regular `clock_gettime()`. | ||
* - If you want osmo_clock_gettime() to provide a specific time, you must | ||
* enable time override with osmo_clock_override_enable(), | ||
* then set a pointer to the timespec storing the fake time for that | ||
* specific clock (`struct timespec *ts = | ||
* osmo_clock_override_gettimespec()`) and set it as | ||
* desired. Next time osmo_clock_gettime() is called, it will return the | ||
* values previously set through the ts pointer. | ||
* - A helper osmo_clock_override_add() is provided to increment a given | ||
* overriden clock with a specific amount of time. | ||
*/ | ||
|
||
/*! \file timer_clockgettime.c | ||
*/ | ||
|
||
#include <stdlib.h> | ||
#include <stdbool.h> | ||
#include <sys/time.h> | ||
#include <time.h> | ||
|
||
#include <osmocom/core/timer_compat.h> | ||
|
||
/*! An internal structure to handle overriden time for each clock type. */ | ||
struct fakeclock { | ||
bool override; | ||
struct timespec time; | ||
}; | ||
|
||
static struct fakeclock realtime; | ||
static struct fakeclock realtime_coarse; | ||
static struct fakeclock mono; | ||
static struct fakeclock mono_coarse; | ||
static struct fakeclock mono_raw; | ||
static struct fakeclock boottime; | ||
static struct fakeclock boottime; | ||
static struct fakeclock proc_cputime_id; | ||
static struct fakeclock th_cputime_id; | ||
|
||
static struct fakeclock* clkid_to_fakeclock(clockid_t clk_id) | ||
{ | ||
switch(clk_id) { | ||
case CLOCK_REALTIME: | ||
return &realtime; | ||
case CLOCK_REALTIME_COARSE: | ||
return &realtime_coarse; | ||
case CLOCK_MONOTONIC: | ||
return &mono; | ||
case CLOCK_MONOTONIC_COARSE: | ||
return &mono_coarse; | ||
case CLOCK_MONOTONIC_RAW: | ||
return &mono_raw; | ||
case CLOCK_BOOTTIME: | ||
return &boottime; | ||
case CLOCK_PROCESS_CPUTIME_ID: | ||
return &proc_cputime_id; | ||
case CLOCK_THREAD_CPUTIME_ID: | ||
return &th_cputime_id; | ||
default: | ||
return NULL; | ||
} | ||
} | ||
|
||
/*! Shim around clock_gettime to be able to set the time manually. | ||
* | ||
* To override, use osmo_clock_override_enable and set the desired | ||
* current time with osmo_clock_gettimespec. */ | ||
int osmo_clock_gettime(clockid_t clk_id, struct timespec *tp) | ||
{ | ||
struct fakeclock* c = clkid_to_fakeclock(clk_id); | ||
if (!c || !c->override) | ||
return clock_gettime(clk_id, tp); | ||
|
||
*tp = c->time; | ||
return 0; | ||
} | ||
|
||
/*! Convenience function to enable or disable a specific clock fake time. | ||
*/ | ||
void osmo_clock_override_enable(clockid_t clk_id, bool enable) | ||
{ | ||
struct fakeclock* c = clkid_to_fakeclock(clk_id); | ||
if (c) | ||
c->override = enable; | ||
} | ||
|
||
/*! Convenience function to return a pointer to the timespec handling the | ||
* fake time for clock clk_id. */ | ||
struct timespec *osmo_clock_override_gettimespec(clockid_t clk_id) | ||
{ | ||
struct fakeclock* c = clkid_to_fakeclock(clk_id); | ||
if (c) | ||
return &c->time; | ||
return NULL; | ||
} | ||
|
||
/*! Convenience function to advance the fake time. | ||
* | ||
* Adds the given values to the clock time. */ | ||
void osmo_clock_override_add(clockid_t clk_id, time_t secs, long nsecs) | ||
{ | ||
struct timespec val = { secs, nsecs }; | ||
struct fakeclock* c = clkid_to_fakeclock(clk_id); | ||
if (c) | ||
timespecadd(&c->time, &val, &c->time); | ||
} | ||
|
||
/*! @} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
* (C) 2008 by Holger Hans Peter Freyther <zecke@selfish.org> | ||
* (C) 2011 by Harald Welte <laforge@gnumonks.org> | ||
* All Rights Reserved | ||
* | ||
* Authors: Holger Hans Peter Freyther <zecke@selfish.org> | ||
* Pablo Neira Ayuso <pablo@gnumonks.org> | ||
* | ||
* 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. | ||
* | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <unistd.h> | ||
#include <string.h> | ||
|
||
#include <osmocom/core/talloc.h> | ||
#include <osmocom/core/timer.h> | ||
#include <osmocom/core/select.h> | ||
#include <osmocom/core/linuxlist.h> | ||
#include <osmocom/core/timer_compat.h> | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
|
||
struct timespec ts1 = { 123, 456 }, ts2 = {1, 200}; | ||
struct timespec read1, read2, res; | ||
struct timespec *mono; | ||
|
||
osmo_clock_gettime(CLOCK_BOOTTIME, &read1); | ||
usleep(500); | ||
osmo_clock_gettime(CLOCK_BOOTTIME, &read2); | ||
if (!timespeccmp(&read2, &read1, >)) | ||
return EXIT_FAILURE; | ||
printf("Non implemented clocks work fine\n"); | ||
|
||
osmo_clock_gettime(CLOCK_MONOTONIC, &read1); | ||
usleep(500); | ||
osmo_clock_gettime(CLOCK_MONOTONIC, &read2); | ||
if (!timespeccmp(&read2, &read1, >)) | ||
return EXIT_FAILURE; | ||
printf("Monotonic clock is working fine by default\n"); | ||
|
||
osmo_clock_override_enable(CLOCK_MONOTONIC, true); | ||
printf("Monotonic clock override enabled\n"); | ||
|
||
mono = osmo_clock_override_gettimespec(CLOCK_MONOTONIC); | ||
if (timespecisset(mono)) | ||
return EXIT_FAILURE; | ||
printf("Monotonic override is cleared by default\n"); | ||
|
||
memcpy(mono, &ts1, sizeof(struct timespec)); | ||
osmo_clock_gettime(CLOCK_MONOTONIC, &read1); | ||
if (!timespeccmp(&ts1, &read1, ==)) | ||
return EXIT_FAILURE; | ||
printf("Monotonic clock can be overriden\n"); | ||
|
||
osmo_clock_override_add(CLOCK_MONOTONIC, ts2.tv_sec, ts2.tv_nsec); | ||
osmo_clock_gettime(CLOCK_MONOTONIC, &read1); | ||
timespecadd(&ts2, &ts1, &res); | ||
if (!timespeccmp(&res, &read1, ==)) | ||
return EXIT_FAILURE; | ||
printf("osmo_clock_override_add works fine.\n"); | ||
|
||
osmo_clock_override_enable(CLOCK_MONOTONIC, false); | ||
printf("Monotonic clock override disabled\n"); | ||
|
||
osmo_clock_gettime(CLOCK_MONOTONIC, &read1); | ||
usleep(500); | ||
osmo_clock_gettime(CLOCK_MONOTONIC, &read2); | ||
if (!timespeccmp(&read2, &read1, >)) | ||
return EXIT_FAILURE; | ||
printf("Monotonic clock is working fine after enable+disable.\n"); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
Non implemented clocks work fine | ||
Monotonic clock is working fine by default | ||
Monotonic clock override enabled | ||
Monotonic override is cleared by default | ||
Monotonic clock can be overriden | ||
osmo_clock_override_add works fine. | ||
Monotonic clock override disabled | ||
Monotonic clock is working fine after enable+disable. |
@pespin this broke the macOS build: https://github.com/NixOS/nixpkgs/pull/51742/checks?check_run_id=39071151
A fix would be: