shithub: 9bench

ref: 3f899338e54ae7ed97d980838a0c40e350718405
dir: /test.c/

View raw version
#include <u.h>
#include <libc.h>
#include <bench.h>

typedef struct SLock SLock;
struct SLock {
	long	state;
	long	sem;
};

int	casl(long *, long, long);

void
slock(SLock *s)
{
	int i;

	for(i = 0; i < 100; i++){
		if(casl(&s->state, 0, 1))
			return;
		sleep(0);
	}
	if(ainc(&s->state) == 1)
		return;
	while(semacquire(&s->sem, 1) == -1)
		/* retry */;
}

void
sunlock(SLock *s)
{
	if(adec(&s->state) == 0)
		return;
	semrelease(&s->sem, 1);
}

void
benchmallocfree32(B *b)
{
	int i;

	for(i = 0; i < b->N; i++) {
		free(malloc(32));
	}
}

void
benchrand(B *b)
{
	int i;

	for(i = 0; i < b->N; i++) {
		(void)rand();
	}
}

void
benchtruerand(B *b)
{
	int i;

	for(i = 0; i < b->N; i++) {
		(void)truerand();
	}
}

void
benchinc(B *b)
{
	int i;
	long inc;

	inc = 0;
	for(i = 0; i < b->N; i++) {
		inc++;
	}
}

void
benchainc(B *b)
{
	int i;
	long inc;

	for(i = 0; i < b->N; i++) {
		ainc(&inc);
	}
}

void
benchfork(B *b)
{
	int i;
	
	for(i = 0; i < b->N; i++){
		if(!rfork(RFPROC|RFMEM))
			exits(nil);
		waitpid();
	}
}
void
benchmfork(B *b)
{
	int i;
	
	for(i = 0; i < b->N; i++){
		if(!fork())
			exits(nil);
		waitpid();
	}
}


void
benchforkexecl(B *b)
{
	int i;
	
	for(i = 0; i < b->N; i++){
		switch(fork()){
		case -1:
			abort();
		case 0:
			execl("./6.true", "6.true", nil);
			print("exec: %r");
			abort();
		default:
			waitpid();
		}
	}
}

Lock l;
QLock q;
SLock s;
int count;

void
hammerlock(int n)
{
	int i;

	for(i = 0; i < n; i++){
		lock(&l);
		count++;
		unlock(&l);
	}
}

void
hammerqlock(int n)
{
	int i;

	for(i = 0; i < n; i++){
		qlock(&q);
		count++;
		qunlock(&q);
	}
}

void
hammerslock(int n)
{
	int i;

	for(i = 0; i < n; i++){
		slock(&s);
		count++;
		sunlock(&s);
	}
}

void
lockbench(void (*fn)(int), int nthr, int ninc)
{
	int i, p;

	for(i = 0; i < nthr; i++){
		if((p = rfork(RFPROC|RFMEM)) == -1)
			sysfatal("rfork: %r");
		if(p == 0){
			(*fn)(ninc);
			exits(nil);
		}
	}
	for(i = 0; i < nthr; i++)
		free(wait());
}

#define LKB(nthr) \
	void benchlock##nthr(B *b){lockbench(hammerlock, nthr, b->N);} \
	void benchqlock##nthr(B *b){lockbench(hammerqlock, nthr, b->N);} \
	void benchslock##nthr(B *b){lockbench(hammerslock, nthr, b->N);}

LKB(1)
LKB(4)
LKB(32)
LKB(512)

void
main(void)
{
	benchinit();

	bench("mallocfree32", benchmallocfree32);
	bench("rand", benchrand);
	bench("truerand", benchtruerand);
	bench("inc", benchinc);
	bench("ainc", benchainc);
	bench("mfork", benchmfork);
	bench("fork", benchfork);
	bench("forkexecl", benchforkexecl);

	bench("lock1", benchlock1);
	bench("qlock1", benchqlock1);
	bench("slock1", benchslock1);

	bench("lock4", benchlock4);
	bench("qlock4", benchqlock4);
	bench("slock4", benchslock4);

	bench("lock32", benchlock32);
	bench("qlock32", benchqlock32);
	bench("slock32", benchslock32);

	bench("lock512", benchlock512);
	bench("qlock512", benchqlock512);
	bench("slock512", benchslock512);
	exits(0);
}