shithub: sysbench

ref: 16a2cc57f9cd49f84db08e9c46478d8d0acfdf45
dir: /lock.c/

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

#include "bench.h"

#define NLockIters	1

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

int	casl(long *, long, long);

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

void
nop(void)
{
}

void
work(void)
{
	int i;

	for(i = 0; i < 100*1000; i++)
		count++;
}

void
slock(SLock *s)
{
	int i;

	for(i = 0; i < 1000; 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
dolock(void (*work)(void), int n)
{
	int i;

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

void
doqlock(void (*work)(void), int n)
{
	int i;

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

void
doslock(void (*work)(void), int n)
{
	int i;

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

void
lockbench(void (*fn)(void(*)(void), int), int nthr, void (*work)(void), int ninc)
{
	static long thrwait;
	int i, p;

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

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

void	benchlock1_w(B *b)	{ lockbench(dolock, 1, work, b->N); }
void	benchqlock1_w(B *b)	{ lockbench(doqlock, 1, work, b->N); }
void	benchslock1_w(B *b)	{ lockbench(doslock, 1, work, b->N); }
void	benchlock4_w(B *b)	{ lockbench(dolock, 4, work, b->N); }
void	benchqlock4_w(B *b)	{ lockbench(doqlock, 4, work, b->N); }
void	benchslock4_w(B *b)	{ lockbench(doslock, 4, work, b->N); }
void	benchlock16_w(B *b)	{ lockbench(dolock, 16, work, b->N); }
void	benchqlock16_w(B *b)	{ lockbench(doqlock, 16, work, b->N); }
void	benchslock16_w(B *b)	{ lockbench(doslock, 16, work, b->N); }
void	benchlock64_w(B *b)	{ lockbench(dolock, 64, work, b->N); }
void	benchqlock64_w(B *b)	{ lockbench(doqlock, 64, work, b->N); }
void	benchslock64_w(B *b)	{ lockbench(doslock, 64, work, b->N); }
void	benchlock512_w(B *b)	{ lockbench(dolock, 512, work, b->N); }
void	benchqlock512_w(B *b)	{ lockbench(doqlock, 512, work, b->N); }
void	benchslock512_w(B *b)	{ lockbench(doslock, 512, work, b->N); }

void
main(int argc, char **argv)
{
	benchinit(argc, argv);

	print("== locking (fast work) ==\n");
	BM(benchlock1);
	BM(benchqlock1);
	BM(benchslock1);
	BM(benchlock4);
	BM(benchqlock4);
	BM(benchslock4);
	BM(benchlock16);
	BM(benchqlock16);
	BM(benchslock16);
	BM(benchlock64);
	BM(benchqlock64);
	BM(benchslock64);
	BM(benchlock512);
	BM(benchqlock512);
	BM(benchslock512);

	print("== locking (slow work) ==\n");
	BM(benchlock1_w);
	BM(benchqlock1_w);
	BM(benchslock1_w);
	BM(benchlock4_w);
	BM(benchqlock4_w);
	BM(benchslock4_w);
	BM(benchlock16_w);
	BM(benchqlock16_w);
	BM(benchslock16_w);
	BM(benchlock64_w);
	BM(benchqlock64_w);
	BM(benchslock64_w);
	BM(benchlock512_w);
	BM(benchqlock512_w);
	BM(benchslock512_w);
	exits(nil);
}