Something went wrong. Try again.
A modern, network-enabled music player platform built on Rockbox technology. rockboxd.tsiry-sandratraina.com
rust deno navidrome airplay libadwaita zig mpris snapcast mpd rockbox audio subsonic
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
/**************************************************************************** * Tick-based interval timers/one-shots - be mindful this is not really * intended for continuous timers but for events that need to run for a short * time and be cancelled without further software intervention. ****************************************************************************/
#include "config.h"#include "system.h" /* TIME_AFTER */#include "kernel.h"#include "timeout.h"#include "general.h"
/* list of active timeout events */static struct timeout *tmo_list[MAX_NUM_TIMEOUTS+1];
/* timeout tick task - calls event handlers when they expire * Event handlers may alter expiration, callback and data during operation. */static void timeout_tick(void){ unsigned long tick = current_tick; struct timeout **p = tmo_list; struct timeout *curr;
for(curr = *p; curr != NULL; curr = *(++p)) { int ticks;
if(TIME_BEFORE(tick, curr->expires)) continue;
/* this event has expired - call callback */ ticks = curr->callback(curr); if(ticks > 0) { curr->expires = tick + ticks; /* reload */ } else { timeout_cancel(curr); /* cancel */ } }}
/* Cancels a timeout callback - can be called from the ISR */void timeout_cancel(struct timeout *tmo){ int oldlevel = disable_irq_save(); int rc = remove_array_ptr((void **)tmo_list, tmo);
if(rc >= 0 && *tmo_list == NULL) { tick_remove_task(timeout_tick); /* Last one - remove task */ }
restore_irq(oldlevel);}
/* Adds a timeout callback - calling with an active timeout resets the interval - can be called from the ISR */void timeout_register(struct timeout *tmo, timeout_cb_type callback, int ticks, intptr_t data){ int oldlevel; void **arr, **p;
if(tmo == NULL) return;
oldlevel = disable_irq_save();
/* See if this one is already registered */ arr = (void **)tmo_list; p = find_array_ptr(arr, tmo);
if(p - arr < MAX_NUM_TIMEOUTS) { /* Vacancy */ if(*p == NULL) { /* Not present */ if(*tmo_list == NULL) { tick_add_task(timeout_tick); /* First one - add task */ }
*p = tmo; }
tmo->callback = callback; tmo->data = data; tmo->expires = current_tick + ticks; }
restore_irq(oldlevel);}