/* * gcc -Wall -Werror -O3 -static -o ctx ctx.c */ #define errx(x,y...) { fprintf(stderr, y); fprintf(stderr, "\n"); exit(x); } #include #include #include #include #include #if defined (LWP) #include #include #endif #define ITERATIONS 8192 #define PASSES 50 int fd0[2], fd1[2]; unsigned long elapsed_times[ITERATIONS]; unsigned long overhead; pid_t childpid; static void usage(void) { printf("ctx [-hl]\n"); exit(1); } static void child(void) { int ch; ch = 0; if (write(fd1[1], &ch, 1) != 1) errx(1, "child write failed"); while (1) { if (read(fd0[0], &ch, 1) != 1) errx(1, "child read failed"); if (write(fd1[1], &ch, 1) != 1) errx(1, "child write failed"); } } static void dump_results(void) { unsigned long min_time, max_time, sum; int i; min_time = elapsed_times[0]; max_time = elapsed_times[0]; sum = 0; for (i=1; i max_time) max_time = elapsed_times[i]; sum += elapsed_times[i] - overhead; } min_time -= overhead; max_time -= overhead; printf("min latency: %f\n", (double)min_time / PASSES); printf("max latency: %f\n", (double)max_time / PASSES); printf("mean latency: %f\n", (double)sum / ITERATIONS / PASSES); } int main(int argc, char *argv[]) { int i, ch, count; struct timeval before, after; unsigned long elapsed; int use_lwps = 0; memset(elapsed_times, 0, ITERATIONS); while ((ch = getopt(argc, argv, "hl")) != -1) { switch (ch) { case 'l': #if defined(LWP) use_lwps = 1; #else errx(1, "not supported"); #endif break; case 'h': usage(); } } argc -= optind; argv += optind; sleep(1); if (pipe(fd0) != 0) errx(1, "Unable to create pipe"); if (pipe(fd1) != 0) errx(1, "Unable to create pipe"); /* * Determine overhead */ for (count=0; count<2; count++) { gettimeofday(&before, NULL); for (i=0; i<2*(PASSES/2); i++) { ch = 0; write(fd0[1], &ch, 1); read(fd0[0], &ch, 1); } gettimeofday(&after, NULL); overhead = 1000000 * (after.tv_sec - before.tv_sec); overhead += after.tv_usec - before.tv_usec; } if (use_lwps) { #if defined(LWP) ucontext_t u; ucontext_t *contextp; int stacksize = 65536; void *stackbase; lwpid_t l; int error; getcontext(&u); contextp = (ucontext_t *)malloc(sizeof(ucontext_t)); stackbase = malloc(stacksize); sigprocmask(SIG_SETMASK, NULL, &contextp->uc_sigmask); _lwp_makecontext(contextp, child, NULL, NULL, stackbase, stacksize); error = _lwp_create(contextp, 0, &l); if (error) errx(1, "error _lwp_create"); #endif } else { switch (childpid = fork()) { case 0: /* child */ child(); case -1: /* error */ errx(1, "error forking"); break; } } ch = 0; if (read(fd1[0], &ch, 1) != 1) errx(1, "parent read failed"); for (count=0; count