From cc5d17ecbbda250c6686f0e348627ab63458543c Mon Sep 17 00:00:00 2001 From: Jan Maria Matejka Date: Mon, 24 Sep 2018 15:48:27 +0200 Subject: [PATCH] Mutex abstraction layer; used in timeloop update calls --- lib/timer.c | 8 +++++++ lib/timer.h | 10 ++++----- sysdep/cf/bsd.h | 2 ++ sysdep/cf/linux.h | 1 + sysdep/unix/io.c | 10 +++++++++ sysdep/unix/locking.h | 49 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 sysdep/unix/locking.h diff --git a/lib/timer.c b/lib/timer.c index ed731d26e..d07bf0f7f 100644 --- a/lib/timer.c +++ b/lib/timer.c @@ -76,6 +76,14 @@ current_time(void) return timeloop_current()->last_time; } +btime +current_fresh_time(void) +{ + struct timeloop *loop = timeloop_current(); + times_update(loop); + return loop->last_time; +} + btime current_real_time(void) { diff --git a/lib/timer.h b/lib/timer.h index ed8f0d025..fa5f2f9d5 100644 --- a/lib/timer.h +++ b/lib/timer.h @@ -13,10 +13,9 @@ #include "nest/bird.h" #include "lib/buffer.h" #include "lib/resource.h" +#include CONFIG_INCLUDE_LOCKING_H - -typedef struct timer -{ +typedef struct timer { resource r; void (*hook)(struct timer *); void *data; @@ -28,11 +27,11 @@ typedef struct timer int index; } timer; -struct timeloop -{ +struct timeloop { BUFFER_(timer *) timers; btime last_time; btime real_time; + mutex update_lock; }; static inline uint timers_count(struct timeloop *loop) @@ -44,6 +43,7 @@ static inline timer *timers_first(struct timeloop *loop) extern struct timeloop main_timeloop; btime current_time(void); +btime current_fresh_time(void); btime current_real_time(void); //#define now (current_time() TO_S) diff --git a/sysdep/cf/bsd.h b/sysdep/cf/bsd.h index 22c542772..2d1354e5c 100644 --- a/sysdep/cf/bsd.h +++ b/sysdep/cf/bsd.h @@ -18,6 +18,8 @@ #define CONFIG_INCLUDE_SYSIO_H "sysdep/bsd/sysio.h" #define CONFIG_INCLUDE_KRTSYS_H "sysdep/bsd/krt-sys.h" +#define CONFIG_INCLUDE_LOCKING_H "sysdep/unix/locking.h" + /* Link: sysdep/unix Link: sysdep/bsd diff --git a/sysdep/cf/linux.h b/sysdep/cf/linux.h index 047d3764e..b0eb2fd43 100644 --- a/sysdep/cf/linux.h +++ b/sysdep/cf/linux.h @@ -21,6 +21,7 @@ #define CONFIG_RESTRICTED_PRIVILEGES #define CONFIG_INCLUDE_SYSPRIV_H "sysdep/linux/syspriv.h" +#define CONFIG_INCLUDE_LOCKING_H "sysdep/unix/locking.h" #ifndef AF_MPLS #define AF_MPLS 28 diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index 4455fc199..8fd471184 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -115,6 +115,8 @@ times_init(struct timeloop *loop) struct timespec ts; int rv; + mutex_init(&loop->update_lock); + rv = clock_gettime(CLOCK_MONOTONIC, &ts); if (rv < 0) die("Monotonic clock is missing"); @@ -132,6 +134,8 @@ times_update(struct timeloop *loop) struct timespec ts; int rv; + mutex_lock(&loop->update_lock); + rv = clock_gettime(CLOCK_MONOTONIC, &ts); if (rv < 0) die("clock_gettime: %m"); @@ -143,6 +147,8 @@ times_update(struct timeloop *loop) loop->last_time = new_time; loop->real_time = 0; + + mutex_unlock(&loop->update_lock); } void @@ -151,11 +157,15 @@ times_update_real_time(struct timeloop *loop) struct timespec ts; int rv; + mutex_lock(&loop->update_lock); + rv = clock_gettime(CLOCK_REALTIME, &ts); if (rv < 0) die("clock_gettime: %m"); loop->real_time = ts.tv_sec S + ts.tv_nsec NS; + + mutex_unlock(&loop->update_lock); } diff --git a/sysdep/unix/locking.h b/sysdep/unix/locking.h new file mode 100644 index 000000000..8d3fcd4cd --- /dev/null +++ b/sysdep/unix/locking.h @@ -0,0 +1,49 @@ +/* + * BIRD Locking Subsystem + * + * (c) 2018 Maria Matejka + * + * Can be freely distributed and used under the terms of the GNU GPL. + */ + +#ifndef _BIRD_SYSDEP_MUTEX_H_ +#define _BIRD_SYSDEP_MUTEX_H_ + +#define MUTEX_DEBUG 1 + +#if MUTEX_DEBUG +#define MUTEX_TYPE PTHREAD_MUTEX_ERRORCHECK +#else +#define MUTEX_TYPE PTHREAD_MUTEX_NORMAL +#endif + +#include +typedef pthread_mutex_t mutex; + +static inline void mutex_init(mutex *m) +{ + pthread_mutexattr_t mat; + if (pthread_mutexattr_init(&mat) < 0) + bug("pthread_mutexattr_init() failed: %m"); + if (pthread_mutexattr_settype(&mat, MUTEX_TYPE) < 0) + bug("pthread_mutexattr_settype() failed: %m"); + if (pthread_mutex_init(m, &mat) < 0) + bug("pthread_mutex_init() failed: %m"); +} + +#if MUTEX_DEBUG +#define mutex_lock(m) do { \ + if (pthread_mutex_lock(m)) \ + bug("pthread_mutex_lock() failed: %m"); \ + } while (0) + +#define mutex_unlock(m) do { \ + if (pthread_mutex_unlock(m)) \ + bug("pthread_mutex_unlock() failed: %m"); \ + } while (0) +#else +#define mutex_lock(m) pthread_mutex_lock(m) +#define mutex_unlock(m) pthread_mutex_unlock(m) +#endif + +#endif -- 2.47.2