int EXP_Touch(const struct object *o) { struct objcore *oc; int retval = 0; struct objcore_head *lru; CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); oc = o->objcore; if (oc == NULL) return (retval); lru = STV_lru(o->objstore); if (lru == NULL) return (retval); AN(o->objhead); CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); if (Lck_Trylock(&exp_mtx)) return (retval); if (oc->flags & OC_F_ONLRU) { VTAILQ_REMOVE(lru, oc, lru_list); VTAILQ_INSERT_TAIL(lru, oc, lru_list); VSL_stats->n_lru_moved++; retval = 1; } Lck_Unlock(&exp_mtx); return (retval); }
int WRK_TrySumStat(struct worker *w) { if (Lck_Trylock(&wstat_mtx)) return (0); wrk_sumstat(w); Lck_Unlock(&wstat_mtx); return (1); }
int Pool_TrySumstat(struct worker *wrk) { if (Lck_Trylock(&wstat_mtx)) return (0); pool_sumstat(wrk->stats); Lck_Unlock(&wstat_mtx); memset(wrk->stats, 0, sizeof *wrk->stats); return (1); }
static struct objcore * ban_lurker_getfirst(struct vsl_log *vsl, struct ban *bt) { struct objhead *oh; struct objcore *oc; while (1) { Lck_Lock(&ban_mtx); oc = VTAILQ_FIRST(&bt->objcore); CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); if (oc == &oc_marker) { VTAILQ_REMOVE(&bt->objcore, oc, ban_list); Lck_Unlock(&ban_mtx); return (NULL); } oh = oc->objhead; CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); if (!Lck_Trylock(&oh->mtx)) { if (oc->refcnt == 0) { Lck_Unlock(&oh->mtx); } else { /* * We got the lock, and the oc is not being * dismantled under our feet. * Take it off the ban and (optimistically) * put it on the * destination ban */ AZ(oc->flags & OC_F_BUSY); oc->refcnt += 1; VTAILQ_REMOVE(&bt->objcore, oc, ban_list); VTAILQ_INSERT_TAIL(&bt->objcore, oc, ban_list); Lck_Unlock(&oh->mtx); Lck_Unlock(&ban_mtx); break; } } /* Try again, later */ Lck_Unlock(&ban_mtx); VSC_C_main->bans_lurker_contention++; VSL_Flush(vsl, 0); VTIM_sleep(cache_param->ban_lurker_sleep); } return (oc); }
static void * mpl_guard(void *priv) { struct mempool *mpl; struct memitem *mi = NULL; double mpl_slp __state_variable__(mpl_slp); double last = 0; CAST_OBJ_NOTNULL(mpl, priv, MEMPOOL_MAGIC); mpl_slp = 0.15; // random while (1) { VTIM_sleep(mpl_slp); mpl_slp = 0.814; // random mpl->t_now = VTIM_real(); if (mi != NULL && (mpl->n_pool > mpl->param->max_pool || mi->size < *mpl->cur_size)) { FREE_OBJ(mi); mi = NULL; } if (mi == NULL && mpl->n_pool < mpl->param->min_pool) mi = mpl_alloc(mpl); if (mpl->n_pool < mpl->param->min_pool && mi != NULL) { /* can do */ } else if (mpl->n_pool > mpl->param->max_pool && mi == NULL) { /* can do */ } else if (!VTAILQ_EMPTY(&mpl->surplus)) { /* can do */ } else if (last + .1 * mpl->param->max_age < mpl->t_now) { /* should do */ } else if (mpl->self_destruct) { /* can do */ } else { continue; /* nothing to do */ } mpl_slp = 0.314; // random if (Lck_Trylock(&mpl->mtx)) continue; if (mpl->self_destruct) { AZ(mpl->live); while (1) { if (mi == NULL) { mi = VTAILQ_FIRST(&mpl->list); if (mi != NULL) { mpl->vsc->pool = --mpl->n_pool; VTAILQ_REMOVE(&mpl->list, mi, list); } } if (mi == NULL) { mi = VTAILQ_FIRST(&mpl->surplus); if (mi != NULL) VTAILQ_REMOVE(&mpl->surplus, mi, list); } if (mi == NULL) break; FREE_OBJ(mi); mi = NULL; } VSM_Free(mpl->vsc); Lck_Unlock(&mpl->mtx); Lck_Delete(&mpl->mtx); FREE_OBJ(mpl); break; } if (mpl->n_pool < mpl->param->min_pool && mi != NULL && mi->size >= *mpl->cur_size) { CHECK_OBJ_NOTNULL(mi, MEMITEM_MAGIC); mpl->vsc->pool = ++mpl->n_pool; mi->touched = mpl->t_now; VTAILQ_INSERT_HEAD(&mpl->list, mi, list); mi = NULL; mpl_slp = .01; // random } if (mpl->n_pool > mpl->param->max_pool && mi == NULL) { mi = VTAILQ_FIRST(&mpl->list); CHECK_OBJ_NOTNULL(mi, MEMITEM_MAGIC); mpl->vsc->pool = --mpl->n_pool; mpl->vsc->surplus++; VTAILQ_REMOVE(&mpl->list, mi, list); mpl_slp = .01; // random } if (mi == NULL) { mi = VTAILQ_FIRST(&mpl->surplus); if (mi != NULL) { CHECK_OBJ_NOTNULL(mi, MEMITEM_MAGIC); VTAILQ_REMOVE(&mpl->surplus, mi, list); mpl_slp = .01; // random } } if (mi == NULL && mpl->n_pool > mpl->param->min_pool) { mi = VTAILQ_LAST(&mpl->list, memhead_s); CHECK_OBJ_NOTNULL(mi, MEMITEM_MAGIC); if (mi->touched + mpl->param->max_age < mpl->t_now) { mpl->vsc->pool = --mpl->n_pool; mpl->vsc->timeout++; VTAILQ_REMOVE(&mpl->list, mi, list); mpl_slp = .01; // random } else { mi = NULL; last = mpl->t_now; } } else if (mpl->n_pool <= mpl->param->min_pool) { last = mpl->t_now; } Lck_Unlock(&mpl->mtx); if (mi != NULL) { FREE_OBJ(mi); mi = NULL; } } return (NULL); }