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);
}
Example #2
0
int
WRK_TrySumStat(struct worker *w)
{
	if (Lck_Trylock(&wstat_mtx))
		return (0);
	wrk_sumstat(w);
	Lck_Unlock(&wstat_mtx);
	return (1);
}
Example #3
0
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);
}
Example #5
0
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);
}