ErtsThrQCleanState_t erts_thr_q_finalize(ErtsThrQ_t *q) { #ifdef USE_THREADS q->q.finalizing = 1; #endif while (erts_thr_q_dequeue(q)); return erts_thr_q_clean(q); }
int erts_async_ready_clean(void *varq, void *val) { ErtsAsyncReadyQ *arq = (ErtsAsyncReadyQ *) varq; ErtsThrQCleanState_t cstate; cstate = erts_thr_q_clean(&arq->thr_q); if (erts_thr_q_finalize_dequeue(&arq->fin_deq)) return ERTS_ASYNC_READY_DIRTY; switch (cstate) { case ERTS_THR_Q_DIRTY: return ERTS_ASYNC_READY_DIRTY; case ERTS_THR_Q_NEED_THR_PRGR: #ifdef ERTS_SMP *((ErtsThrPrgrVal *) val) = erts_thr_q_need_thr_progress(&arq->thr_q); return ERTS_ASYNC_READY_NEED_THR_PRGR; #endif case ERTS_THR_Q_CLEAN: break; } return ERTS_ASYNC_READY_CLEAN; }
static ERTS_INLINE ErtsAsync *async_get(ErtsThrQ_t *q, erts_tse_t *tse, ErtsThrQPrepEnQ_t **prep_enq) { #if ERTS_USE_ASYNC_READY_Q int saved_fin_deq = 0; ErtsThrQFinDeQ_t fin_deq; #endif #ifdef USE_VM_PROBES int len; #endif while (1) { ErtsAsync *a = (ErtsAsync *) erts_thr_q_dequeue(q); if (a) { #if ERTS_USE_ASYNC_READY_Q *prep_enq = a->q.prep_enq; erts_thr_q_get_finalize_dequeue_data(q, &a->q.fin_deq); if (saved_fin_deq) erts_thr_q_append_finalize_dequeue_data(&a->q.fin_deq, &fin_deq); #endif #ifdef USE_LTTNG_VM_TRACEPOINTS if (LTTNG_ENABLED(aio_pool_get)) { lttng_decl_portbuf(port_str); int length = erts_thr_q_length_dirty(q); lttng_portid_to_str(a->port, port_str); LTTNG2(aio_pool_get, port_str, length); } #endif #ifdef USE_VM_PROBES if (DTRACE_ENABLED(aio_pool_get)) { DTRACE_CHARBUF(port_str, 16); erts_snprintf(port_str, sizeof(DTRACE_CHARBUF_NAME(port_str)), "%T", a->port); /* DTRACE TODO: Get the length from erts_thr_q_dequeue() ? */ len = -1; DTRACE2(aio_pool_get, port_str, len); } #endif return a; } if (ERTS_THR_Q_DIRTY != erts_thr_q_clean(q)) { ErtsThrQFinDeQ_t tmp_fin_deq; erts_tse_reset(tse); #if ERTS_USE_ASYNC_READY_Q chk_fin_deq: if (erts_thr_q_get_finalize_dequeue_data(q, &tmp_fin_deq)) { if (!saved_fin_deq) { erts_thr_q_finalize_dequeue_state_init(&fin_deq); saved_fin_deq = 1; } erts_thr_q_append_finalize_dequeue_data(&fin_deq, &tmp_fin_deq); } #endif switch (erts_thr_q_inspect(q, 1)) { case ERTS_THR_Q_DIRTY: break; case ERTS_THR_Q_NEED_THR_PRGR: #ifdef ERTS_SMP { ErtsThrPrgrVal prgr = erts_thr_q_need_thr_progress(q); erts_thr_progress_wakeup(NULL, prgr); /* * We do no dequeue finalizing in hope that a new async * job will arrive before we are woken due to thread * progress... */ erts_tse_wait(tse); break; } #endif case ERTS_THR_Q_CLEAN: #if ERTS_USE_ASYNC_READY_Q if (saved_fin_deq) { if (erts_thr_q_finalize_dequeue(&fin_deq)) goto chk_fin_deq; else saved_fin_deq = 0; } #endif erts_tse_wait(tse); break; default: ASSERT(0); break; } } } }