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);
}
Exemple #2
0
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);
}