Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 35 additions & 4 deletions sys/evtimer/evtimer.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*
* Copyright (C) 2016 Freie Universität Berlin
* Copyright (C) 2016 Kaspar Schleiser <[email protected]>
*
* This file is subject to the terms and conditions of the GNU Lesser
Expand All @@ -14,9 +15,13 @@
* @brief event timer implementation
*
* @author Kaspar Schleiser <[email protected]>
* @author Martine Lenders <[email protected]>
*
* @}
*/

#include <stdio.h>

#include "evtimer.h"
#include "div.h"
#include "irq.h"
Expand All @@ -29,6 +34,7 @@
static void _add_event_to_list(evtimer_event_t *list, evtimer_event_t *event)
{
uint32_t delta_sum = 0;

while (list->next) {
evtimer_event_t *list_entry = list->next;
if ((list_entry->offset + delta_sum) > event->offset) {
Expand Down Expand Up @@ -68,6 +74,7 @@ static void _del_event_from_list(evtimer_event_t *list, evtimer_event_t *event)
static void _set_timer(xtimer_t *timer, uint32_t offset)
{
uint64_t offset_in_us = (uint64_t)offset * 1000;

DEBUG("evtimer: now=%"PRIu32" setting xtimer to %"PRIu32":%"PRIu32"\n", xtimer_now(),
(uint32_t)(offset_in_us>>32), (uint32_t)(offset_in_us));
_xtimer_set64(timer, offset_in_us, offset_in_us>>32);
Expand Down Expand Up @@ -111,10 +118,11 @@ static void _update_head_offset(evtimer_t *evtimer)
void evtimer_add(evtimer_t *evtimer, evtimer_event_t *event)
{
unsigned state = irq_disable();

DEBUG("evtimer_add(): adding event with offset %"PRIu32"\n", event->offset);

_update_head_offset(evtimer);
_add_event_to_list((evtimer_event_t*)&evtimer->events, event);
_add_event_to_list(evtimer->events, event);

if (evtimer->events == event) {
_set_timer(&evtimer->timer, event->offset);
Expand All @@ -125,16 +133,40 @@ void evtimer_add(evtimer_t *evtimer, evtimer_event_t *event)
void evtimer_del(evtimer_t *evtimer, evtimer_event_t *event)
{
unsigned state = irq_disable();

DEBUG("evtimer_del(): removing event with offset %"PRIu32"\n", event->offset);
_update_head_offset(evtimer);
_del_event_from_list((evtimer_event_t*)&evtimer->events, event);
_update_timer(evtimer);
irq_restore(state);
}

bool evtimer_peek(evtimer_t *evtimer, evtimer_peek_cb_t *peek_cb,
void *peek_ctx, uint64_t limit)
{
bool res = false;
unsigned state = irq_disable();
evtimer_event_t *event = evtimer->events;
uint64_t acc = (event == NULL) ? 0 : event->offset;

DEBUG("evtimer_peek(): searching events in the next %"PRIu32" ms\n",
limit);
while((event != NULL) && (acc <= limit)) {
if (peek_cb(event, peek_ctx)) {
res = true;
break;
}
event = event->next;
acc += event->offset;
}
irq_restore(state);
return res;
}

static evtimer_event_t *_get_next(evtimer_t *evtimer)
{
evtimer_event_t *event = evtimer->events;

if (event && (event->offset == 0)) {
evtimer->events = event->next;
return event;
Expand Down Expand Up @@ -172,14 +204,13 @@ void evtimer_init(evtimer_t *evtimer, void(*handler)(void*))
evtimer->events = NULL;
}

#if ENABLE_DEBUG == 1
void evtimer_print(evtimer_t *evtimer)
{
evtimer_event_t *list = evtimer->events;

while (list->next) {
evtimer_event_t *list_entry = list->next;
DEBUG("ev offset=%u\n", (unsigned)list_entry->offset);
printf("ev offset=%u\n", (unsigned)list_entry->offset);
list = list->next;
}
}
#endif
25 changes: 24 additions & 1 deletion sys/include/evtimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*
* Compared to xtimer, evtimer offers:
*
* - only relative 32bit milisecond timer values
* - only relative 32bit millisecond timer values
* Events can be scheduled with a relative offset of up to ~49.7 days in the
* future.
* For time-critical stuff, use xtimer!
Expand All @@ -39,17 +39,22 @@
#ifndef EVTIMER_H
#define EVTIMER_H

#include <stdbool.h>
#include <stdint.h>

#include "kernel_types.h"
#include "msg.h"
#include "xtimer.h"

#ifdef __cplusplus
extern "C" {
#endif

#define EVTIMER_PEEK_LIMIT_INFINITY (UINT64_MAX)

/** forward declaration */
typedef struct evtimer_event evtimer_event_t;
typedef bool (*evtimer_peek_cb_t)(evtimer_event_t *event, void *ctx);

typedef struct {
xtimer_t timer;
Expand All @@ -68,8 +73,26 @@ typedef struct {

void evtimer_init(evtimer_t *evtimer, void(*handler)(void*));
void evtimer_add(evtimer_t *evtimer, evtimer_event_t *event);

static inline void evtimer_add_msg(evtimer_t *evtimer,
evtimer_msg_event_t *event,
kernel_pid_t target_pid)
{
/* use sender_pid field to get target_pid into callback function */
event->msg.sender_pid = target_pid;
evtimer_add(evtimer, &event->event);
}

void evtimer_del(evtimer_t *evtimer, evtimer_event_t *event);
bool evtimer_peek(evtimer_t *evtimer, evtimer_peek_cb_t *peek_cb,
void *peek_ctx, uint64_t limit);
void evtimer_msg_handler(void *arg);

static inline void evtimer_init_msg(evtimer_t *evtimer)
{
evtimer_init(evtimer, evtimer_msg_handler);
}

void evtimer_print(evtimer_t *evtimer);

#ifdef __cplusplus
Expand Down