static void one_sec(void *arg) { struct ofp_timer_internal *bufdata; (void)arg; odp_spinlock_lock(&shm->lock); shm->sec_counter = (shm->sec_counter + 1) & TIMER_LONG_MASK; bufdata = shm->long_table[shm->sec_counter]; shm->long_table[shm->sec_counter] = NULL; odp_spinlock_unlock(&shm->lock); while (bufdata) { struct ofp_timer_internal *next = bufdata->next; bufdata->callback(&bufdata->arg); odp_buffer_free(bufdata->buf); bufdata = next; } /* Start one second timeout */ shm->timer_1s = ofp_timer_start(1000000UL, one_sec, NULL, 0); }
static void ofp_perf_tmo(void *arg) { uint64_t pps, value = 0; int core; (void)arg; if (ofp_stat_flags & OFP_STAT_COMPUTE_PERF) ofp_timer_start(US_PER_SEC/PROBES, ofp_perf_tmo, NULL, 0); odp_sync_stores(); for (core = 0; core < odp_cpu_count(); core++) value += shm_stat->ofp_packet_statistics.per_core[core].rx_fp; if (value >= shm_stat->ofp_perf_stat.rx_prev_sum) pps = value - shm_stat->ofp_perf_stat.rx_prev_sum; else pps = (uint64_t)(-1) - shm_stat->ofp_perf_stat.rx_prev_sum + value; shm_stat->ofp_perf_stat.rx_fp_pps = (shm_stat->ofp_perf_stat.rx_fp_pps + pps * PROBES) / 2; shm_stat->ofp_perf_stat.rx_prev_sum = value; }
int ofp_timer_init_global(int resolution_us, int min_us, int max_us, int tmo_count) { odp_queue_param_t param; odp_pool_param_t pool_params; odp_timer_pool_param_t timer_params; /* For later tuning. */ (void)tmo_count; HANDLE_ERROR(ofp_timer_alloc_shared_memory()); ofp_timer_shm_init(); /* Timout pool */ memset(&pool_params, 0, sizeof(pool_params)); pool_params.tmo.num = TIMER_NUM_TIMERS; pool_params.type = ODP_POOL_TIMEOUT; shm->pool = ofp_pool_create("TimeoutPool", &pool_params); if (shm->pool == ODP_POOL_INVALID) { OFP_ERR("odp_pool_create failed"); return -1; } /* Buffer pool */ memset(&pool_params, 0, sizeof(pool_params)); pool_params.buf.size = sizeof(struct ofp_timer_internal); pool_params.buf.align = 0; pool_params.buf.num = TIMER_NUM_TIMERS; pool_params.type = ODP_POOL_BUFFER; shm->buf_pool = ofp_pool_create("TimeoutBufferPool", &pool_params); if (shm->buf_pool == ODP_POOL_INVALID) { OFP_ERR("odp_pool_create failed"); return -1; } /* Timer pool */ memset(&timer_params, 0, sizeof(timer_params)); timer_params.res_ns = resolution_us*ODP_TIME_USEC_IN_NS; timer_params.min_tmo = min_us*ODP_TIME_USEC_IN_NS; timer_params.max_tmo = max_us*ODP_TIME_USEC_IN_NS; timer_params.num_timers = TIMER_NUM_TIMERS; timer_params.priv = 0; /* Shared */ timer_params.clk_src = ODP_CLOCK_CPU; shm->socket_timer_pool = odp_timer_pool_create("TmrPool", &timer_params); if (shm->socket_timer_pool == ODP_TIMER_POOL_INVALID) { OFP_ERR("odp_timer_pool_create"); return -1; } odp_timer_pool_start(); /* * Create a queue */ odp_queue_param_init(¶m); param.type = ODP_QUEUE_TYPE_SCHED; param.sched.prio = ODP_SCHED_PRIO_DEFAULT; param.sched.sync = ODP_SCHED_SYNC_PARALLEL; param.sched.group = ODP_SCHED_GROUP_ALL; shm->queue = odp_queue_create("TimerQueue", ¶m); if (shm->queue == ODP_QUEUE_INVALID) { OFP_ERR("odp_queue_create failed"); return -1; } odp_spinlock_init(&shm->lock); /* Start one second timeouts */ shm->timer_1s = ofp_timer_start(1000000UL, one_sec, NULL, 0); return 0; }
static void ofp_start_perf_stat(void) { ofp_timer_start(US_PER_SEC/PROBES, ofp_perf_tmo, NULL, 0); }