/* * lat_sem.c - semaphore test * * usage: lat_sem [-P ] [-W ] [-N ] * * Copyright (c) 2000 Carl Staelin. * Copyright (c) 1994 Larry McVoy. Distributed under the FSF GPL with * additional restriction that results may published only if * (1) the benchmark is unmodified, and * (2) the version in the sccsid below is included in the report. * Support for this development by Sun Microsystems is gratefully acknowledged. */ char *id = "$Id$\n"; #include "bench.h" #include void initialize(iter_t iterations, void *cookie); void cleanup(iter_t iterations, void *cookie); void doit(iter_t iterations, void *cookie); void writer(int sid); typedef struct _state { int pid; int semid; } state_t; int main(int ac, char **av) { state_t state; int parallel = 1; int warmup = 0; int repetitions = -1; int c; char* usage = "[-P ] [-W ] [-N ]\n"; while (( c = getopt(ac, av, "P:W:N:")) != EOF) { switch(c) { case 'P': parallel = atoi(optarg); if (parallel <= 0) lmbench_usage(ac, av, usage); break; case 'W': warmup = atoi(optarg); break; case 'N': repetitions = atoi(optarg); break; default: lmbench_usage(ac, av, usage); break; } } if (optind < ac) { lmbench_usage(ac, av, usage); } state.pid = 0; benchmp(initialize, doit, cleanup, SHORT, parallel, warmup, repetitions, &state); micro("Semaphore latency", get_n() * 2); return (0); } void initialize(iter_t iterations, void* cookie) { char c; state_t * state = (state_t *)cookie; if (iterations) return; state->semid = semget(IPC_PRIVATE, 2, IPC_CREAT | IPC_EXCL | 0600); semctl(state->semid, 0, SETVAL, 0); semctl(state->semid, 1, SETVAL, 0); handle_scheduler(benchmp_childid(), 0, 1); switch (state->pid = fork()) { case 0: signal(SIGTERM, exit); handle_scheduler(benchmp_childid(), 1, 1); writer(state->semid); return; case -1: perror("fork"); return; default: break; } } void cleanup(iter_t iterations, void* cookie) { state_t * state = (state_t *)cookie; if (iterations) return; if (state->pid) { kill(state->pid, SIGKILL); waitpid(state->pid, NULL, 0); state->pid = 0; } /* free the semaphores */ semctl(state->semid, 0, IPC_RMID); } void doit(register iter_t iterations, void *cookie) { state_t *state = (state_t *) cookie; struct sembuf sop[2]; sop[0].sem_num = 1; sop[0].sem_op = -1; sop[0].sem_flg = 0; sop[1].sem_num = 0; sop[1].sem_op = 1; sop[1].sem_flg = 0; while (iterations-- > 0) { if (semop(state->semid, sop, 2) < 0) { perror("(r) error on semaphore"); exit(1); } } } void writer(register int sid) { struct sembuf sop[2]; sop[0].sem_num = 1; sop[0].sem_op = 1; sop[0].sem_flg = 0; if (semop(sid, sop, 1) < 0) { perror("(w) error on initial semaphore"); exit(1); } sop[0].sem_num = 0; sop[0].sem_op = -1; sop[0].sem_flg = 0; sop[1].sem_num = 1; sop[1].sem_op = 1; sop[1].sem_flg = 0; for ( ;; ) { if (semop(sid, sop, 2) < 0) { perror("(w) error on semaphore"); exit(1); } } }