ref: 721724916347c46df7cfa3105ac6fd1f6da652ed
dir: /spawn.c/
#include <u.h> #include <libc.h> #include "bench.h" #define DirtySz 1024*1024*1024 void *junk; #ifdef NOPE void setupfork(void) { if(DirtySz != 0){ if((junk = malloc(DirtySz)) == nil) sysfatal("malloc: %r"); memset(junk, 42, DirtySz); } } #endif void doit(void (*fn)(int), int n) { int r, i; for(i = 0; i < NPROC; i++){ r = fork(); if(r == -1) sysfatal("rfork: %r"); if(r == 0){ fn(n/NPROC); exits(nil); } } for(i = 0; i < NPROC; i++) waitpid(); } void benchfork(int N) { int i; for(i = 0; i < N; i++){ if(!fork()) exits(nil); waitpid(); } } void benchrforkm(int N) { int i; for(i = 0; i < N; i++){ if(!rfork(RFPROC|RFMEM)) exits(nil); waitpid(); } } void benchexec(int N) { int i; for(i = 0; i < N; i++){ switch(fork()){ case -1: abort(); case 0: execl("./6.nop", "6.nop", nil); print("exec: %r"); abort(); default: waitpid(); } } } void benchexecm(int N) { int i; for(i = 0; i < N; i++){ switch(rfork(RFPROC|RFMEM)){ case -1: abort(); case 0: execl("./6.nop", "6.nop", nil); print("exec: %r"); abort(); default: waitpid(); } } } void benchfork1(B *b) { benchfork(b->N); } void benchforkN(B *b) { doit(benchfork, b->N); } void benchrforkm1(B *b) { benchrforkm(b->N); } void benchrforkmN(B *b) { doit(benchrforkm, b->N); } void benchexec1(B *b) { benchexec(b->N); } void benchexecN(B *b) { doit(benchexec, b->N); } void benchexecm1(B *b) { benchexecm(b->N); } void benchexecmN(B *b) { doit(benchexecm, b->N); } void main(int argc, char **argv) { benchinit(argc, argv); print("== fork/exec (single spawner) ==\n"); BM(benchfork1); BM(benchrforkm1); BM(benchexec1); BM(benchexecm1); print("== fork/exec (%d spawners) ==\n", NPROC); BM(benchforkN); BM(benchrforkmN); BM(benchexecN); BM(benchexecmN); exits(nil); }