static uns32 ncs_tmr_select_intr_process(struct timeval *tv, struct timespec *ts_current, uns64 next_delay) { uns64 tmr_restart = 0; uns64 time_left = 0; struct timespec ts_curr = *ts_current; struct timespec ts_eint = { 0, 0 }; tv->tv_sec = tv->tv_usec = 0; if (next_delay == 0) { tv->tv_sec = 0xffffff; tv->tv_usec = 0; return NCSCC_RC_SUCCESS; } if (clock_gettime(CLOCK_MONOTONIC, &ts_eint)) { perror("clock_gettime with MONOTONIC Failed \n"); return NCSCC_RC_FAILURE; } else { tmr_restart = TIMESPEC_DIFF_IN_NS(ts_eint, ts_curr); time_left = ((next_delay * 1000000LL * NCS_MILLISECONDS_PER_TICK) - (tmr_restart)); if (time_left > 0) { tv->tv_sec = time_left / 1000000000LL; tv->tv_usec = ((time_left % 1000000000LL) / 1000); } } return NCSCC_RC_SUCCESS; }
static uint32_t ncs_tmr_engine(struct timeval *tv, uint64_t *next_delay) { uint64_t next_expiry = 0; uint64_t ticks_elapsed = 0; SYSF_TMR_PAT_NODE *tmp = NULL; #if ENABLE_SYSLOG_TMR_STATS /* To measure avg. timer expiry gap */ struct timespec tmr_exp_prev_finish = { 0, 0 }; struct timespec tmr_exp_curr_start = { 0, 0 }; uint32_t tot_tmr_exp = 0; uint64_t sum_of_tmr_exp_gaps = 0; /* Avg = sum_of_tmr_exp_gaps/tot_tmr_exp */ #endif while (true) { tmp = (SYSF_TMR_PAT_NODE *)ncs_patricia_tree_getnext(&gl_tcb.tmr_pat_tree, (uint8_t *)NULL); ticks_elapsed = get_time_elapsed_in_ticks(&ts_start); if (tmp != NULL) { next_expiry = m_NCS_OS_NTOHLL_P(&tmp->key); } else { tv->tv_sec = 0xffffff; tv->tv_usec = 0; *next_delay = 0; return NCSCC_RC_SUCCESS; } if (ticks_elapsed >= next_expiry) { #if ENABLE_SYSLOG_TMR_STATS if (tot_tmr_exp != 0) { tmr_exp_curr_start.tv_sec = tmr_exp_curr_start.tv_nsec = 0; if (clock_gettime(CLOCK_MONOTONIC, &tmr_exp_curr_start)) { perror("clock_gettime with MONOTONIC Failed \n"); } sum_of_tmr_exp_gaps += TIMESPEC_DIFF_IN_NS(tmr_exp_curr_start, tmr_exp_prev_finish); if (tot_tmr_exp >= 100) { printf("\nTotal active timers: %d\n", gl_tcb.stats.cnt); printf("Average timer-expiry gap (last %d expiries) = %lld\n", tot_tmr_exp, sum_of_tmr_exp_gaps / tot_tmr_exp); tot_tmr_exp = 0; sum_of_tmr_exp_gaps = 0; } } #endif if (true == sysfTmrExpiry(tmp)) { /* call expiry routine */ return NCSCC_RC_FAILURE; } #if ENABLE_SYSLOG_TMR_STATS tot_tmr_exp++; tmr_exp_prev_finish.tv_sec = tmr_exp_prev_finish.tv_nsec = 0; if (clock_gettime(CLOCK_MONOTONIC, &tmr_exp_prev_finish)) { perror("clock_gettime with MONOTONIC Failed \n"); return NCSCC_RC_FAILURE; } #endif } else { break; } } /* while loop end */ (*next_delay) = next_expiry - ticks_elapsed; /* Convert the next_dealy intto the below structure */ tv->tv_sec = ((*next_delay) * NCS_MILLISECONDS_PER_TICK) / 1000; tv->tv_usec = (((*next_delay) % (1000 / NCS_MILLISECONDS_PER_TICK)) * (1000 * NCS_MILLISECONDS_PER_TICK)); return NCSCC_RC_SUCCESS; }