#include "terror.h"
#include <sys/mman.h>
#include <sys/time.h>
#ifndef N_PROC
#define N_PROC 8
#endif
#define N_STEP 1000
#define N_REP 1000
static unsigned int *Lock;
static unsigned int *Active;
static unsigned int *Count;
static void workload(unsigned int pid)
{
int k, r;
asoincint(Active);
while(*Active < N_PROC)
asorelax(1);
for(k = 0; k < N_STEP; ++k)
for(r = 0; r < N_REP; ++r)
asoincint(Count);
}
tmain()
{
ssize_t k;
Asometh_t *meth;
Void_t *addr;
int status;
int zerof;
int type;
char *lockid;
pid_t pid, cpid[N_PROC];
struct timeval tv1, tv2;
taso(0);
tchild();
type = Tstall ? ASO_PROCESS : ASO_INTRINSIC;
if((zerof = open("/dev/zero", O_RDWR)) < 0)
terror("Can't open /dev/zero");
addr = mmap(0, 3*sizeof(unsigned int), PROT_READ|PROT_WRITE, MAP_SHARED, zerof, 0);
if(!addr || addr == (Void_t*)(-1))
terror("mmap failed");
Lock = (unsigned int*)addr;
Count = Lock+1;
Active = Count+1;
lockid = tstfile("aso", 0);
meth = 0;
while (meth = asometh(ASO_NEXT, meth))
{
if (!(meth->type & type))
continue;
if (asoinit(lockid, meth, 0))
{
twarn("%s method initialization failed", meth->name);
continue;
}
tinfo("testing %s method with %d processes", meth->name, N_PROC);
gettimeofday(&tv1, 0);
*Lock = 0;
*Count = 0;
*Active = 0;
#if N_PROC > 1
for(k = 0; k < N_PROC; ++k)
if((pid = fork()) < 0)
terror("Can't create a child process");
else if(pid > 0)
{ cpid[k] = pid;
continue;
}
else
{ workload((unsigned int)getpid());
texit(0);
}
if (twait(cpid, N_PROC))
terror("workload subprocess error");
#else
workload((unsigned int)getpid());
#endif
if(*Lock != 0)
terror("Aso lock is still held by %d", *Lock);
if(*Count != N_PROC*N_STEP*N_REP)
terror("%s method count error -- expected %d, got %d", meth->name, N_PROC*N_STEP*N_REP, *Count);
gettimeofday(&tv2, 0);
if (tv1.tv_usec > tv2.tv_usec)
{ tv2.tv_sec -= 1;
tv2.tv_usec += 1000000;
}
tinfo("%s method elapsed time %ld.%lds", meth->name,
tv2.tv_sec - tv1.tv_sec, tv2.tv_usec - tv1.tv_usec);
}
texit(0);
}