shithub: 9bench

ref: 3df92bd8dd256de9b90fd12a4d63d8bf458f1b83
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
benchsyscall(B *b)
{
	int i;

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

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();
		}
	}
}

void
pingpongbench(B *b)
{
	int i;
	int pfd[2];
	char buf[32];

	if(pipe(pfd) == -1)
		sysfatal("pipe: %r");
	switch(fork()){
	case -1:
		sysfatal("fork: %r");
		break;
	case 0:
		while(1){
			if(read(pfd[0], buf, sizeof(buf)) != 4)
				sysfatal("wrk: read: %r");
			if(write(pfd[1], "pong", 4) != 4)
				sysfatal("wrk: write: %r");
		}
		break;
	default:
		for(i = 0; i < b->N; i++){
			if(write(pfd[1], "ping", 4) != 4)
				sysfatal("write: %r");
			if(read(pfd[0], buf, sizeof(buf)) != 4)
				sysfatal("read: %r");
		}
		break;
	}
}

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());
}

void benchlock1(B *b){lockbench(hammerlock, 1, b->N);}
void benchqlock1(B *b){lockbench(hammerqlock, 1, b->N);}
void benchslock1(B *b){lockbench(hammerslock, 1, b->N);}
void benchlock4(B *b){lockbench(hammerlock, 4, b->N);}
void benchqlock4(B *b){lockbench(hammerqlock, 4, b->N);}
void benchslock4(B *b){lockbench(hammerslock, 4, b->N);}
void benchlock16(B *b){lockbench(hammerlock, 16, b->N);}
void benchqlock16(B *b){lockbench(hammerqlock, 16, b->N);}
void benchslock16(B *b){lockbench(hammerslock, 16, b->N);}
void benchlock64(B *b){lockbench(hammerlock, 64, b->N);}
void benchqlock64(B *b){lockbench(hammerqlock, 64, b->N);}
void benchslock64(B *b){lockbench(hammerslock, 64, b->N);}
void benchlock512(B *b){lockbench(hammerlock, 512, b->N);}
void benchqlock512(B *b){lockbench(hammerqlock, 512, b->N);}
void benchslock512(B *b){lockbench(hammerslock, 512, b->N);}

void
main(void)
{
	benchinit();

	bench("syscall", benchsyscall);

	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("lock16", benchlock16);
	bench("qlock16", benchqlock16);
	bench("slock16", benchslock16);

	bench("lock64", benchlock64);
	bench("qlock64", benchqlock64);
	bench("slock64", benchslock64);

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

	bench("pingpong", pingpongbench);
	exits(0);
}