From 2cee6b036b84f30575d92233e797e44523795ca9 Mon Sep 17 00:00:00 2001 From: Kaspar Schleiser <kaspar@schleiser.de> Date: Wed, 29 Jul 2015 16:00:58 +0200 Subject: [PATCH] sys: remove vtimer --- sys/auto_init/auto_init.c | 8 - sys/include/vtimer.h | 158 ------------- sys/vtimer/Makefile | 1 - sys/vtimer/vtimer.c | 455 -------------------------------------- 4 files changed, 622 deletions(-) delete mode 100644 sys/include/vtimer.h delete mode 100644 sys/vtimer/Makefile delete mode 100644 sys/vtimer/vtimer.c diff --git a/sys/auto_init/auto_init.c b/sys/auto_init/auto_init.c index 2641c41e72..faaf8cde6c 100644 --- a/sys/auto_init/auto_init.c +++ b/sys/auto_init/auto_init.c @@ -40,10 +40,6 @@ #include "diskio.h" #endif -#ifdef MODULE_VTIMER -#include "vtimer.h" -#endif - #ifdef MODULE_XTIMER #include "xtimer.h" #endif @@ -94,10 +90,6 @@ void auto_init(void) config_load(); #endif -#ifdef MODULE_VTIMER - DEBUG("Auto init vtimer module.\n"); - vtimer_init(); -#endif #ifdef MODULE_XTIMER DEBUG("Auto init xtimer module.\n"); xtimer_init(); diff --git a/sys/include/vtimer.h b/sys/include/vtimer.h deleted file mode 100644 index 814c4deec7..0000000000 --- a/sys/include/vtimer.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2009, 2014 Kaspar Schleiser - * Copyright (C) 2013, 2014 Freie Universität Berlin - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @defgroup sys_vtimer Virtual Timer - * @ingroup sys - * @brief Provides a high level abstraction timer module to register - * timers, get current system time, and let a thread sleep for a certain amount - * of time. It does not give any timing guarantees. - * @{ - * @file - * @author Kaspar Schleiser <kaspar@schleiser.de> - */ - -#ifndef __VTIMER_H -#define __VTIMER_H - -#include <time.h> -#include <sys/time.h> - -#include "priority_queue.h" -#include "timex.h" -#include "msg.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief IPC message type for vtimer msg callback - */ -#define MSG_TIMER 12345 - -/** - * @brief A vtimer object. - * - * This structure is used for declaring a vtimer. This should not be used by - * programmers, use the vtimer_set_*-functions instead. - * - * \hideinitializer - */ -typedef struct vtimer_t { - /** entry in vtimer's internal priority queue */ - priority_queue_node_t priority_queue_entry; - /** the absoule point in time when the timer expires */ - timex_t absolute; - /** the action to perform when timer fires */ - void (*action)(struct vtimer_t *timer); - /** value for msg_t.type */ - uint16_t type; - /** optional argument for vtimer_t::action */ - void *arg; - /** optional process id for vtimer_t::action to act on */ - kernel_pid_t pid; -} vtimer_t; - -/** - * @brief Current system time - * @return Time as timex_t since system boot - */ -void vtimer_now(timex_t *out); - -/** - * @brief Get the current time in seconds and microseconds since system start - * @param[in] tp Uptime will be stored in the timeval structure pointed to by tp - */ -void vtimer_gettimeofday(struct timeval *tp); - -/** - * @brief Returns the current time in broken down format - * @param[out] localt Pointer to structure to receive time - */ -void vtimer_get_localtime(struct tm *localt); - -/** - * @brief Initializes the vtimer subsystem. To be called once at system initialization. Will be initialized by auto_init. - */ -void vtimer_init(void); - -/** - * @brief will cause the calling thread to be suspended from excecution until the number of microseconds has elapsed - * @param[in] us number of microseconds - * @return 0 on success, < 0 on error - */ -int vtimer_usleep(uint32_t us); - -/** - * @brief will cause the calling thread to be suspended from excecution until the time specified by time has elapsed - * @param[in] time timex_t with time to suspend execution - * @return 0 on success, < 0 on error - */ -int vtimer_sleep(timex_t time); - -/** - * @brief set a vtimer with msg event handler of the specified type - * @param[in] t pointer to preinitialised vtimer_t - * @param[in] interval vtimer timex_t interval - * @param[in] pid process id - * @param[in] type value for the msg_t type - * @param[in] ptr message value - */ -void vtimer_set_msg(vtimer_t *t, timex_t interval, kernel_pid_t pid, uint16_t type, void *ptr); - -/** - * @brief set a vtimer with wakeup event - * @param[in] t pointer to preinitialised vtimer_t - * @param[in] interval the interval after which the timer shall fire - * @param[in] pid process id - * @return 0 on success, < 0 on error - */ -int vtimer_set_wakeup(vtimer_t *t, timex_t interval, kernel_pid_t pid); - -/** - * @brief remove a vtimer - * @param[in] t pointer to preinitialised vtimer_t - */ -void vtimer_remove(vtimer_t *t); - - -/** - * @brief receive a message but return in case of timeout time is passed by without a new message - * @param[out] m pointer to a msg_t which will be filled in case of no timeout - * @param[in] timeout timex_t containing the relative time to fire the timeout - * @return < 0 on error, other value otherwise - */ -int vtimer_msg_receive_timeout(msg_t *m, timex_t timeout); - -#if ENABLE_DEBUG - -/** - * @brief Prints a vtimer_t - */ -void vtimer_print(vtimer_t *t); - -/** - * @brief Prints the vtimer shortterm queue (use for debug purposes) - */ -void vtimer_print_short_queue(void); - -/** - * @brief Prints the vtimer longterm queue (use for debug purposes) - */ -void vtimer_print_long_queue(void); - -#endif - -#ifdef __cplusplus -} -#endif - -/** @} */ -#endif /* __VTIMER_H */ diff --git a/sys/vtimer/Makefile b/sys/vtimer/Makefile deleted file mode 100644 index 48422e909a..0000000000 --- a/sys/vtimer/Makefile +++ /dev/null @@ -1 +0,0 @@ -include $(RIOTBASE)/Makefile.base diff --git a/sys/vtimer/vtimer.c b/sys/vtimer/vtimer.c deleted file mode 100644 index a3f9acb0b1..0000000000 --- a/sys/vtimer/vtimer.c +++ /dev/null @@ -1,455 +0,0 @@ -/** - * virtual timer - * - * Copyright (C) 2013 - 2015 Freie Universität Berlin - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - * - * @ingroup vtimer - * @{ - * @file - * @author Kaspar Schleiser <kaspar@schleiser.de> (author) - * @author Oliver Hahm <oliver.hahm@inria.fr> (modifications) - * @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de> (cleaning up the mess) - * @} - */ - -#include <stddef.h> -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> - -#define ENABLE_DEBUG (0) -#include "debug.h" - -#include "irq.h" -#include "priority_queue.h" -#include "timex.h" -#include "hwtimer.h" -#include "msg.h" -#include "mutex.h" -#include "thread.h" -#include "kernel_macros.h" - -#include "vtimer.h" - - -#if ENABLE_DEBUG - -void vtimer_print_short_queue(void); -void vtimer_print_long_queue(void); -void vtimer_print(vtimer_t *t); - -#endif - -#define VTIMER_THRESHOLD 20UL -#define VTIMER_BACKOFF 10UL - -#define SECONDS_PER_TICK (4096U) -#define MICROSECONDS_PER_TICK (4096UL * 1000000) - -/* - * This is a workaround for missing support in clang on OSX, - * the alias is not needed in native. - * Compare https://github.com/RIOT-OS/RIOT/issues/2336 - */ -#ifndef BOARD_NATIVE -void _gettimeofday(void) __attribute__ ((weak, alias("vtimer_gettimeofday"))); -#endif - -static void vtimer_callback(void *ptr); -static void vtimer_callback_tick(vtimer_t *timer); -static void vtimer_callback_msg(vtimer_t *timer); -static void vtimer_callback_wakeup(vtimer_t *timer); - -static int vtimer_set(vtimer_t *timer); -static int set_longterm(vtimer_t *timer); -static int set_shortterm(vtimer_t *timer); - -static priority_queue_t longterm_priority_queue_root = PRIORITY_QUEUE_INIT; -static priority_queue_t shortterm_priority_queue_root = PRIORITY_QUEUE_INIT; - -static vtimer_t longterm_tick_timer; -static uint32_t longterm_tick_start; -static volatile int in_callback = false; - -static int hwtimer_id = -1; -static uint32_t hwtimer_next_absolute; - -static inline priority_queue_node_t *timer_get_node(vtimer_t *timer) -{ - if (!timer) { - return NULL; - } - return &timer->priority_queue_entry; -} - -static inline vtimer_t *node_get_timer(priority_queue_node_t *node) -{ - if (!node) { - return NULL; - } - return container_of(node, vtimer_t, priority_queue_entry); -} - -static int set_longterm(vtimer_t *timer) -{ - timer->priority_queue_entry.priority = timer->absolute.seconds; - /* *** UGLY FIX BEGINS *** */ - /* Workaround for a bug in a so far undiscovered location which causes the - * vtimer to add the same timer twice, locking the system in an infinite - * loop inside priority_queue_add. */ - priority_queue_remove(&longterm_priority_queue_root, timer_get_node(timer)); - /* *** UGLY FIX ENDS *** */ - priority_queue_add(&longterm_priority_queue_root, timer_get_node(timer)); - return 0; -} - -static int update_shortterm(void) -{ - if (shortterm_priority_queue_root.first == NULL) { - /* there is no vtimer to schedule, queue is empty */ - DEBUG("update_shortterm: shortterm_priority_queue_root.next == NULL - dont know what to do here\n"); - return 0; - } - if (hwtimer_id != -1) { - /* there is a running hwtimer for us */ - if (hwtimer_next_absolute != shortterm_priority_queue_root.first->priority) { - /* the next timer in the vtimer queue is not the next hwtimer */ - /* we have to remove the running hwtimer (and schedule a new one) */ - hwtimer_remove(hwtimer_id); - } - else { - /* the next vtimer is the next hwtimer, nothing to do */ - return 0; - } - } - - /* short term part of the next vtimer */ - hwtimer_next_absolute = shortterm_priority_queue_root.first->priority; - - uint32_t next = hwtimer_next_absolute + longterm_tick_start; - - /* current short term time */ - uint32_t now_ticks = hwtimer_now(); - uint32_t now = HWTIMER_TICKS_TO_US(now_ticks); - - if((next - HWTIMER_TICKS_TO_US(VTIMER_THRESHOLD) - now) > MICROSECONDS_PER_TICK ) { - DEBUG("truncating next (next - HWTIMER_TICKS_TO_US(VTIMER_THRESHOLD) - now): %lu\n", (next - HWTIMER_TICKS_TO_US(VTIMER_THRESHOLD) - now)); - next = now + HWTIMER_TICKS_TO_US(VTIMER_BACKOFF); - } - - DEBUG("update_shortterm: Set hwtimer to %" PRIu32 " (now=%lu)\n", next, now); - unsigned long offset_ticks = (unsigned long)HWTIMER_TICKS(next - now); - hwtimer_id = hwtimer_set(offset_ticks, vtimer_callback, NULL); - - return 0; -} - -void vtimer_callback_tick(vtimer_t *timer) -{ - (void) timer; - - DEBUG("vtimer_callback_tick().\n"); - - longterm_tick_start += MICROSECONDS_PER_TICK; - longterm_tick_timer.absolute.seconds += SECONDS_PER_TICK; - longterm_tick_timer.absolute.microseconds = MICROSECONDS_PER_TICK; // Should never change, just for clarity. - set_shortterm(&longterm_tick_timer); - - while (longterm_priority_queue_root.first) { - vtimer_t *timer = node_get_timer(longterm_priority_queue_root.first); - - if (timer->absolute.seconds == longterm_tick_timer.absolute.seconds) { - priority_queue_remove_head(&longterm_priority_queue_root); - set_shortterm(timer); - } - else { - break; - } - } -} - -static void vtimer_callback_msg(vtimer_t *timer) -{ - msg_t msg; - msg.type = timer->type; - msg.content.value = (unsigned int) timer->arg; - msg_send_int(&msg, timer->pid); -} - -static void vtimer_callback_wakeup(vtimer_t *timer) -{ - thread_wakeup(timer->pid); -} - -static void vtimer_callback_unlock(vtimer_t *timer) -{ - mutex_t *mutex = (mutex_t *) timer->arg; - mutex_unlock(mutex); -} - -static int set_shortterm(vtimer_t *timer) -{ - DEBUG("set_shortterm(): Absolute: %" PRIu32 " %" PRIu32 "\n", timer->absolute.seconds, timer->absolute.microseconds); - timer->priority_queue_entry.priority = timer->absolute.microseconds; - /* *** UGLY FIX BEGINS *** */ - /* Workaround for a bug in a so far undiscovered location which causes the - * vtimer to add the same timer twice, locking the system in an infinite - * loop inside priority_queue_add. */ - priority_queue_remove(&shortterm_priority_queue_root, timer_get_node(timer)); - /* *** UGLY FIX ENDS *** */ - priority_queue_add(&shortterm_priority_queue_root, timer_get_node(timer)); - return 1; -} - -void vtimer_callback(void *ptr) -{ - DEBUG("vtimer_callback ptr=%p\n", ptr); - (void) ptr; - - in_callback = true; - hwtimer_id = -1; - - /* get the vtimer that fired */ - vtimer_t *timer = node_get_timer(priority_queue_remove_head(&shortterm_priority_queue_root)); - - if (timer) { -#if ENABLE_DEBUG - vtimer_print(timer); -#endif - DEBUG("vtimer_callback(): Shooting %" PRIu32 ".\n", timer->absolute.microseconds); - - /* shoot timer */ - timer->action(timer); - } - else { - DEBUG("vtimer_callback(): spurious call.\n"); - } - - in_callback = false; - update_shortterm(); -} - -void normalize_to_tick(timex_t *time) -{ - DEBUG("Normalizing: %" PRIu32 " %" PRIu32 "\n", time->seconds, time->microseconds); - uint32_t seconds_tmp = time->seconds % SECONDS_PER_TICK; - time->seconds -= seconds_tmp; - uint32_t usecs_tmp = time->microseconds + (seconds_tmp * 1000000); - DEBUG("Normalizin2: %" PRIu32 " %" PRIu32 "\n", time->seconds, usecs_tmp); - - if (usecs_tmp < time->microseconds) { - usecs_tmp -= MICROSECONDS_PER_TICK; - time->seconds += SECONDS_PER_TICK; - } - - if (usecs_tmp > MICROSECONDS_PER_TICK) { - usecs_tmp -= MICROSECONDS_PER_TICK; - time->seconds += SECONDS_PER_TICK; - } - - time->microseconds = usecs_tmp; - DEBUG(" Result: %" PRIu32 " %" PRIu32 "\n", time->seconds, time->microseconds); -} - -static int vtimer_set(vtimer_t *timer) -{ - DEBUG("vtimer_set(): New timer. Offset: %" PRIu32 " %" PRIu32 "\n", timer->absolute.seconds, timer->absolute.microseconds); - - timex_t now; - vtimer_now(&now); - timer->absolute = timex_add(now, timer->absolute); - normalize_to_tick(&(timer->absolute)); - - DEBUG("vtimer_set(): Absolute: %" PRIu32 " %" PRIu32 "\n", timer->absolute.seconds, timer->absolute.microseconds); - DEBUG("vtimer_set(): NOW: %" PRIu32 " %" PRIu32 "\n", now.seconds, now.microseconds); - - int result = 0; - - if (timer->absolute.seconds == 0) { - if (timer->absolute.microseconds > 10) { - timer->absolute.microseconds -= 10; - } - } - - unsigned state = disableIRQ(); - if (timer->absolute.seconds != longterm_tick_timer.absolute.seconds) { - /* we're long-term */ - DEBUG("vtimer_set(): setting long_term\n"); - result = set_longterm(timer); - } - else { - DEBUG("vtimer_set(): setting short_term\n"); - - if (set_shortterm(timer)) { - /* delay update of next shortterm timer if we - * are called from within vtimer_callback. */ - - if (!in_callback) { - result = update_shortterm(); - } - } - } - restoreIRQ(state); - - return result; -} - -void vtimer_now(timex_t *out) -{ - uint32_t us = HWTIMER_TICKS_TO_US(hwtimer_now()) - longterm_tick_start; - static const uint32_t us_per_s = 1000ul * 1000ul; - - out->seconds = longterm_tick_timer.absolute.seconds + us / us_per_s; - out->microseconds = us % us_per_s; -} - -void vtimer_gettimeofday(struct timeval *tp) { - timex_t now; - vtimer_now(&now); - - tp->tv_sec = now.seconds; - tp->tv_usec = now.microseconds; -} - -void vtimer_get_localtime(struct tm *localt) -{ - timex_t now; - vtimer_now(&now); - - memset(localt, 0, sizeof(struct tm)); - localt->tm_sec = now.seconds % 60; - localt->tm_min = (now.seconds / 60) % 60; - localt->tm_hour = (now.seconds / 60 / 60) % 24; -} - -void vtimer_init(void) -{ - DEBUG("vtimer_init().\n"); - unsigned state = disableIRQ(); - - longterm_tick_start = 0; - - longterm_tick_timer.action = vtimer_callback_tick; - longterm_tick_timer.arg = NULL; - - longterm_tick_timer.absolute.seconds = 0; - longterm_tick_timer.absolute.microseconds = MICROSECONDS_PER_TICK; - - DEBUG("vtimer_init(): Setting longterm tick to %" PRIu32 "\n", longterm_tick_timer.absolute.microseconds); - - set_shortterm(&longterm_tick_timer); - update_shortterm(); - - restoreIRQ(state); -} - -int vtimer_set_wakeup(vtimer_t *t, timex_t interval, kernel_pid_t pid) -{ - t->action = vtimer_callback_wakeup; - t->arg = NULL; - t->absolute = interval; - t->pid = pid; - return vtimer_set(t); -} - -int vtimer_usleep(uint32_t usecs) -{ - timex_t offset = timex_set(0, usecs); - return vtimer_sleep(offset); -} - -int vtimer_sleep(timex_t time) -{ - /** - * Use spin lock for short periods. - * Assumes that hardware timer ticks are shorter than a second. - */ - if (time.seconds == 0) { - unsigned long ticks = HWTIMER_TICKS(time.microseconds); - if (ticks <= HWTIMER_SPIN_BARRIER) { - hwtimer_spin(ticks); - return 0; - } - } - - int ret; - vtimer_t t; - mutex_t mutex = MUTEX_INIT; - mutex_lock(&mutex); - - t.action = vtimer_callback_unlock; - t.arg = &mutex; - t.absolute = time; - - ret = vtimer_set(&t); - mutex_lock(&mutex); - return ret; -} - -void vtimer_remove(vtimer_t *t) -{ - unsigned irq_state = disableIRQ(); - - priority_queue_remove(&shortterm_priority_queue_root, timer_get_node(t)); - priority_queue_remove(&longterm_priority_queue_root, timer_get_node(t)); - update_shortterm(); - - restoreIRQ(irq_state); - -} - -void vtimer_set_msg(vtimer_t *t, timex_t interval, kernel_pid_t pid, uint16_t type, void *ptr) -{ - t->action = vtimer_callback_msg; - t->type = type; - t->arg = ptr; - t->absolute = interval; - t->pid = pid; - vtimer_set(t); -} - -int vtimer_msg_receive_timeout(msg_t *m, timex_t timeout) { - msg_t timeout_message; - timeout_message.type = MSG_TIMER; - timeout_message.content.ptr = (char *) &timeout_message; - - vtimer_t t; - vtimer_set_msg(&t, timeout, sched_active_pid, MSG_TIMER, &timeout_message); - msg_receive(m); - if (m->type == MSG_TIMER && m->content.ptr == (char *) &timeout_message) { - /* we hit the timeout */ - return -1; - } - else { - vtimer_remove(&t); - return 1; - } -} - -#if ENABLE_DEBUG - -void vtimer_print_short_queue(void){ - priority_queue_print(&shortterm_priority_queue_root); -} - -void vtimer_print_long_queue(void){ - priority_queue_print(&longterm_priority_queue_root); -} - -void vtimer_print(vtimer_t *t) -{ - printf("Seconds: %" PRIu32 " - Microseconds: %" PRIu32 "\n \ - action: %p\n \ - arg: %p\n \ - pid: %" PRIkernel_pid "\n", - t->absolute.seconds, t->absolute.microseconds, - t->action, - t->arg, - t->pid); -} - -#endif -- GitLab