1 /* 2 * gcc -Wall -Werror -O3 -static -o ctx ctx.c 3 */ 4 5 #define errx(x,y...) { fprintf(stderr, y); fprintf(stderr, "\n"); exit(x); } 6 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <unistd.h> 10 #include <sys/time.h> 11 #include <signal.h> 12 #if defined (LWP) 13 #include <sys/ucontext.h> 14 #include <sys/lwp.h> 15 #endif 16 17 #define ITERATIONS 8192 18 #define PASSES 50 19 20 int fd0[2], fd1[2]; 21 unsigned long elapsed_times[ITERATIONS]; 22 unsigned long overhead; 23 pid_t childpid; 24 25 static void 26 usage(void) 27 { 28 printf("ctx [-hl]\n"); 29 exit(1); 30 } 31 32 static void 33 child(void) 34 { 35 int ch; 36 37 ch = 0; 38 if (write(fd1[1], &ch, 1) != 1) 39 errx(1, "child write failed"); 40 while (1) { 41 if (read(fd0[0], &ch, 1) != 1) 42 errx(1, "child read failed"); 43 if (write(fd1[1], &ch, 1) != 1) 44 errx(1, "child write failed"); 45 } 46 } 47 48 static void 49 dump_results(void) 50 { 51 unsigned long min_time, max_time, sum; 52 int i; 53 54 min_time = elapsed_times[0]; 55 max_time = elapsed_times[0]; 56 sum = 0; 57 for (i=1; i<ITERATIONS; i++) { 58 if (elapsed_times[i] < min_time) 59 min_time = elapsed_times[i]; 60 if (elapsed_times[i] > max_time) 61 max_time = elapsed_times[i]; 62 sum += elapsed_times[i] - overhead; 63 } 64 min_time -= overhead; 65 max_time -= overhead; 66 67 printf("min latency: %f\n", (double)min_time / PASSES); 68 printf("max latency: %f\n", (double)max_time / PASSES); 69 printf("mean latency: %f\n", (double)sum / ITERATIONS / PASSES); 70 } 71 72 int 73 main(int argc, char *argv[]) 74 { 75 int i, ch, count; 76 struct timeval before, after; 77 unsigned long elapsed; 78 int use_lwps = 0; 79 80 memset(elapsed_times, 0, ITERATIONS); 81 82 while ((ch = getopt(argc, argv, "hl")) != -1) { 83 switch (ch) { 84 case 'l': 85 #if defined(LWP) 86 use_lwps = 1; 87 #else 88 errx(1, "not supported"); 89 #endif 90 break; 91 case 'h': 92 usage(); 93 } 94 } 95 argc -= optind; 96 argv += optind; 97 98 sleep(1); 99 100 if (pipe(fd0) != 0) 101 errx(1, "Unable to create pipe"); 102 if (pipe(fd1) != 0) 103 errx(1, "Unable to create pipe"); 104 105 /* 106 * Determine overhead 107 */ 108 for (count=0; count<2; count++) { 109 gettimeofday(&before, NULL); 110 for (i=0; i<2*(PASSES/2); i++) { 111 ch = 0; 112 write(fd0[1], &ch, 1); 113 read(fd0[0], &ch, 1); 114 } 115 gettimeofday(&after, NULL); 116 overhead = 1000000 * (after.tv_sec - before.tv_sec); 117 overhead += after.tv_usec - before.tv_usec; 118 } 119 120 if (use_lwps) { 121 #if defined(LWP) 122 ucontext_t u; 123 ucontext_t *contextp; 124 int stacksize = 65536; 125 void *stackbase; 126 lwpid_t l; 127 int error; 128 129 getcontext(&u); 130 contextp = (ucontext_t *)malloc(sizeof(ucontext_t)); 131 stackbase = malloc(stacksize); 132 sigprocmask(SIG_SETMASK, NULL, &contextp->uc_sigmask); 133 _lwp_makecontext(contextp, child, NULL, NULL, 134 stackbase, stacksize); 135 error = _lwp_create(contextp, 0, &l); 136 if (error) 137 errx(1, "error _lwp_create"); 138 #endif 139 } else { 140 switch (childpid = fork()) { 141 case 0: /* child */ 142 child(); 143 case -1: /* error */ 144 errx(1, "error forking"); 145 break; 146 } 147 } 148 149 ch = 0; 150 if (read(fd1[0], &ch, 1) != 1) 151 errx(1, "parent read failed"); 152 for (count=0; count<ITERATIONS; count++) { 153 gettimeofday(&before, NULL); 154 for (i=0; i<PASSES/2; i++) { 155 ch = 0; 156 if (write(fd0[1], &ch, 1) != 1) 157 errx(1, "parent write failed"); 158 if (read(fd1[0], &ch, 1) != 1) 159 errx(1, "parent read failed"); 160 } 161 gettimeofday(&after, NULL); 162 elapsed = 1000000 * (after.tv_sec - before.tv_sec); 163 elapsed += after.tv_usec - before.tv_usec; 164 elapsed_times[count] = elapsed; 165 } 166 167 if (!use_lwps) 168 kill(childpid, SIGTERM); 169 dump_results(); 170 171 return (0); 172 } 173 174 175 /* 176 * PMAX_SA: 177 * 178 * min latency: 93.100000 179 * max latency: 150.700000 180 * mean latency: 100.857581 181 * 182 * PMAX_CHOOSEPROC: 183 * 184 * min latency: 49.350000 185 * max latency: 76.750000 186 * mean latency: 54.141626 187 * 188 * PMAX_OLD: 189 * 190 * min latency: 54.750000 191 * max latency: 76.050000 192 * mean latency: 60.088654 193 * 194 * HP300_SA: 195 * 196 * min latency: 352.560000 197 * max latency: 402.960000 198 * mean latency: 367.836250 199 * 200 * HP300_CHOOSEPROC: 201 * 202 * min latency: 129.200000 203 * max latency: 187.040000 204 * mean latency: 142.528223 205 * 206 * HP300_OLD: 207 * 208 * min latency: 357.360000 209 * max latency: 414.400000 210 * mean latency: 372.436104 211 * 212 */ 213