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)
{
#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;
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)
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)
#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
#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
struct timespec ts;
int rv;
+ mutex_init(&loop->update_lock);
+
rv = clock_gettime(CLOCK_MONOTONIC, &ts);
if (rv < 0)
die("Monotonic clock is missing");
struct timespec ts;
int rv;
+ mutex_lock(&loop->update_lock);
+
rv = clock_gettime(CLOCK_MONOTONIC, &ts);
if (rv < 0)
die("clock_gettime: %m");
loop->last_time = new_time;
loop->real_time = 0;
+
+ mutex_unlock(&loop->update_lock);
}
void
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);
}
--- /dev/null
+/*
+ * BIRD Locking Subsystem
+ *
+ * (c) 2018 Maria Matejka <mq@jmq.cz>
+ *
+ * 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 <pthread.h>
+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