Skip to content

Commit 98fbddc

Browse files
committed
Add safety checks for timer
This commit improves memory safety and performance by adding branch prediction hints.
1 parent 2360788 commit 98fbddc

File tree

1 file changed

+32
-24
lines changed

1 file changed

+32
-24
lines changed

kernel/timer.c

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <sys/timer.h>
1515

1616
#include "private/error.h"
17+
#include "private/utils.h"
1718

1819
/* Pre-allocated node pool for reduced malloc/free overhead */
1920
#define TIMER_NODE_POOL_SIZE 16
@@ -79,7 +80,7 @@ static timer_t *cache_lookup_timer(uint16_t id)
7980
/* Initializes the timer subsystem's data structures. */
8081
static int32_t timer_subsystem_init(void)
8182
{
82-
if (timer_initialized)
83+
if (unlikely(timer_initialized))
8384
return ERR_OK;
8485

8586
NOSCHED_ENTER();
@@ -91,10 +92,15 @@ static int32_t timer_subsystem_init(void)
9192
all_timers_list = list_create();
9293
kcb->timer_list = list_create();
9394

94-
if (!all_timers_list || !kcb->timer_list) {
95-
free(all_timers_list);
96-
free(kcb->timer_list);
97-
kcb->timer_list = NULL;
95+
if (unlikely(!all_timers_list || !kcb->timer_list)) {
96+
if (all_timers_list) {
97+
list_destroy(all_timers_list);
98+
all_timers_list = NULL;
99+
}
100+
if (kcb->timer_list) {
101+
list_destroy(kcb->timer_list);
102+
kcb->timer_list = NULL;
103+
}
98104
NOSCHED_LEAVE();
99105
return ERR_FAIL;
100106
}
@@ -113,7 +119,7 @@ static int32_t timer_subsystem_init(void)
113119
/* Fast removal of timer from active list by data pointer */
114120
static void timer_remove_item_by_data(list_t *list, void *data)
115121
{
116-
if (!list || list_is_empty(list))
122+
if (unlikely(!list || list_is_empty(list)))
117123
return;
118124

119125
list_node_t *prev = list->head;
@@ -135,7 +141,7 @@ static void timer_remove_item_by_data(list_t *list, void *data)
135141
static int32_t timer_sorted_insert(timer_t *timer)
136142
{
137143
list_node_t *new_node = get_timer_node();
138-
if (!new_node)
144+
if (unlikely(!new_node))
139145
return ERR_FAIL;
140146
new_node->data = timer;
141147

@@ -171,7 +177,7 @@ static timer_t *timer_find_by_id_fast(uint16_t id)
171177
if (cached && cached->id == id)
172178
return cached;
173179

174-
if (!all_timers_list || list_is_empty(all_timers_list))
180+
if (unlikely(!all_timers_list || list_is_empty(all_timers_list)))
175181
return NULL;
176182

177183
/* Linear search for now - could be optimized to binary search if needed */
@@ -193,7 +199,7 @@ static timer_t *timer_find_by_id_fast(uint16_t id)
193199
/* Find timer node for removal operations */
194200
static list_node_t *timer_find_node_by_id(uint16_t id)
195201
{
196-
if (!all_timers_list)
202+
if (unlikely(!all_timers_list))
197203
return NULL;
198204

199205
list_node_t *node = all_timers_list->head->next;
@@ -210,7 +216,8 @@ static list_node_t *timer_find_node_by_id(uint16_t id)
210216

211217
void _timer_tick_handler(void)
212218
{
213-
if (!timer_initialized || list_is_empty(kcb->timer_list))
219+
if (unlikely(!timer_initialized || !kcb->timer_list ||
220+
list_is_empty(kcb->timer_list)))
214221
return;
215222

216223
uint32_t now = mo_ticks();
@@ -236,7 +243,7 @@ void _timer_tick_handler(void)
236243
timer_t *t = expired_timers[i];
237244

238245
/* Execute callback */
239-
if (t->callback)
246+
if (likely(t->callback))
240247
t->callback(t->arg);
241248

242249
/* Handle auto-reload timers */
@@ -253,7 +260,7 @@ void _timer_tick_handler(void)
253260
static int32_t timer_insert_sorted_by_id(timer_t *timer)
254261
{
255262
list_node_t *new_node = get_timer_node();
256-
if (!new_node)
263+
if (unlikely(!new_node))
257264
return ERR_FAIL;
258265
new_node->data = timer;
259266

@@ -278,13 +285,13 @@ int32_t mo_timer_create(void *(*callback)(void *arg),
278285
{
279286
static uint16_t next_id = 0x6000;
280287

281-
if (!callback || period_ms == 0)
288+
if (unlikely(!callback || !period_ms))
282289
return ERR_FAIL;
283-
if (timer_subsystem_init() != ERR_OK)
290+
if (unlikely(timer_subsystem_init() != ERR_OK))
284291
return ERR_FAIL;
285292

286293
timer_t *t = malloc(sizeof(timer_t));
287-
if (!t)
294+
if (unlikely(!t))
288295
return ERR_FAIL;
289296

290297
NOSCHED_ENTER();
@@ -296,9 +303,10 @@ int32_t mo_timer_create(void *(*callback)(void *arg),
296303
t->period_ms = period_ms;
297304
t->deadline_ticks = 0;
298305
t->mode = TIMER_DISABLED;
306+
t->_reserved = 0;
299307

300308
/* Insert into sorted all_timers_list */
301-
if (timer_insert_sorted_by_id(t) != ERR_OK) {
309+
if (unlikely(timer_insert_sorted_by_id(t) != ERR_OK)) {
302310
NOSCHED_LEAVE();
303311
free(t);
304312
return ERR_FAIL;
@@ -313,13 +321,13 @@ int32_t mo_timer_create(void *(*callback)(void *arg),
313321

314322
int32_t mo_timer_destroy(uint16_t id)
315323
{
316-
if (!timer_initialized)
324+
if (unlikely(!timer_initialized))
317325
return ERR_FAIL;
318326

319327
NOSCHED_ENTER();
320328

321329
list_node_t *node = timer_find_node_by_id(id);
322-
if (!node) {
330+
if (unlikely(!node)) {
323331
NOSCHED_LEAVE();
324332
return ERR_FAIL;
325333
}
@@ -349,15 +357,15 @@ int32_t mo_timer_destroy(uint16_t id)
349357

350358
int32_t mo_timer_start(uint16_t id, uint8_t mode)
351359
{
352-
if (mode != TIMER_ONESHOT && mode != TIMER_AUTORELOAD)
360+
if (unlikely(mode != TIMER_ONESHOT && mode != TIMER_AUTORELOAD))
353361
return ERR_FAIL;
354-
if (!timer_initialized)
362+
if (unlikely(!timer_initialized))
355363
return ERR_FAIL;
356364

357365
NOSCHED_ENTER();
358366

359367
timer_t *t = timer_find_by_id_fast(id);
360-
if (!t) {
368+
if (unlikely(!t)) {
361369
NOSCHED_LEAVE();
362370
return ERR_FAIL;
363371
}
@@ -370,7 +378,7 @@ int32_t mo_timer_start(uint16_t id, uint8_t mode)
370378
t->mode = mode;
371379
t->deadline_ticks = mo_ticks() + MS_TO_TICKS(t->period_ms);
372380

373-
if (timer_sorted_insert(t) != ERR_OK) {
381+
if (unlikely(timer_sorted_insert(t) != ERR_OK)) {
374382
t->mode = TIMER_DISABLED;
375383
NOSCHED_LEAVE();
376384
return ERR_FAIL;
@@ -382,13 +390,13 @@ int32_t mo_timer_start(uint16_t id, uint8_t mode)
382390

383391
int32_t mo_timer_cancel(uint16_t id)
384392
{
385-
if (!timer_initialized)
393+
if (unlikely(!timer_initialized))
386394
return ERR_FAIL;
387395

388396
NOSCHED_ENTER();
389397

390398
timer_t *t = timer_find_by_id_fast(id);
391-
if (!t || t->mode == TIMER_DISABLED) {
399+
if (unlikely(!t || t->mode == TIMER_DISABLED)) {
392400
NOSCHED_LEAVE();
393401
return ERR_FAIL;
394402
}

0 commit comments

Comments
 (0)