exp_thread(struct worker *wrk, void *priv) { struct objcore *oc; double t = 0, tnext = 0; struct exp_priv *ep; unsigned flags = 0; CAST_OBJ_NOTNULL(ep, priv, EXP_PRIV_MAGIC); ep->wrk = wrk; VSL_Setup(&ep->vsl, NULL, 0); ep->heap = binheap_new(NULL, object_cmp, object_update); AN(ep->heap); while (1) { Lck_Lock(&ep->mtx); oc = VSTAILQ_FIRST(&ep->inbox); CHECK_OBJ_ORNULL(oc, OBJCORE_MAGIC); if (oc != NULL) { assert(oc->refcnt >= 1); VSTAILQ_REMOVE(&ep->inbox, oc, objcore, exp_list); VSC_C_main->exp_received++; tnext = 0; flags = oc->exp_flags; if (flags & OC_EF_REMOVE) oc->exp_flags = 0; else oc->exp_flags &= OC_EF_REFD; } else if (tnext > t) { VSL_Flush(&ep->vsl, 0); Pool_Sumstat(wrk); (void)Lck_CondWait(&ep->condvar, &ep->mtx, tnext); } Lck_Unlock(&ep->mtx); t = VTIM_real(); if (oc != NULL) exp_inbox(ep, oc, flags); else tnext = exp_expire(ep, t); } NEEDLESS(return NULL); }
void WRK_Thread(struct pool *qp, size_t stacksize, unsigned thread_workspace) { struct worker *w, ww; unsigned char ws[thread_workspace]; uintptr_t u; AN(qp); AN(stacksize); AN(thread_workspace); THR_SetName("cache-worker"); w = &ww; INIT_OBJ(w, WORKER_MAGIC); w->lastused = NAN; AZ(pthread_cond_init(&w->cond, NULL)); WS_Init(w->aws, "wrk", ws, thread_workspace); u = getpagesize(); AN(u); u -= 1U; w->stack_start = (((uintptr_t)&qp) + u) & ~u; /* XXX: assuming stack grows down. */ w->stack_end = w->stack_start - stacksize; VSL(SLT_WorkThread, 0, "%p start", w); Pool_Work_Thread(qp, w); AZ(w->pool); VSL(SLT_WorkThread, 0, "%p end", w); if (w->vcl != NULL) VCL_Rel(&w->vcl); AZ(pthread_cond_destroy(&w->cond)); if (w->nbo != NULL) VBO_Free(&w->nbo); HSH_Cleanup(w); Pool_Sumstat(w); }