ref: 3f899338e54ae7ed97d980838a0c40e350718405
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
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);
}