Commit 676064df authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Add timeouts and comprehensive test-case for memorypool gymnastics.

parent 8313da8d
...@@ -42,14 +42,17 @@ struct memitem { ...@@ -42,14 +42,17 @@ struct memitem {
#define MEMITEM_MAGIC 0x42e55401 #define MEMITEM_MAGIC 0x42e55401
VTAILQ_ENTRY(memitem) list; VTAILQ_ENTRY(memitem) list;
unsigned size; unsigned size;
double payload; double touched;
char payload;
}; };
VTAILQ_HEAD(memhead_s, memitem);
struct mempool { struct mempool {
unsigned magic; unsigned magic;
#define MEMPOOL_MAGIC 0x37a75a8d #define MEMPOOL_MAGIC 0x37a75a8d
VTAILQ_HEAD(,memitem) list; struct memhead_s list;
VTAILQ_HEAD(,memitem) surplus; struct memhead_s surplus;
struct lock *mtx; struct lock *mtx;
struct lock imtx; struct lock imtx;
const char *name; const char *name;
...@@ -58,6 +61,7 @@ struct mempool { ...@@ -58,6 +61,7 @@ struct mempool {
struct VSC_C_mempool *vsc; struct VSC_C_mempool *vsc;
unsigned n_pool; unsigned n_pool;
pthread_t thread; pthread_t thread;
double t_now;
}; };
/*--------------------------------------------------------------------- /*---------------------------------------------------------------------
...@@ -81,21 +85,26 @@ mpl_alloc(const struct mempool *mpl) ...@@ -81,21 +85,26 @@ mpl_alloc(const struct mempool *mpl)
/*--------------------------------------------------------------------- /*---------------------------------------------------------------------
* Pool-guard * Pool-guard
* Attempt to keep number of free items in pool inside bounds with * Attempt to keep number of free items in pool inside bounds with
* minimum locking activity. * minimum locking activity, and keep an eye on items at the tail
* of the list not getting too old.
*/ */
#include <stdio.h>
static void * static void *
mpl_guard(void *priv) mpl_guard(void *priv)
{ {
struct mempool *mpl; struct mempool *mpl;
struct memitem *mi = NULL; struct memitem *mi = NULL;
double mpl_slp __state_variable__(mpl_slp); double mpl_slp __state_variable__(mpl_slp);
double last = 0;
CAST_OBJ_NOTNULL(mpl, priv, MEMPOOL_MAGIC); CAST_OBJ_NOTNULL(mpl, priv, MEMPOOL_MAGIC);
mpl_slp = 0.15; // random mpl_slp = 0.15; // random
while (1) { while (1) {
VTIM_sleep(mpl_slp); VTIM_sleep(mpl_slp);
mpl_slp = 0.814; // random mpl_slp = 0.814; // random
mpl->t_now = VTIM_real();
if (mi != NULL && (mpl->n_pool > mpl->param->max_pool || if (mi != NULL && (mpl->n_pool > mpl->param->max_pool ||
mi->size < *mpl->cur_size)) { mi->size < *mpl->cur_size)) {
...@@ -106,45 +115,69 @@ mpl_guard(void *priv) ...@@ -106,45 +115,69 @@ mpl_guard(void *priv)
if (mi == NULL && mpl->n_pool < mpl->param->min_pool) if (mi == NULL && mpl->n_pool < mpl->param->min_pool)
mi = mpl_alloc(mpl); mi = mpl_alloc(mpl);
if (mpl->n_pool < mpl->param->min_pool && mi != NULL) { if (mpl->n_pool < mpl->param->min_pool && mi != NULL) {
/* can do */ /* can do */
} else if (mpl->n_pool > mpl->param->max_pool && mi == NULL) { } else if (mpl->n_pool > mpl->param->max_pool && mi == NULL) {
/* can do */ /* can do */
} else if (!VTAILQ_EMPTY(&mpl->surplus)) { } else if (!VTAILQ_EMPTY(&mpl->surplus)) {
/* can do */ /* can do */
} else if (last + .1 * mpl->param->max_age < mpl->t_now) {
/* should do */
} else { } else {
continue; /* cannot do */ continue; /* nothing to do */
} }
mpl_slp = 0.314; mpl_slp = 0.314; // random
if (Lck_Trylock(mpl->mtx)) if (Lck_Trylock(mpl->mtx))
continue; continue;
mpl_slp = .01;
if (mpl->n_pool < mpl->param->min_pool && if (mpl->n_pool < mpl->param->min_pool &&
mi != NULL && mi->size >= *mpl->cur_size) { mi != NULL && mi->size >= *mpl->cur_size) {
CHECK_OBJ_NOTNULL(mi, MEMITEM_MAGIC); CHECK_OBJ_NOTNULL(mi, MEMITEM_MAGIC);
mpl->vsc->pool++; mpl->vsc->pool++;
mpl->n_pool++; mpl->n_pool++;
mi->touched = mpl->t_now;
VTAILQ_INSERT_HEAD(&mpl->list, mi, list); VTAILQ_INSERT_HEAD(&mpl->list, mi, list);
mi = NULL; mi = NULL;
mpl_slp = .01; // random
} }
if (mpl->n_pool > mpl->param->max_pool && mi == NULL) { if (mpl->n_pool > mpl->param->max_pool && mi == NULL) {
mi = VTAILQ_FIRST(&mpl->list); mi = VTAILQ_FIRST(&mpl->list);
CHECK_OBJ_NOTNULL(mi, MEMITEM_MAGIC); CHECK_OBJ_NOTNULL(mi, MEMITEM_MAGIC);
mpl->vsc->pool--; mpl->vsc->pool--;
mpl->vsc->surplus++;
mpl->n_pool--; mpl->n_pool--;
VTAILQ_REMOVE(&mpl->list, mi, list); VTAILQ_REMOVE(&mpl->list, mi, list);
mpl_slp = .01; // random
} }
if (mi == NULL) { if (mi == NULL) {
mi = VTAILQ_FIRST(&mpl->surplus); mi = VTAILQ_FIRST(&mpl->surplus);
if (mi != NULL) { if (mi != NULL) {
CHECK_OBJ_NOTNULL(mi, MEMITEM_MAGIC); CHECK_OBJ_NOTNULL(mi, MEMITEM_MAGIC);
VTAILQ_REMOVE(&mpl->surplus, mi, list); 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->vsc->timeout++;
mpl->n_pool--;
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); Lck_Unlock(mpl->mtx);
if (mi != NULL) { if (mi != NULL) {
...@@ -250,6 +283,7 @@ MPL_Free(struct mempool *mpl, void *item) ...@@ -250,6 +283,7 @@ MPL_Free(struct mempool *mpl, void *item)
} else { } else {
mpl->vsc->pool++; mpl->vsc->pool++;
mpl->n_pool++; mpl->n_pool++;
mi->touched = mpl->t_now;
VTAILQ_INSERT_HEAD(&mpl->list, mi, list); VTAILQ_INSERT_HEAD(&mpl->list, mi, list);
} }
......
varnishtest "Memory pool gymnastics"
server s1 { } -start
varnish v1 -vcl+backend {} -start
delay 1
varnish v1 -expect MEMPOOL.vbc.pool == 10
varnish v1 -cliok "param.set vbc_pool 90,100,100"
delay 1
varnish v1 -expect MEMPOOL.vbc.pool == 90
varnish v1 -cliok "param.set vbc_pool 50,80,100"
delay 1
varnish v1 -expect MEMPOOL.vbc.pool == 80
varnish v1 -expect MEMPOOL.vbc.surplus == 10
varnish v1 -cliok "param.set vbc_pool 10,80,1"
delay 1
varnish v1 -expect MEMPOOL.vbc.pool == 10
varnish v1 -expect MEMPOOL.vbc.timeout == 70
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment