Fix timer setTimeout issue and some coding style issues (#459)

This commit is contained in:
Wenyong Huang 2020-12-04 18:07:52 +08:00 committed by GitHub
parent 2f530e67fc
commit 5176fe2595
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 196 additions and 155 deletions

View File

@ -8,17 +8,19 @@
#include "../app-manager/module_wasm_app.h" #include "../app-manager/module_wasm_app.h"
#include "timer_native_api.h" #include "timer_native_api.h"
static bool timer_thread_run = true;
bh_list g_timer_ctx_list;
korp_cond g_timer_ctx_list_cond;
korp_mutex g_timer_ctx_list_mutex;
typedef struct { typedef struct {
bh_list_link l; bh_list_link l;
timer_ctx_t timer_ctx; timer_ctx_t timer_ctx;
} timer_ctx_node_t; } timer_ctx_node_t;
void wasm_timer_callback(timer_id_t id, unsigned int mod_id) static bool timer_thread_run = true;
static bh_list g_timer_ctx_list;
static korp_cond g_timer_ctx_list_cond;
static korp_mutex g_timer_ctx_list_mutex;
void
wasm_timer_callback(timer_id_t id, unsigned int mod_id)
{ {
module_data* module = module_data_list_lookup_id(mod_id); module_data* module = module_data_list_lookup_id(mod_id);
if (module == NULL) if (module == NULL)
@ -29,13 +31,14 @@ void wasm_timer_callback(timer_id_t id, unsigned int mod_id)
bh_post_msg(module->queue, TIMER_EVENT_WASM, (char *)(uintptr_t)id, 0); bh_post_msg(module->queue, TIMER_EVENT_WASM, (char *)(uintptr_t)id, 0);
} }
/// /**
/// why we create a separate link for module timer contexts * why we create a separate link for module timer contexts
/// rather than traverse the module list? * rather than traverse the module list?
/// It helps to reduce the lock frequency for the module list. * It helps to reduce the lock frequency for the module list.
/// Also when we lock the module list and then call the callback for * Also when we lock the module list and then call the callback for
/// timer expire, the callback is request the list lock again for lookup * timer expire, the callback is request the list lock again for lookup
/// the module from module id. It is for avoiding that situation. * the module from module id. It is for avoiding that situation.
*/
void * thread_modulers_timer_check(void * arg) void * thread_modulers_timer_check(void * arg)
{ {
@ -68,37 +71,41 @@ void * thread_modulers_timer_check(void * arg)
return NULL; return NULL;
} }
void wakeup_modules_timer_thread(timer_ctx_t ctx) void
wakeup_modules_timer_thread(timer_ctx_t ctx)
{ {
os_mutex_lock(&g_timer_ctx_list_mutex); os_mutex_lock(&g_timer_ctx_list_mutex);
os_cond_signal(&g_timer_ctx_list_cond); os_cond_signal(&g_timer_ctx_list_cond);
os_mutex_unlock(&g_timer_ctx_list_mutex); os_mutex_unlock(&g_timer_ctx_list_mutex);
} }
void init_wasm_timer() void
init_wasm_timer()
{ {
korp_tid tm_tid; korp_tid tm_tid;
bh_list_init(&g_timer_ctx_list); bh_list_init(&g_timer_ctx_list);
os_cond_init(&g_timer_ctx_list_cond); os_cond_init(&g_timer_ctx_list_cond);
/* temp solution for: thread_modulers_timer_check thread would recursive lock the mutex */ /* temp solution for: thread_modulers_timer_check thread
would recursive lock the mutex */
os_recursive_mutex_init(&g_timer_ctx_list_mutex); os_recursive_mutex_init(&g_timer_ctx_list_mutex);
os_thread_create(&tm_tid, thread_modulers_timer_check, os_thread_create(&tm_tid, thread_modulers_timer_check,
NULL, BH_APPLET_PRESERVED_STACK_SIZE); NULL, BH_APPLET_PRESERVED_STACK_SIZE);
} }
void exit_wasm_timer() void
exit_wasm_timer()
{ {
timer_thread_run = false; timer_thread_run = false;
} }
timer_ctx_t create_wasm_timer_ctx(unsigned int module_id, int prealloc_num) timer_ctx_t
create_wasm_timer_ctx(unsigned int module_id, int prealloc_num)
{ {
timer_ctx_t ctx = create_timer_ctx(wasm_timer_callback, timer_ctx_t ctx = create_timer_ctx(wasm_timer_callback,
wakeup_modules_timer_thread, wakeup_modules_timer_thread,
prealloc_num, prealloc_num, module_id);
module_id);
if (ctx == NULL) if (ctx == NULL)
return NULL; return NULL;
@ -119,11 +126,14 @@ timer_ctx_t create_wasm_timer_ctx(unsigned int module_id, int prealloc_num)
return ctx; return ctx;
} }
void destroy_module_timer_ctx(unsigned int module_id) void
destroy_module_timer_ctx(unsigned int module_id)
{ {
timer_ctx_node_t* elem;
os_mutex_lock(&g_timer_ctx_list_mutex); os_mutex_lock(&g_timer_ctx_list_mutex);
timer_ctx_node_t* elem = (timer_ctx_node_t*) elem = (timer_ctx_node_t*)
bh_list_first_elem(&g_timer_ctx_list); bh_list_first_elem(&g_timer_ctx_list);
while (elem) { while (elem) {
if (timer_ctx_get_owner(elem->timer_ctx) == module_id) { if (timer_ctx_get_owner(elem->timer_ctx) == module_id) {
bh_list_remove(&g_timer_ctx_list, elem); bh_list_remove(&g_timer_ctx_list, elem);
@ -137,7 +147,8 @@ void destroy_module_timer_ctx(unsigned int module_id)
os_mutex_unlock(&g_timer_ctx_list_mutex); os_mutex_unlock(&g_timer_ctx_list_mutex);
} }
timer_ctx_t get_wasm_timer_ctx(wasm_module_inst_t module_inst) timer_ctx_t
get_wasm_timer_ctx(wasm_module_inst_t module_inst)
{ {
module_data * m = app_manager_get_module_data(Module_WASM_App, module_data * m = app_manager_get_module_data(Module_WASM_App,
module_inst); module_inst);
@ -184,8 +195,6 @@ wasm_timer_restart(wasm_exec_env_t exec_env,
sys_timer_restart(timer_ctx, timer_id, interval); sys_timer_restart(timer_ctx, timer_id, interval);
} }
extern uint32 get_sys_tick_ms();
uint32 uint32
wasm_get_sys_tick_ms(wasm_exec_env_t exec_env) wasm_get_sys_tick_ms(wasm_exec_env_t exec_env)
{ {

View File

@ -198,17 +198,16 @@ void release_module(module_data *m_data)
APP_MGR_FREE(m_data); APP_MGR_FREE(m_data);
} }
int check_modules_timer_expiry() uint32 check_modules_timer_expiry()
{ {
os_mutex_lock(&module_data_list_lock); os_mutex_lock(&module_data_list_lock);
module_data *p = module_data_list; module_data *p = module_data_list;
int ms_to_expiry = -1; uint32 ms_to_expiry = (uint32)-1;
while (p) { while (p) {
uint32 next = get_expiry_ms(p->timer_ctx);
int next = get_expiry_ms(p->timer_ctx); if (next != (uint32)-1) {
if (next != -1) { if (ms_to_expiry == (uint32)-1 || ms_to_expiry > next)
if (ms_to_expiry == -1 || ms_to_expiry > next)
ms_to_expiry = next; ms_to_expiry = next;
} }

View File

@ -5,101 +5,111 @@
#include "runtime_timer.h" #include "runtime_timer.h"
#define PRINT(...) #if 1
//#define PRINT printf #define PRINT(...) (void)0
#else
#define PRINT printf
#endif
typedef struct _app_timer { typedef struct _app_timer {
struct _app_timer * next; struct _app_timer * next;
uint32 id; uint32 id;
unsigned int interval; uint32 interval;
uint64 expiry; uint64 expiry;
bool is_periodic; bool is_periodic;
} app_timer_t; } app_timer_t;
struct _timer_ctx { typedef struct _timer_ctx {
app_timer_t * g_app_timers; app_timer_t *app_timers;
app_timer_t * idle_timers; app_timer_t *idle_timers;
app_timer_t * free_timers; app_timer_t *free_timers;
unsigned int g_max_id; uint32 max_timer_id;
int pre_allocated; int pre_allocated;
unsigned int owner; uint32 owner;
//add mutext and conditions /* mutex and condition */
korp_cond cond; korp_cond cond;
korp_mutex mutex; korp_mutex mutex;
timer_callback_f timer_callback; timer_callback_f timer_callback;
check_timer_expiry_f refresh_checker; check_timer_expiry_f refresh_checker;
}; } *timer_ctx_t;
uint64 bh_get_tick_ms() uint64
bh_get_tick_ms()
{ {
return os_time_get_boot_microsecond() / 1000; return os_time_get_boot_microsecond() / 1000;
} }
uint32 bh_get_elpased_ms(uint32 * last_system_clock) uint32
bh_get_elpased_ms(uint32 *last_system_clock)
{ {
uint32 elpased_ms; uint32 elpased_ms;
/* attention: the bh_get_tick_ms() return 64 bits integer, but
// attention: the bh_get_tick_ms() return 64 bits integer. the bh_get_elpased_ms() is designed to use 32 bits clock count */
// but the bh_get_elpased_ms() is designed to use 32 bits clock count.
uint32 now = (uint32)bh_get_tick_ms(); uint32 now = (uint32)bh_get_tick_ms();
// system clock overrun /* system clock overrun */
if (now < *last_system_clock) { if (now < *last_system_clock) {
elpased_ms = now + (0xFFFFFFFF - *last_system_clock) + 1; PRINT("system clock overrun!\n");
} else { elpased_ms = now + (UINT32_MAX - *last_system_clock) + 1;
}
else {
elpased_ms = now - *last_system_clock; elpased_ms = now - *last_system_clock;
} }
*last_system_clock = now; *last_system_clock = now;
return elpased_ms; return elpased_ms;
} }
static app_timer_t * remove_timer_from(timer_ctx_t ctx, uint32 timer_id, static app_timer_t *
bool active_list) remove_timer_from(timer_ctx_t ctx, uint32 timer_id, bool active_list)
{ {
app_timer_t **head, *prev, *t;
os_mutex_lock(&ctx->mutex); os_mutex_lock(&ctx->mutex);
app_timer_t ** head;
if (active_list) if (active_list)
head = &ctx->g_app_timers; head = &ctx->app_timers;
else else
head = &ctx->idle_timers; head = &ctx->idle_timers;
app_timer_t * t = *head; t = *head;
app_timer_t * prev = NULL; prev = NULL;
while (t) { while (t) {
if (t->id == timer_id) { if (t->id == timer_id) {
if (prev == NULL) { if (prev == NULL) {
*head = t->next; *head = t->next;
PRINT("removed timer [%d] at head from list %d\n", t->id, active_list); PRINT("removed timer [%d] at head from list %d\n",
} else { t->id, active_list);
}
else {
prev->next = t->next; prev->next = t->next;
PRINT("removed timer [%d] after [%d] from list %d\n", t->id, prev->id, active_list); PRINT("removed timer [%d] after [%d] from list %d\n",
t->id, prev->id, active_list);
} }
os_mutex_unlock(&ctx->mutex); os_mutex_unlock(&ctx->mutex);
if (active_list && prev == NULL && ctx->refresh_checker) if (active_list && prev == NULL && ctx->refresh_checker)
ctx->refresh_checker(ctx); ctx->refresh_checker(ctx);
return t; return t;
} else { }
else {
prev = t; prev = t;
t = t->next; t = t->next;
} }
} }
os_mutex_unlock(&ctx->mutex); os_mutex_unlock(&ctx->mutex);
return NULL; return NULL;
} }
static app_timer_t * remove_timer(timer_ctx_t ctx, uint32 timer_id, static app_timer_t *
bool * active) remove_timer(timer_ctx_t ctx, uint32 timer_id, bool *active)
{ {
app_timer_t* t = remove_timer_from(ctx, timer_id, true); app_timer_t *t = remove_timer_from(ctx, timer_id, true);
if (t) { if (t) {
if (active) if (active)
*active = true; *active = true;
@ -111,61 +121,63 @@ static app_timer_t * remove_timer(timer_ctx_t ctx, uint32 timer_id,
return remove_timer_from(ctx, timer_id, false); return remove_timer_from(ctx, timer_id, false);
} }
static void reschedule_timer(timer_ctx_t ctx, app_timer_t * timer) static void
reschedule_timer(timer_ctx_t ctx, app_timer_t *timer)
{ {
app_timer_t *t;
app_timer_t *prev = NULL;
os_mutex_lock(&ctx->mutex); os_mutex_lock(&ctx->mutex);
app_timer_t * t = ctx->g_app_timers;
app_timer_t * prev = NULL;
t = ctx->app_timers;
timer->next = NULL; timer->next = NULL;
timer->expiry = bh_get_tick_ms() + timer->interval; timer->expiry = bh_get_tick_ms() + timer->interval;
while (t) { while (t) {
if (timer->expiry < t->expiry) { if (timer->expiry < t->expiry) {
if (prev == NULL) { if (prev == NULL) {
timer->next = ctx->g_app_timers; timer->next = ctx->app_timers;
ctx->g_app_timers = timer; ctx->app_timers = timer;
PRINT("rescheduled timer [%d] at head\n", timer->id); PRINT("rescheduled timer [%d] at head\n", timer->id);
} else { }
else {
timer->next = t; timer->next = t;
prev->next = timer; prev->next = timer;
PRINT("rescheduled timer [%d] after [%d]\n", timer->id, prev->id); PRINT("rescheduled timer [%d] after [%d]\n",
timer->id, prev->id);
} }
os_mutex_unlock(&ctx->mutex); goto out;
}
// ensure the refresh_checker() is called out of the lock else {
if (prev == NULL && ctx->refresh_checker)
ctx->refresh_checker(ctx);
return;
} else {
prev = t; prev = t;
t = t->next; t = t->next;
} }
} }
if (prev) { if (prev) {
// insert to the list end /* insert to the list end */
prev->next = timer; prev->next = timer;
PRINT("rescheduled timer [%d] at end, after [%d]\n", timer->id, prev->id); PRINT("rescheduled timer [%d] at end, after [%d]\n",
} else { timer->id, prev->id);
// insert at the begin }
bh_assert(ctx->g_app_timers == NULL); else {
ctx->g_app_timers = timer; /* insert at the begin */
bh_assert(ctx->app_timers == NULL);
ctx->app_timers = timer;
PRINT("rescheduled timer [%d] as first\n", timer->id); PRINT("rescheduled timer [%d] as first\n", timer->id);
} }
out:
os_mutex_unlock(&ctx->mutex); os_mutex_unlock(&ctx->mutex);
// ensure the refresh_checker() is called out of the lock /* ensure the refresh_checker() is called out of the lock */
if (prev == NULL && ctx->refresh_checker) if (prev == NULL && ctx->refresh_checker)
ctx->refresh_checker(ctx); ctx->refresh_checker(ctx);
} }
static void release_timer(timer_ctx_t ctx, app_timer_t * t) static void
release_timer(timer_ctx_t ctx, app_timer_t *t)
{ {
if (ctx->pre_allocated) { if (ctx->pre_allocated) {
os_mutex_lock(&ctx->mutex); os_mutex_lock(&ctx->mutex);
@ -173,15 +185,18 @@ static void release_timer(timer_ctx_t ctx, app_timer_t * t)
ctx->free_timers = t; ctx->free_timers = t;
PRINT("recycle timer :%d\n", t->id); PRINT("recycle timer :%d\n", t->id);
os_mutex_unlock(&ctx->mutex); os_mutex_unlock(&ctx->mutex);
} else { }
else {
PRINT("destroy timer :%d\n", t->id); PRINT("destroy timer :%d\n", t->id);
BH_FREE(t); BH_FREE(t);
} }
} }
void release_timer_list(app_timer_t ** p_list) void
release_timer_list(app_timer_t **p_list)
{ {
app_timer_t *t = *p_list; app_timer_t *t = *p_list;
while (t) { while (t) {
app_timer_t *next = t->next; app_timer_t *next = t->next;
PRINT("destroy timer list:%d\n", t->id); PRINT("destroy timer list:%d\n", t->id);
@ -193,18 +208,19 @@ void release_timer_list(app_timer_t ** p_list)
} }
/* /*
* * API exposed
* API exposed
*
*/ */
timer_ctx_t create_timer_ctx(timer_callback_f timer_handler, timer_ctx_t
check_timer_expiry_f expiery_checker, int prealloc_num, create_timer_ctx(timer_callback_f timer_handler,
unsigned int owner) check_timer_expiry_f expiery_checker,
int prealloc_num, unsigned int owner)
{ {
timer_ctx_t ctx = (timer_ctx_t) BH_MALLOC(sizeof(struct _timer_ctx)); timer_ctx_t ctx = (timer_ctx_t)BH_MALLOC(sizeof(struct _timer_ctx));
if (ctx == NULL) if (ctx == NULL)
return NULL; return NULL;
memset(ctx, 0, sizeof(struct _timer_ctx)); memset(ctx, 0, sizeof(struct _timer_ctx));
ctx->timer_callback = timer_handler; ctx->timer_callback = timer_handler;
@ -213,7 +229,8 @@ timer_ctx_t create_timer_ctx(timer_callback_f timer_handler,
ctx->owner = owner; ctx->owner = owner;
while (prealloc_num > 0) { while (prealloc_num > 0) {
app_timer_t *timer = (app_timer_t*) BH_MALLOC(sizeof(app_timer_t)); app_timer_t *timer = (app_timer_t*)BH_MALLOC(sizeof(app_timer_t));
if (timer == NULL) if (timer == NULL)
goto cleanup; goto cleanup;
@ -223,15 +240,18 @@ timer_ctx_t create_timer_ctx(timer_callback_f timer_handler,
prealloc_num--; prealloc_num--;
} }
os_cond_init(&ctx->cond); if (os_cond_init(&ctx->cond) != 0)
os_mutex_init(&ctx->mutex); goto cleanup;
if (os_mutex_init(&ctx->mutex) != 0) {
os_cond_destroy(&ctx->cond);
goto cleanup;
}
PRINT("timer ctx created. pre-alloc: %d\n", ctx->pre_allocated); PRINT("timer ctx created. pre-alloc: %d\n", ctx->pre_allocated);
return ctx; return ctx;
cleanup: cleanup:
if (ctx) { if (ctx) {
release_timer_list(&ctx->free_timers); release_timer_list(&ctx->free_timers);
BH_FREE(ctx); BH_FREE(ctx);
@ -240,10 +260,11 @@ cleanup:
return NULL; return NULL;
} }
void destroy_timer_ctx(timer_ctx_t ctx) void
destroy_timer_ctx(timer_ctx_t ctx)
{ {
while (ctx->free_timers) { while (ctx->free_timers) {
void * tmp = ctx->free_timers; void *tmp = ctx->free_timers;
ctx->free_timers = ctx->free_timers->next; ctx->free_timers = ctx->free_timers->next;
BH_FREE(tmp); BH_FREE(tmp);
} }
@ -255,12 +276,14 @@ void destroy_timer_ctx(timer_ctx_t ctx)
BH_FREE(ctx); BH_FREE(ctx);
} }
unsigned int timer_ctx_get_owner(timer_ctx_t ctx) unsigned int
timer_ctx_get_owner(timer_ctx_t ctx)
{ {
return ctx->owner; return ctx->owner;
} }
void add_idle_timer(timer_ctx_t ctx, app_timer_t * timer) void
add_idle_timer(timer_ctx_t ctx, app_timer_t * timer)
{ {
os_mutex_lock(&ctx->mutex); os_mutex_lock(&ctx->mutex);
timer->next = ctx->idle_timers; timer->next = ctx->idle_timers;
@ -268,31 +291,33 @@ void add_idle_timer(timer_ctx_t ctx, app_timer_t * timer)
os_mutex_unlock(&ctx->mutex); os_mutex_unlock(&ctx->mutex);
} }
uint32 sys_create_timer(timer_ctx_t ctx, int interval, bool is_period, uint32
bool auto_start) sys_create_timer(timer_ctx_t ctx, int interval, bool is_period,
bool auto_start)
{ {
app_timer_t *timer; app_timer_t *timer;
if (ctx->pre_allocated) { if (ctx->pre_allocated) {
if (ctx->free_timers == NULL) if (ctx->free_timers == NULL) {
return (uint32)-1; return (uint32)-1;
}
else { else {
timer = ctx->free_timers; timer = ctx->free_timers;
ctx->free_timers = timer->next; ctx->free_timers = timer->next;
} }
} else { }
timer = (app_timer_t*) BH_MALLOC(sizeof(app_timer_t)); else {
timer = (app_timer_t*)BH_MALLOC(sizeof(app_timer_t));
if (timer == NULL) if (timer == NULL)
return (uint32)-1; return (uint32)-1;
} }
memset(timer, 0, sizeof(*timer)); memset(timer, 0, sizeof(*timer));
ctx->g_max_id++; ctx->max_timer_id++;
if (ctx->g_max_id == (uint32)-1) if (ctx->max_timer_id == (uint32)-1)
ctx->g_max_id++; ctx->max_timer_id++;
timer->id = ctx->g_max_id; timer->id = ctx->max_timer_id;
timer->interval = (uint32)interval; timer->interval = (uint32)interval;
timer->is_periodic = is_period; timer->is_periodic = is_period;
@ -304,10 +329,12 @@ uint32 sys_create_timer(timer_ctx_t ctx, int interval, bool is_period,
return timer->id; return timer->id;
} }
bool sys_timer_cancel(timer_ctx_t ctx, uint32 timer_id) bool
sys_timer_cancel(timer_ctx_t ctx, uint32 timer_id)
{ {
bool from_active; bool from_active;
app_timer_t * t = remove_timer(ctx, timer_id, &from_active); app_timer_t * t = remove_timer(ctx, timer_id, &from_active);
if (t == NULL) if (t == NULL)
return false; return false;
@ -317,10 +344,12 @@ bool sys_timer_cancel(timer_ctx_t ctx, uint32 timer_id)
return from_active; return from_active;
} }
bool sys_timer_destroy(timer_ctx_t ctx, uint32 timer_id) bool
sys_timer_destroy(timer_ctx_t ctx, uint32 timer_id)
{ {
bool from_active; bool from_active;
app_timer_t * t = remove_timer(ctx, timer_id, &from_active); app_timer_t * t = remove_timer(ctx, timer_id, &from_active);
if (t == NULL) if (t == NULL)
return false; return false;
@ -330,14 +359,15 @@ bool sys_timer_destroy(timer_ctx_t ctx, uint32 timer_id)
return true; return true;
} }
bool sys_timer_restart(timer_ctx_t ctx, uint32 timer_id, int interval) bool
sys_timer_restart(timer_ctx_t ctx, uint32 timer_id, int interval)
{ {
app_timer_t * t = remove_timer(ctx, timer_id, NULL); app_timer_t * t = remove_timer(ctx, timer_id, NULL);
if (t == NULL) if (t == NULL)
return false; return false;
if (interval > 0) t->interval = (uint32)interval;
t->interval = (uint32)interval;
reschedule_timer(ctx, t); reschedule_timer(ctx, t);
@ -346,44 +376,46 @@ bool sys_timer_restart(timer_ctx_t ctx, uint32 timer_id, int interval)
} }
/* /*
*
*
* API called by the timer manager from another thread or the kernel timer handler * API called by the timer manager from another thread or the kernel timer handler
*
*
*/ */
// lookup the app queue by the module name /**
//post a timeout message to the app queue * lookup the app queue by the module name
// * post a timeout message to the app queue
static void handle_expired_timers(timer_ctx_t ctx, app_timer_t * expired) */
static void
handle_expired_timers(timer_ctx_t ctx, app_timer_t *expired)
{ {
while (expired) { while (expired) {
app_timer_t * t = expired; app_timer_t *t = expired;
ctx->timer_callback(t->id, ctx->owner); ctx->timer_callback(t->id, ctx->owner);
/* get next expired timer first, since the following
operation may change expired->next */
expired = expired->next; expired = expired->next;
if (t->is_periodic) { if (t->is_periodic) {
// if it is repeating, then reschedule it; /* if it is repeating, then reschedule it; */
reschedule_timer(ctx, t); reschedule_timer(ctx, t);
} else { }
// else move it to idle list else {
/* else move it to idle list */
add_idle_timer(ctx, t); add_idle_timer(ctx, t);
} }
} }
} }
int get_expiry_ms(timer_ctx_t ctx) uint32
get_expiry_ms(timer_ctx_t ctx)
{ {
int ms_to_next_expiry; uint32 ms_to_next_expiry;
uint64 now = bh_get_tick_ms(); uint64 now = bh_get_tick_ms();
os_mutex_lock(&ctx->mutex); os_mutex_lock(&ctx->mutex);
if (ctx->g_app_timers == NULL) if (ctx->app_timers == NULL)
ms_to_next_expiry = 7 * 24 * 60 * 60 * 1000; // 1 week ms_to_next_expiry = (uint32)-1;
else if (ctx->g_app_timers->expiry >= now) else if (ctx->app_timers->expiry >= now)
ms_to_next_expiry = (int)(ctx->g_app_timers->expiry - now); ms_to_next_expiry = (uint32)(ctx->app_timers->expiry - now);
else else
ms_to_next_expiry = 0; ms_to_next_expiry = 0;
os_mutex_unlock(&ctx->mutex); os_mutex_unlock(&ctx->mutex);
@ -391,39 +423,40 @@ int get_expiry_ms(timer_ctx_t ctx)
return ms_to_next_expiry; return ms_to_next_expiry;
} }
int check_app_timers(timer_ctx_t ctx) int
check_app_timers(timer_ctx_t ctx)
{ {
os_mutex_lock(&ctx->mutex); app_timer_t *t, *expired = NULL;
app_timer_t * t = ctx->g_app_timers;
app_timer_t * expired = NULL;
uint64 now = bh_get_tick_ms(); uint64 now = bh_get_tick_ms();
os_mutex_lock(&ctx->mutex);
t = ctx->app_timers;
while (t) { while (t) {
if (now >= t->expiry) { if (now >= t->expiry) {
ctx->g_app_timers = t->next; ctx->app_timers = t->next;
t->next = expired; t->next = expired;
expired = t; expired = t;
t = ctx->g_app_timers; t = ctx->app_timers;
} else { }
else {
break; break;
} }
} }
os_mutex_unlock(&ctx->mutex); os_mutex_unlock(&ctx->mutex);
handle_expired_timers(ctx, expired); handle_expired_timers(ctx, expired);
return get_expiry_ms(ctx); return get_expiry_ms(ctx);
} }
void cleanup_app_timers(timer_ctx_t ctx) void
cleanup_app_timers(timer_ctx_t ctx)
{ {
os_mutex_lock(&ctx->mutex); os_mutex_lock(&ctx->mutex);
release_timer_list(&ctx->g_app_timers); release_timer_list(&ctx->app_timers);
release_timer_list(&ctx->idle_timers); release_timer_list(&ctx->idle_timers);
os_mutex_unlock(&ctx->mutex); os_mutex_unlock(&ctx->mutex);

View File

@ -33,7 +33,7 @@ bool sys_timer_cancel(timer_ctx_t ctx, uint32 timer_id);
bool sys_timer_restart(timer_ctx_t ctx, uint32 timer_id, int interval); bool sys_timer_restart(timer_ctx_t ctx, uint32 timer_id, int interval);
void cleanup_app_timers(timer_ctx_t ctx); void cleanup_app_timers(timer_ctx_t ctx);
int check_app_timers(timer_ctx_t ctx); int check_app_timers(timer_ctx_t ctx);
int get_expiry_ms(timer_ctx_t ctx); uint32 get_expiry_ms(timer_ctx_t ctx);
#ifdef __cplusplus #ifdef __cplusplus
} }