ref: 3df92bd8dd256de9b90fd12a4d63d8bf458f1b83
dir: /test.c/
#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);
}