#include "vmtest.h"
#define RAND() random()
typedef struct _obj_s Obj_t;
struct _obj_s
{ Void_t* obj;
size_t size;
Obj_t* next;
};
#define N_OBJ 500000
static Obj_t Obj[N_OBJ], *List[N_OBJ+1];
#define Z_HUGE 5000
#define Z_BIG 10000
#define Z_MED 100
#define Z_TINY 10
#define ALLOCSIZE() (RAND()%100 == 0 ? (RAND()%Z_BIG + Z_BIG/2 ) : \
RAND()%10 == 0 ? (RAND()%Z_MED + Z_MED ) : \
(RAND()%Z_TINY + 1) )
#define TM_BIG 1000
#define TM_MED 10
#define TM_TINY 5
#define TMRANGE(zz) (zz >= Z_BIG ? TM_BIG : zz >= Z_MED ? TM_MED : TM_TINY )
#define TIME(nk,kk,zz) ((nk = kk + (RAND() % TMRANGE(zz)) + 1), \
(nk = nk <= kk ? kk+1 : nk > N_OBJ ? N_OBJ : nk ) )
#define COMPACT(kk) ((kk % (N_OBJ/5000)) == 0 ? 1 : 0)
#define RESIZE(kk) ((kk % (N_OBJ/500)) == 0 ? 1 : 0)
tmain()
{
Obj_t *o, *next;
Void_t *huge;
size_t hugesz;
Vmstat_t sb;
ssize_t k, p;
srandom(0);
hugesz = Z_HUGE;
if(!(huge = vmalloc(Vmregion, hugesz)) )
terror("Can't allocate block");
for(k = 0; k < N_OBJ; ++k)
{
for(o = List[k]; o; o = next)
{ next = o->next;
if((RAND()%2) == 0 )
vmfree(Vmregion, o->obj);
else
{ o->size = ALLOCSIZE();
if(!(o->obj = vmresize(Vmregion,o->obj,o->size,VM_RSMOVE)) )
terror("Vmresize failed");
TIME(p, k, o->size);
o->next = List[p]; List[p] = o;
}
}
if(COMPACT(k))
{ if(vmstat(Vmregion, &sb) < 0)
terror("Vmstat failed");
tinfo("Arena: busy=(%u,%u) free=(%u,%u) extent=%u #segs=%d",
sb.n_busy,sb.s_busy, sb.n_free,sb.s_free,
sb.extent, sb.n_seg);
if(vmcompact(Vmregion) < 0 )
terror("Vmcompact failed");
if(vmstat(Vmregion, &sb) < 0)
terror("Vmstat failed");
tinfo("Compact: busy=(%u,%u) free=(%u,%u) extent=%u #segs=%d",
sb.n_busy,sb.s_busy, sb.n_free,sb.s_free,
sb.extent, sb.n_seg);
}
if(RESIZE(k))
{ hugesz += Z_HUGE;
if(!(huge = vmresize(Vmregion, huge, hugesz, VM_RSMOVE)) )
terror("Bad resize of huge block");
}
o = Obj+k;
o->size = ALLOCSIZE();
if(!(o->obj = vmalloc(Vmregion, o->size)) )
terror("Vmalloc failed");
TIME(p, k, o->size);
o->next = List[p]; List[p] = o;
}
if(vmdbcheck(Vmregion) < 0)
terror("Corrupted region");
if(vmstat(Vmregion, &sb) < 0)
terror("Vmstat failed");
tinfo("Full: Busy=(%u,%u) Free=(%u,%u) Extent=%u #segs=%d\n",
sb.n_busy, sb.s_busy, sb.n_free, sb.s_free, sb.extent, sb.n_seg);
if(vmcompact(Vmregion) < 0 )
terror("Vmcompact failed");
if(vmstat(Vmregion, &sb) < 0)
terror("Vmstat failed");
tinfo("Compact: Busy=(%u,%u) Free=(%u,%u) Extent=%u #segs=%d\n",
sb.n_busy, sb.s_busy, sb.n_free, sb.s_free, sb.extent, sb.n_seg);
for(o = List[N_OBJ]; o; o = o->next)
vmfree(Vmregion,o->obj);
vmfree(Vmregion,huge);
if(vmstat(Vmregion, &sb) < 0)
terror("Vmstat failed");
tinfo("Free: Busy=(%u,%u) Free=(%u,%u) Extent=%u #segs=%d\n",
sb.n_busy, sb.s_busy, sb.n_free, sb.s_free, sb.extent, sb.n_seg);
if(vmcompact(Vmregion) < 0 )
terror("Vmcompact failed2");
if(vmstat(Vmregion, &sb) < 0)
terror("Vmstat failed");
tinfo("Compact: Busy=(%u,%u) Free=(%u,%u) Extent=%u #segs=%d\n",
sb.n_busy, sb.s_busy, sb.n_free, sb.s_free, sb.extent, sb.n_seg);
if(!(huge = vmalloc(Vmregion, 10)))
terror("Vmalloc failed");
if(vmstat(Vmregion, &sb) < 0)
terror("Vmstat failed");
tinfo("Small: Busy=(%u,%u) Free=(%u,%u) Extent=%u #segs=%d\n",
sb.n_busy, sb.s_busy, sb.n_free, sb.s_free, sb.extent, sb.n_seg);
texit(0);
}