static inline void s_destroy_all(void) { if (is_child == true) { s_stop_all(); (void)lagopus_mutex_lock(&stop_lock); { size_t i; test_thread_t tt; /* * Wait the threads done and delete it. */ if (tts != NULL) { for (i = 0; i < n_created_thds; i++) { tt = &(tts[i]); (void)lagopus_thread_wait((lagopus_thread_t *)&tt, -1LL); (void)lagopus_thread_destroy((lagopus_thread_t *)&tt); } free((void *)tts); tts = NULL; } if (polls != NULL) { for (i = 0; i < n_created_polls; i++) { lagopus_qmuxer_poll_destroy(&(polls[i])); } free((void *)polls); polls = NULL; } if (bbqs != NULL) { for (i = 0; i < n_created_bbqs; i++) { lagopus_bbq_destroy(&(bbqs[i]), true); } free((void *)bbqs); bbqs = NULL; } if (qmx != NULL) { lagopus_qmuxer_destroy(&qmx); qmx = NULL; } if (start_lock != NULL) { lagopus_mutex_destroy(&start_lock); start_lock = NULL; } } (void)lagopus_mutex_unlock(&stop_lock); if (stop_lock != NULL) { lagopus_mutex_destroy(&stop_lock); stop_lock = NULL; } } }
static inline void s_final(void) { lagopus_bbq_destroy(&s_idle_tsk_q, true); lagopus_bbq_destroy(&s_urgent_tsk_q, true); lagopus_hashmap_destroy(&s_tsk_tbl, true); lagopus_cond_destroy(&s_sched_cnd); lagopus_mutex_destroy(&s_lck); lagopus_mutex_destroy(&s_sched_lck); }
void snmpmgr_finalize(void) { if (snmp_lock == NULL) { lagopus_mutex_destroy(&snmp_lock); snmp_lock = NULL; } if (snmp_state_lock == NULL) { lagopus_mutex_destroy(&snmp_state_lock); snmp_state_lock = NULL; } if (iftable_entry_hash != NULL) { lagopus_hashmap_destroy(&iftable_entry_hash, true); iftable_entry_hash = NULL; } state = SNMPMGR_NONE; }
void ofp_bridgeq_mgr_destroy(void) { lagopus_hashmap_destroy(&bridgeq_table, true); bridgeq_table = NULL; lagopus_mutex_destroy(&lock); lock = NULL; }
static inline void s_destroy_arg(callout_arg_t arg) { if (likely(arg != NULL && arg->m_is_freeuped == true)) { lagopus_cond_destroy(&(arg->m_cond)); lagopus_mutex_destroy(&(arg->m_lock)); free((void *)arg); } }
static inline void s_final(void) { if (s_cond != NULL) { lagopus_cond_destroy(&s_cond); } if (s_lck != NULL) { (void)lagopus_mutex_lock(&s_lck); (void)lagopus_mutex_unlock(&s_lck); lagopus_mutex_destroy(&s_lck); } }
static inline void a_obj_destroy(a_obj_t o) { lagopus_msg_debug(1, "enter.\n"); if (o != NULL) { if (o->m_lock != NULL) { (void)lagopus_mutex_lock(&(o->m_lock)); (void)lagopus_mutex_unlock(&(o->m_lock)); (void)lagopus_mutex_destroy(&(o->m_lock)); } free((void *)o); } lagopus_msg_debug(1, "leave.\n"); }
void ofp_bridgeq_free(struct ofp_bridgeq *bridgeq, bool force) { uint64_t i; if (bridgeq != NULL) { bridgeq_lock(bridgeq); if (bridgeq->refs > 1 && force == false) { /* bridgeq is busy. */ lagopus_msg_debug(500, "bridgeq(dpid = %"PRIu64") is busy.\n", bridgeq->ofp_bridge->dpid); bridgeq->refs--; bridgeq_unlock(bridgeq); } else { lagopus_msg_debug(500, "bridgeq(dpid = %"PRIu64") is free.\n", bridgeq->ofp_bridge->dpid); if (bridgeq->ofp_bridge != NULL) { ofp_bridge_destroy(bridgeq->ofp_bridge); bridgeq->ofp_bridge = NULL; } /* destroy polls. */ for (i = 0; i < MAX_BRIDGE_POLLS; i++) { if (bridgeq->polls[i] != NULL) { lagopus_qmuxer_poll_destroy(&(bridgeq->polls[i])); bridgeq->polls[i] = NULL; } } for (i = 0; i < MAX_BRIDGE_DP_POLLS; i++) { if (bridgeq->dp_polls[i] != NULL) { lagopus_qmuxer_poll_destroy(&(bridgeq->dp_polls[i])); bridgeq->dp_polls[i] = NULL; } } bridgeq_unlock(bridgeq); if (bridgeq->lock != NULL) { lagopus_mutex_destroy(&(bridgeq->lock)); bridgeq->lock = NULL; } free(bridgeq); } } }
void lagopus_cbuffer_destroy(lagopus_cbuffer_t *cbptr, bool free_values) { if (cbptr != NULL && *cbptr != NULL) { s_lock(*cbptr); { s_shutdown(*cbptr, free_values); lagopus_cond_destroy(&((*cbptr)->m_cond_put)); lagopus_cond_destroy(&((*cbptr)->m_cond_get)); lagopus_cond_destroy(&((*cbptr)->m_cond_awakened)); } s_unlock(*cbptr); lagopus_mutex_destroy(&((*cbptr)->m_lock)); free((void *)*cbptr); *cbptr = NULL; } }
void dp_freeproc(const lagopus_thread_t *t, void *arg) { bool is_valid = false; struct dataplane_arg *dparg; lagopus_result_t ret; dparg = arg; lagopus_msg_info("freeproc in\n"); if (*t != *dparg->threadptr) { lagopus_exit_fatal("other threads worked %p, %p", *t, *dparg->threadptr); } ret = lagopus_thread_is_valid(dparg->threadptr, &is_valid); if (ret != LAGOPUS_RESULT_OK || is_valid == false) { lagopus_perror(ret); return; } /* ADD delete ports? */ lagopus_mutex_destroy(dparg->lock); *dparg->lock = NULL; }
static void s_test_thread_destroy(const lagopus_thread_t *tptr, void *arg) { (void)arg; if (tptr != NULL) { test_thread_t tt = (test_thread_t)*tptr; if (tt != NULL) { (void)lagopus_mutex_lock(&(tt->m_lock)); { lagopus_msg_debug(1, "enter.\n"); if (tt->m_is_operational == false) { lagopus_msg_debug(1, "freeup.\n"); free((void *)tt->m_data); tt->m_data = NULL; } s_is_deleted = true; } (void)lagopus_mutex_unlock(&(tt->m_lock)); } lagopus_mutex_destroy(&(tt->m_lock)); } }
static inline void s_final(void) { if (s_lck != NULL) { lagopus_mutex_destroy(&s_lck); } }
static inline void s_destroy_stage(lagopus_pipeline_stage_t ps, bool is_clean_finish) { if (ps != NULL) { s_lock_stage(ps); { if (is_clean_finish == true) { ps->m_status = STAGE_STATE_DESTROYING; s_notify_stage(ps); (void)s_cancel_stage(ps, ps->m_n_workers); (void)s_wait_stage(ps, ps->m_n_workers, -1LL, true); if (ps->m_n_workers > 0 && ps->m_workers != NULL) { size_t i; for (i = 0; i < ps->m_n_workers; i++) { s_worker_destroy(&(ps->m_workers[i])); } } if (ps->m_freeup_proc != NULL) { (ps->m_freeup_proc)(&ps); } } s_delete_stage(ps); free((void *)(ps->m_name)); free((void *)(ps->m_workers)); if (ps->m_cond != NULL) { lagopus_cond_destroy(&(ps->m_cond)); ps->m_cond = NULL; } if (ps->m_final_lock != NULL) { lagopus_mutex_destroy(&(ps->m_final_lock)); ps->m_final_lock = NULL; } if (ps->m_pause_barrier != NULL) { lagopus_barrier_destroy(&(ps->m_pause_barrier)); ps->m_pause_barrier = NULL; } if (ps->m_pause_lock != NULL) { lagopus_mutex_destroy(&(ps->m_pause_lock)); ps->m_pause_lock = NULL; } if (ps->m_pause_cond != NULL) { lagopus_cond_destroy(&(ps->m_pause_cond)); ps->m_pause_cond = NULL; } if (ps->m_resume_cond != NULL) { lagopus_cond_destroy(&(ps->m_resume_cond)); ps->m_resume_cond = NULL; } } s_unlock_stage(ps); if (ps->m_lock != NULL) { lagopus_mutex_destroy(&(ps->m_lock)); ps->m_lock = NULL; } if (ps->m_is_heap_allocd == true) { free((void *)ps); } } }
void tearDown(void) { lagopus_mutex_destroy(&lock); lock = NULL; }
static inline void atomic_cmd_finalize(void) { lagopus_mutex_destroy(&lock); }
static int do_run(size_t nthds, ssize_t nputs) { int ret = 1; lagopus_result_t r; size_t i; size_t j; char thdname[16]; lagopus_mutex_t start_lock = NULL; test_thread_record *tts = NULL; size_t n_created_thds = 0; lagopus_bbq_t *bbqs = NULL; size_t n_created_bbqs = 0; lagopus_qmuxer_poll_t *polls = NULL; size_t n_created_polls = 0; lagopus_qmuxer_t qmx = NULL; size_t n_need_watch = 0; size_t n_valid_polls = 0; ssize_t qsz; test_thread_t tt; lagopus_bbq_t bbq; lagopus_chrono_t put_date; lagopus_chrono_t t_begin; lagopus_chrono_t t_end; lagopus_chrono_t p_begin; lagopus_chrono_t p_t; ssize_t n_gets = 0; lagopus_chrono_t p_min = LLONG_MAX; lagopus_chrono_t p_max = LLONG_MIN; double p_sum = 0.0; double p_sum2 = 0.0; double p_avg; double p_sd; lagopus_chrono_t t_total = 0; double t_avg; if ((r = lagopus_mutex_create(&start_lock)) != LAGOPUS_RESULT_OK) { lagopus_perror(r); goto done; } /* * Create the qmuxer. */ if ((r = lagopus_qmuxer_create(&qmx)) != LAGOPUS_RESULT_OK) { lagopus_perror(r); goto done; } /* * Then create queues. */ bbqs = (lagopus_bbq_t *)malloc(sizeof(lagopus_bbq_t) * nthds); if (bbqs == NULL) { goto done; } for (i = 0; i < nthds; i++) { if ((r = lagopus_bbq_create(&(bbqs[i]), lagopus_chrono_t, 1000LL * 1000LL, NULL)) != LAGOPUS_RESULT_OK) { lagopus_perror(r); goto done; } n_created_bbqs++; } if (n_created_bbqs == 0) { goto done; } /* * Then create poll objects for the each queue. */ polls = (lagopus_qmuxer_poll_t *)malloc(sizeof(lagopus_qmuxer_poll_t) * n_created_bbqs); if (polls == NULL) { goto done; } for (i = 0; i < n_created_bbqs; i++) { if ((r = lagopus_qmuxer_poll_create(&(polls[i]), bbqs[i], LAGOPUS_QMUXER_POLL_READABLE)) != LAGOPUS_RESULT_OK) { lagopus_perror(r); goto done; } n_created_polls++; } if (n_created_polls == 0) { goto done; } /* * Then create threads for the each poll objects/queues. */ tts = (test_thread_record *)malloc(sizeof(test_thread_record) * n_created_polls); if (tts == NULL) { goto done; } for (i = 0; i < n_created_polls; i++) { snprintf(thdname, sizeof(thdname), "putter " PFSZS(4, u), i); tt = &(tts[i]); if (test_thread_create(&tt, start_lock, bbqs[i], nputs, (const char *)thdname) != true) { goto done; } n_created_thds++; } if (n_created_thds == 0) { goto done; } /* * Let the initiation begin. */ /* * Ready, note that all the created threads do this lock. */ (void)lagopus_mutex_lock(&start_lock); /* * Steady, */ for (i = 0; i < n_created_thds; i++) { tt = &(tts[i]); if (lagopus_thread_start((lagopus_thread_t *)&tt, false) != LAGOPUS_RESULT_OK) { (void)lagopus_mutex_unlock(&start_lock); goto done; } } fprintf(stdout, "Test for " PFSZ(u) " threads " PFSZ(u) " events/thdread start.\n", n_created_thds, (size_t)nputs); /* * Go. */ (void)lagopus_mutex_unlock(&start_lock); WHAT_TIME_IS_IT_NOW_IN_NSEC(t_begin); while (true) { /* * Like the select(2)/poll(2), initialize poll objects before * checking events. */ n_need_watch = 0; n_valid_polls = 0; for (i = 0; i < n_created_thds; i++) { /* * Check if the poll has a valid queue. */ bbq = NULL; if ((r = lagopus_qmuxer_poll_get_queue(&(polls[i]), &bbq)) != LAGOPUS_RESULT_OK) { lagopus_perror(r); break; } if (bbq != NULL) { n_valid_polls++; } /* * Reset the poll status. */ if ((r = lagopus_qmuxer_poll_reset(&(polls[i]))) != LAGOPUS_RESULT_OK) { lagopus_perror(r); break; } n_need_watch++; } /* * If there are no valid queues, exit. */ if (n_valid_polls == 0) { break; } /* * Wait for an event. * * Note that we better set timeout, not waiting forever. */ r = lagopus_qmuxer_poll(&qmx, (lagopus_qmuxer_poll_t *const)polls, n_need_watch, 100LL * 1000LL * 1000LL); if (r > 0) { /* * Check which poll got an event. Actually, check all the queues * in this sample. */ WHAT_TIME_IS_IT_NOW_IN_NSEC(p_begin); for (i = 0; i < n_created_thds; i++) { if ((qsz = lagopus_bbq_size(&(bbqs[i]))) > 0) { //qsz = (qsz <= 10000LL) ? qsz : 10000LL; lagopus_msg_debug(1, "Got " PFSZS(8, u) " events from the Q" PFSZS(03, u) ".\n", (size_t)qsz, (size_t)i); for (j = 0; j < (size_t)qsz; j++) { if ((r = lagopus_bbq_get(&(bbqs[i]), &put_date, lagopus_chrono_t, -1LL)) == LAGOPUS_RESULT_OK) { /* * In this sample, -1LL is kinda 'EOF'. Check if we got * the EOF. */ if (put_date == -1LL) { /* * The queue is kinda 'closed'. From now on we don't * check this queue anymore. To specify this: */ lagopus_msg_debug(1, "Got an EOF from the Q" PFSZS(04, u) ".\n", i); goto nullify; } p_t = p_begin - put_date; if (p_t < p_min) { p_min = p_t; } if (p_t > p_max) { p_max = p_t; } p_sum += (double)p_t; p_sum2 += ((double)p_t * (double)p_t); n_gets++; } else { /* * Something wrong for the queue. But we must not exit * here. Keep on checking other queues. In order to do * this, set NULL as the queue into the poll object for * the queue. */ lagopus_perror(r); nullify: if ((r = lagopus_qmuxer_poll_set_queue(&(polls[i]), NULL)) != LAGOPUS_RESULT_OK) { /* * There is nothing we can do now. */ lagopus_perror(r); goto done; } } } } } } else if (r == LAGOPUS_RESULT_TIMEDOUT) { lagopus_msg_debug(1, "Timedout. continue.\n"); continue; } else { lagopus_perror(r); lagopus_msg_debug(1, "Break the loop due to error(s).\n"); goto done; } } WHAT_TIME_IS_IT_NOW_IN_NSEC(t_end); fprintf(stdout, "Done.\n"); fprintf(stdout, "Total # of the events:\t" PFSZS(22, u) "\n\n", n_gets); p_avg = p_sum / (double)n_gets; p_sd = (p_sum2 - 2.0 * p_avg * p_sum + p_avg * p_avg * (double)n_gets) / (double)(n_gets - 1); p_sd = sqrt(p_sd); fprintf(stdout, "Queue stats:\n"); fprintf(stdout, "wait time min =\t" PFSZS(22, d) " nsec.\n", p_min); fprintf(stdout, "wait time max =\t" PFSZS(22, d) " nsec.\n", p_max); fprintf(stdout, "wait time avg =\t%25.2f nsec.\n", p_avg); fprintf(stdout, "wait time sd =\t%25.2f.\n\n", p_sd); t_total = t_end - t_begin; t_avg = (double)t_total / (double)n_gets; fprintf(stdout, "Throughput:\n"); fprintf(stdout, "total time:\t" PFSZS(22, d) " msec.\n", (size_t)(t_total / 1000LL / 1000LL)); fprintf(stdout, "total avg:\t%25.2f nsec/event.\n", t_avg); ret = 0; done: if (bbqs != NULL) { for (i = 0; i < n_created_bbqs; i++) { lagopus_bbq_destroy(&(bbqs[i]), true); } free((void *)bbqs); } if (polls != NULL) { for (i = 0; i < n_created_polls; i++) { lagopus_qmuxer_poll_destroy(&(polls[i])); } free((void *)polls); } if (tts != NULL) { for (i = 0; i < n_created_thds; i++) { tt = &(tts[i]); lagopus_thread_destroy((lagopus_thread_t *)&tt); } free((void *)tts); } if (qmx != NULL) { lagopus_qmuxer_destroy(&qmx); } if (start_lock != NULL) { lagopus_mutex_destroy(&start_lock); } return ret; }