git: 9front

ref: 63a8d1e3eeb4504931640e00a1a067a2619199c0
dir: /sys/src/libc/test/lock.c/

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

Lock l;
QLock ql;
int counter;

void
inc(int *p)
{
	int i;

	lock(&l);
	for(i = 0; i < 10000; i++)
		*p += 1;
	unlock(&l);
}
void
dec(int *p)
{
	int i;

	lock(&l);
	for(i = 0; i < 10000; i++)
		*p -= 1;
	unlock(&l);
}

void
qinc(int *p)
{
	int i;

	qlock(&ql);
	for(i = 0; i < 10000; i++)
		*p += 1;
	qunlock(&ql);
}

void
qdec(int *p)
{
	int i;

	qlock(&ql);
	for(i = 0; i < 10000; i++)
		*p -= 1;
	qunlock(&ql);
}

int
spawn(void (*f)(int *), int *p)
{
	int pid;

	pid = rfork(RFMEM|RFPROC);
	switch(pid){
	case -1:
		sysfatal("rfork");
	case 0:
		f(p);
		exits("spawn");
	default:
		return pid;
	}
}

void
main(void)
{
	int i;

	/* smoke test: lock/unlock */
	assert(canlock(&l));
	unlock(&l);
	lock(&l);
	assert(!canlock(&l));
	unlock(&l);
	assert(canlock(&l));
	unlock(&l);

	/* smoke test: qlock/qunlock */
	assert(canqlock(&ql));
	qunlock(&ql);
	qlock(&ql);
	assert(!canqlock(&ql));
	qunlock(&ql);
	assert(canqlock(&ql));
	qunlock(&ql);

	/* lock from many procs */
	for(i = 0; i < 10; i++){
		spawn(inc, &counter);
		spawn(dec, &counter);
	}
	for(i = 0; i < 10; i++){
		free(wait());
		free(wait());
	}
	assert(counter == 0);

	/* lock from many procs */
	for(i = 0; i < 10; i++){
		spawn(qinc, &counter);
		spawn(qdec, &counter);
	}
	for(i = 0; i < 10; i++){
		free(wait());
		free(wait());
	}
	assert(counter == 0);
	exits(nil);
}