| 317 | } |
| 318 | |
| 319 | ATTRIBUTE_NO_INLINE |
| 320 | void timer_countdown_expired(uc_engine *uc) { |
| 321 | #ifdef DEBUG_TIMER |
| 322 | puts("======= Timer state PRE ======= "); |
| 323 | print_timer_state(); |
| 324 | fflush(stdout); |
| 325 | #endif |
| 326 | struct TimerState* timers = &uc->fw->timers; |
| 327 | struct Timer *initial_head = timers->active_head; |
| 328 | struct Timer *cursor; |
| 329 | if(initial_head) { |
| 330 | // Sync timers |
| 331 | uint64_t elapsed = timers->cur_interval; |
| 332 | timers->global_ticker += elapsed; |
| 333 | for(cursor = initial_head; cursor; cursor = cursor->next) { |
| 334 | cursor->ticker_val -= elapsed; |
| 335 | } |
| 336 | |
| 337 | // Trigger and reload the timers which timeouted |
| 338 | for (cursor = initial_head; cursor->ticker_val == 0; cursor = timers->active_head) { |
| 339 | cursor->ticker_val = cursor->reload_val; |
| 340 | sort_timer_back(timers, cursor); |
| 341 | |
| 342 | // Ding! |
| 343 | #ifdef DEBUG_TIMER |
| 344 | uc->timer_expired(uc->ctx, get_timer_id(timers, cursor), cursor); |
| 345 | printf("[TIMER] Ding! Timer %d is going off. Reloading to %ld\n", get_timer_id(timers, cursor), cursor->reload_val); |
| 346 | #endif |
| 347 | if(cursor->irq_num != TIMER_IRQ_NOT_USED) { |
| 348 | // pend interrupt |
| 349 | #ifdef DEBUG_TIMER |
| 350 | printf("[TIMER] Pending irq %d\n", cursor->irq_num); |
| 351 | #endif |
| 352 | nvic_set_pending(uc, cursor->irq_num, false); |
| 353 | } |
| 354 | if(cursor->trigger_callback != NULL) { |
| 355 | // call timer callback |
| 356 | #ifdef DEBUG_TIMER |
| 357 | puts("[TIMER] Calling timer callback"); |
| 358 | #endif |
| 359 | cursor->trigger_callback(uc, get_timer_id(timers, cursor), cursor->trigger_cb_user_data); |
| 360 | } |
| 361 | } |
| 362 | |
| 363 | // Set interval to the front's ticker |
| 364 | timers->cur_interval = cursor->ticker_val; |
| 365 | } |
| 366 | |
| 367 | timers->cur_countdown = timers->cur_interval; |
| 368 | uc->set_timer_countdown(uc->ctx, uc->fw->timers.cur_countdown); |
| 369 | |
| 370 | #ifdef DEBUG_TIMER |
| 371 | puts("======= Timer state POST ======= "); |
| 372 | print_timer_state(); |
| 373 | fflush(stdout); |
| 374 | #endif |
| 375 | } |
| 376 |
no test coverage detected