/* this creates the specified number of child processes and runs fn() in all of them */ static double create_procs(int nprocs, void (*fn)(struct child_struct * )) { int i, status; int synccount; #ifdef OS2 int cRunning; #endif #ifndef OS2 signal(SIGCONT, sigcont); #endif start_timer(); synccount = 0; if (nprocs < 1) { fprintf(stderr, "create %d procs? you must be kidding.\n", nprocs); return 1; } children = shm_setup(sizeof(struct child_struct)*nprocs); if (!children) { printf("Failed to setup shared memory\n"); return end_timer(); } #ifdef OS2 sem_create_os2(); #endif memset(children, 0, sizeof(*children)*nprocs); for (i=0;i<nprocs;i++) { children[i].id = i; children[i].nprocs = nprocs; } for (i=0;i<nprocs;i++) { if (fork() == 0) { #ifdef OS2 shm_attach_os2(); #endif setbuffer(stdout, NULL, 0); nb_setup(&children[i]); children[i].status = getpid(); #ifndef OS2 pause(); #else sem_wait_os2(); #endif fn(&children[i]); _exit(0); } } do { synccount = 0; for (i=0;i<nprocs;i++) { if (children[i].status) synccount++; } if (synccount == nprocs) break; sleep(1); } while (end_timer() < 30); if (synccount != nprocs) { printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount); return end_timer(); } start_timer(); #ifndef OS2 kill(0, SIGCONT); signal(SIGALRM, sig_alarm); alarm(PRINT_FREQ); printf("%d clients started\n", nprocs); for (i=0;i<nprocs;) { if (waitpid(0, &status, 0) == -1) continue; if (WEXITSTATUS(status) != 0) { printf("Child failed with status %d\n", WEXITSTATUS(status)); exit(1); } i++; } alarm(0); sig_alarm(); #else sem_signal_os2(); printf("%d clients started\n", nprocs); do { sleep(1); sig_alarm(); for (cRunning = i = 0; i < nprocs; i++) if (!children[i].done) cRunning++; } while (cRunning > 0); status = status; #endif printf("\n"); return end_timer(); }
/* this creates the specified number of child processes and runs fn() in all of them */ static void create_procs(int nprocs, void (*fn)(struct child_struct *, const char *)) { int nclients = nprocs * options.clients_per_process; int i, status; int synccount; struct timeval tv; gzFile *load; struct sembuf sbuf; double t; load = open_loadfile(); if (load == NULL) { exit(1); } if (nprocs < 1) { fprintf(stderr, "create %d procs? you must be kidding.\n", nprocs); return; } children = shm_setup(sizeof(struct child_struct)*nclients); if (!children) { printf("Failed to setup shared memory\n"); return; } memset(children, 0, sizeof(*children)*nclients); for (i=0;i<nclients;i++) { children[i].id = i; children[i].num_clients = nclients; children[i].cleanup = 0; children[i].directory = options.directory; children[i].starttime = timeval_current(); children[i].lasttime = timeval_current(); } if (atexit(sem_cleanup) != 0) { printf("can't register cleanup function on exit\n"); exit(1); } sbuf.sem_num = 0; if ( !(barrier = semget(IPC_PRIVATE,1,IPC_CREAT | S_IRUSR | S_IWUSR)) ) { printf("failed to create barrier semaphore \n"); } sbuf.sem_flg = SEM_UNDO; sbuf.sem_op = 1; if (semop(barrier, &sbuf, 1) == -1) { printf("failed to initialize the barrier semaphore\n"); exit(1); } sbuf.sem_flg = 0; for (i=0;i<nprocs;i++) { if (fork() == 0) { int j; setlinebuf(stdout); srandom(getpid() ^ time(NULL)); for (j=0;j<options.clients_per_process;j++) { nb_ops->setup(&children[i*options.clients_per_process + j]); } sbuf.sem_op = 0; if (semop(barrier, &sbuf, 1) == -1) { printf("failed to use the barrier semaphore in child %d\n",getpid()); exit(1); } fn(&children[i*options.clients_per_process], options.loadfile); _exit(0); } } synccount = 0; tv = timeval_current(); do { synccount = semctl(barrier,0,GETZCNT); t = timeval_elapsed(&tv); printf("%d of %d processes prepared for launch %3.0f sec\n", synccount, nprocs, t); if (synccount == nprocs) break; usleep(100*1000); } while (timeval_elapsed(&tv) < 30); if (synccount != nprocs) { printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount); return; } printf("releasing clients\n"); tv_start = timeval_current(); sbuf.sem_op = -1; if (semop(barrier, &sbuf, 1) == -1) { printf("failed to release barrier\n"); exit(1); } signal(SIGALRM, sig_alarm); alarm(PRINT_FREQ); for (i=0;i<nprocs;) { if (waitpid(0, &status, 0) == -1) continue; if (WEXITSTATUS(status) != 0) { printf("Child failed with status %d\n", WEXITSTATUS(status)); exit(1); } i++; } alarm(0); sig_alarm(SIGALRM); semctl(barrier,0,IPC_RMID); printf("\n"); report_latencies(); }