Thanks to visit codestin.com
Credit goes to github.com

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
6 changes: 3 additions & 3 deletions libtock/alarm.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ extern "C" {
*/
typedef struct alarm {
uint32_t t0;
uint32_t expiration;
uint32_t interval;
subscribe_cb *callback;
void* ud;
struct alarm* next;
Expand All @@ -51,13 +51,13 @@ typedef struct alarm {
* The `alarm` parameter is allocated by the caller and must live as long as
* the alarm is outstanding.
*
* \param expiration the clock value to schedule the alarm for.
* \param interval the clock value to schedule the alarm for.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* \param interval the clock value to schedule the alarm for.
* \param interval How far in the future to schedule the alarm.

Probably want to move documentation away from implying an absolute clock value with the new interface

* \param callback a callback to be invoked when the alarm expires.
* \param userdata passed to the callback.
* \param a pointer to a new alarm_t to be used by the implementation to keep
* track of the alarm.
*/
void alarm_at(uint32_t expiration, subscribe_cb, void*, alarm_t *alarm);
void alarm_at(uint32_t interval, subscribe_cb, void*, alarm_t *alarm);

/** \brief Cancels an existing alarm.
*
Expand Down
44 changes: 19 additions & 25 deletions libtock/alarm_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ static void root_insert(alarm_t* alarm) {
alarm_t **cur = &root;
alarm_t *prev = NULL;
while (*cur != NULL) {
if (cmp_exp(alarm->t0, alarm->expiration, (*cur)->expiration) < 0) {
if (cmp_exp(alarm->t0, alarm->interval, (*cur)->interval) < 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be referenced from alarm->t0 if comparing intervals now? I think this method of scheduling doesn't quite work anymore, this list ordering assumes a fixed time, but really we need to somehow understand what amount of an interval has expired when sorting the next one into the list.

// insert before
alarm_t *tmp = *cur;
*cur = alarm;
Expand Down Expand Up @@ -68,26 +68,26 @@ static void callback( __attribute__ ((unused)) int unused0,
uint32_t now = alarm_read();
// has the alarm not expired yet? (distance from `now` has to be larger or
// equal to distance from current clock value.
if (alarm->expiration - alarm->t0 > now - alarm->t0) {
alarm_internal_set(alarm->expiration);
if (alarm->interval > now - alarm->t0) {
alarm_internal_relative_set(alarm->interval);
break;
} else {
root_pop();

if (alarm->callback) {
tock_enqueue(alarm->callback, now, alarm->expiration, 0, alarm->ud);
tock_enqueue(alarm->callback, now, alarm->interval, 0, alarm->ud);
}
}
}
}

void alarm_at(uint32_t expiration, subscribe_cb cb, void* ud, alarm_t* alarm) {
alarm->t0 = alarm_read();
alarm->expiration = expiration;
alarm->callback = cb;
alarm->ud = ud;
alarm->prev = NULL;
alarm->next = NULL;
void alarm_at(uint32_t interval, subscribe_cb cb, void* ud, alarm_t* alarm) {
alarm->t0 = alarm_read();
alarm->interval = interval;
alarm->callback = cb;
alarm->ud = ud;
alarm->prev = NULL;
alarm->next = NULL;

root_insert(alarm);
int i = 0;
Expand All @@ -97,7 +97,7 @@ void alarm_at(uint32_t expiration, subscribe_cb cb, void* ud, alarm_t* alarm) {

if (root_peek() == alarm) {
alarm_internal_subscribe((subscribe_cb*)callback, NULL);
alarm_internal_set(alarm->expiration);
alarm_internal_relative_set(alarm->interval);
}
}

Expand All @@ -112,7 +112,7 @@ void alarm_cancel(alarm_t* alarm) {
if (root == alarm) {
root = alarm->next;
if (root != NULL) {
alarm_internal_set(root->expiration);
alarm_internal_relative_set(root->interval);
}
}

Expand All @@ -128,11 +128,9 @@ uint32_t alarm_read(void) {
// Timer implementation

void timer_in(uint32_t ms, subscribe_cb cb, void* ud, tock_timer_t *timer) {
uint32_t frequency = alarm_internal_frequency();
uint32_t interval = (ms / 1000) * frequency + (ms % 1000) * (frequency / 1000);
uint32_t now = alarm_read();
uint32_t expiration = now + interval;
alarm_at(expiration, cb, ud, &timer->alarm);
uint32_t frequency = alarm_internal_frequency();
uint32_t interval = (ms / 1000) * frequency + (ms % 1000) * (frequency / 1000);
alarm_at(interval, cb, ud, &timer->alarm);
}

static void repeating_cb( uint32_t now,
Expand All @@ -141,9 +139,8 @@ static void repeating_cb( uint32_t now,
void* ud) {
tock_timer_t* repeating = (tock_timer_t*)ud;
uint32_t interval = repeating->interval;
uint32_t expiration = now + interval;
uint32_t cur_exp = repeating->alarm.expiration;
alarm_at(expiration, (subscribe_cb*)repeating_cb,
uint32_t cur_exp = repeating->alarm.interval;
alarm_at(interval, (subscribe_cb*)repeating_cb,
(void*)repeating, &repeating->alarm);
repeating->cb(now, cur_exp, 0, repeating->ud);
}
Expand All @@ -156,10 +153,7 @@ void timer_every(uint32_t ms, subscribe_cb cb, void* ud, tock_timer_t* repeating
repeating->cb = cb;
repeating->ud = ud;

uint32_t now = alarm_read();
uint32_t expiration = now + interval;

alarm_at(expiration, (subscribe_cb*)repeating_cb,
alarm_at(interval, (subscribe_cb*)repeating_cb,
(void*)repeating, &repeating->alarm);
}

Expand Down
9 changes: 9 additions & 0 deletions libtock/internal/alarm.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ int alarm_internal_subscribe(subscribe_cb cb, void *userdata);
*/
int alarm_internal_set(uint32_t tics);

/*
* Starts a oneshot alarm
*
* expiration - absolute expiration value in clock tics relative to now
*
* Side-effects: cancels any existing/outstanding timers
*/
int alarm_internal_relative_set(uint32_t delta_tics);


/*
* Stops any outstanding hardware alarm.
Expand Down
4 changes: 4 additions & 0 deletions libtock/internal/alarm_internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ int alarm_internal_set(uint32_t tics) {
return command(DRIVER_NUM_ALARM, 4, (int)tics, 0);
}

int alarm_internal_relative_set(uint32_t delta_tics) {
return command(DRIVER_NUM_ALARM, 5, (int)delta_tics, 0);
}

int alarm_internal_stop(void) {
return command(DRIVER_NUM_ALARM, 3, 0, 0);
}
Expand Down