int ofp_timer_term_global(void) { int i; struct ofp_timer_internal *bufdata, *next; int rc = 0; if (ofp_timer_lookup_shared_memory()) return -1; CHECK_ERROR(ofp_timer_stop_global(), rc); /* Cleanup long timers*/ for (i = 0; i < TIMER_NUM_LONG_SLOTS; i++) { bufdata = shm->long_table[i]; if (!bufdata) continue; while (bufdata) { next = bufdata->next; odp_buffer_free(bufdata->buf); bufdata = next; } } /* Cleanup timer related ODP objects*/ if (shm->queue != ODP_QUEUE_INVALID) { CHECK_ERROR(odp_queue_destroy(shm->queue), rc); shm->queue = ODP_QUEUE_INVALID; } if (shm->socket_timer_pool != ODP_TIMER_POOL_INVALID) { odp_timer_pool_destroy(shm->socket_timer_pool); shm->socket_timer_pool = ODP_TIMER_POOL_INVALID; } if (shm->buf_pool != ODP_POOL_INVALID) { CHECK_ERROR(odp_pool_destroy(shm->buf_pool), rc); shm->buf_pool = ODP_POOL_INVALID; } if (shm->pool != ODP_POOL_INVALID) { CHECK_ERROR(odp_pool_destroy(shm->pool), rc); shm->pool = ODP_POOL_INVALID; } CHECK_ERROR(ofp_timer_free_shared_memory(), rc); return rc; }
int ofp_init_local(void) { /* Lookup shared memories */ HANDLE_ERROR(ofp_global_config_lookup_shared_memory()); HANDLE_ERROR(ofp_portconf_lookup_shared_memory()); HANDLE_ERROR(ofp_route_lookup_shared_memory()); HANDLE_ERROR(ofp_avl_lookup_shared_memory()); HANDLE_ERROR(ofp_reassembly_lookup_shared_memory()); HANDLE_ERROR(ofp_pcap_lookup_shared_memory()); HANDLE_ERROR(ofp_stat_lookup_shared_memory()); HANDLE_ERROR(ofp_socket_lookup_shared_memory()); HANDLE_ERROR(ofp_timer_lookup_shared_memory()); HANDLE_ERROR(ofp_hook_lookup_shared_memory()); HANDLE_ERROR(ofp_arp_lookup_shared_memory()); HANDLE_ERROR(ofp_vxlan_lookup_shared_memory()); HANDLE_ERROR(ofp_arp_init_local()); return 0; }
int ofp_init_local(void) { /* Lookup shared memories */ HANDLE_ERROR(ofp_global_config_lookup_shared_memory()); HANDLE_ERROR(ofp_portconf_lookup_shared_memory()); HANDLE_ERROR(ofp_route_lookup_shared_memory()); HANDLE_ERROR(ofp_avl_lookup_shared_memory()); HANDLE_ERROR(ofp_reassembly_lookup_shared_memory()); HANDLE_ERROR(ofp_pcap_lookup_shared_memory()); HANDLE_ERROR(ofp_stat_lookup_shared_memory()); HANDLE_ERROR(ofp_socket_lookup_shared_memory()); HANDLE_ERROR(ofp_timer_lookup_shared_memory()); HANDLE_ERROR(ofp_hook_lookup_shared_memory()); HANDLE_ERROR(ofp_arp_lookup_shared_memory()); HANDLE_ERROR(ofp_vxlan_lookup_shared_memory()); HANDLE_ERROR(ofp_arp_init_local()); HANDLE_ERROR(ofp_tcp_var_lookup_shared_memory()); #ifdef OFP_SEND_PKT_BURST HANDLE_ERROR(ofp_send_pkt_burst_out_init_local()); #endif /*OFP_SEND_PKT_BURST*/ return 0; }
odp_timer_t ofp_timer_start(uint64_t tmo_us, ofp_timer_callback callback, void *arg, int arglen) { uint64_t tick; uint64_t period; uint64_t period_ns; struct ofp_timer_internal *bufdata; odp_buffer_t buf; odp_timer_set_t t; odp_timeout_t tmo; /* Init shm if not done yet. */ if ((shm == NULL) && ofp_timer_lookup_shared_memory()) { OFP_ERR("ofp_timer_lookup_shared_memory failed"); return ODP_TIMER_INVALID; } /* Alloc user buffer */ buf = odp_buffer_alloc(shm->buf_pool); if (buf == ODP_BUFFER_INVALID) { OFP_ERR("odp_buffer_alloc failed"); return ODP_TIMER_INVALID; } bufdata = (struct ofp_timer_internal *)odp_buffer_addr(buf); bufdata->callback = callback; bufdata->buf = buf; bufdata->t_ev = ODP_EVENT_INVALID; bufdata->next = NULL; bufdata->id = 0; if (arg && arglen) memcpy(bufdata->arg, arg, arglen); if (tmo_us >= OFP_TIMER_MAX_US) { /* Long 1 s resolution timeout */ uint64_t sec = tmo_us/1000000UL; if (sec > TIMER_NUM_LONG_SLOTS) { OFP_ERR("Timeout too long = %"PRIu64"s", sec); } odp_spinlock_lock(&shm->lock); int ix = (shm->sec_counter + sec) & TIMER_LONG_MASK; bufdata->id = ((shm->id++)<<TIMER_LONG_SHIFT) | ix | 0x80000000; bufdata->next = shm->long_table[ix]; shm->long_table[ix] = bufdata; odp_spinlock_unlock(&shm->lock); return (odp_timer_t) bufdata->id; } else { /* Short 10 ms resolution timeout */ odp_timer_t timer; /* Alloc timout event */ tmo = odp_timeout_alloc(shm->pool); if (tmo == ODP_TIMEOUT_INVALID) { odp_buffer_free(buf); OFP_ERR("odp_timeout_alloc failed"); return ODP_TIMER_INVALID; } bufdata->t_ev = odp_timeout_to_event(tmo); period_ns = tmo_us*ODP_TIME_USEC_IN_NS; period = odp_timer_ns_to_tick(shm->socket_timer_pool, period_ns); tick = odp_timer_current_tick(shm->socket_timer_pool); tick += period; timer = odp_timer_alloc(shm->socket_timer_pool, shm->queue, bufdata); if (timer == ODP_TIMER_INVALID) { odp_timeout_free(tmo); odp_buffer_free(buf); OFP_ERR("odp_timer_alloc failed"); return ODP_TIMER_INVALID; } t = odp_timer_set_abs(timer, tick, &bufdata->t_ev); if (t != ODP_TIMER_SUCCESS) { odp_timeout_free(tmo); odp_buffer_free(buf); OFP_ERR("odp_timer_set_abs failed"); return ODP_TIMER_INVALID; } return timer; } return ODP_TIMER_INVALID; }