static void print_summary(void) { double requeuetime_avg = avg_stats(&requeuetime_stats); double requeuetime_stddev = stddev_stats(&requeuetime_stats); unsigned int requeued_avg = avg_stats(&requeued_stats); printf("Requeued %d of %d threads in %.4f ms (+-%.2f%%)\n", requeued_avg, nthreads, requeuetime_avg / USEC_PER_MSEC, rel_stddev_stats(requeuetime_stddev, requeuetime_avg)); }
static void print_summary(void) { unsigned long avg = avg_stats(&throughput_stats); double stddev = stddev_stats(&throughput_stats); printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n", !silent ? "\n" : "", avg, rel_stddev_stats(stddev, avg), (int) runtime.tv_sec); }
int main(int ac, char **av) { int ret; int i; int semid = 0; int sem_num = 0; int burn_count = 0; struct sem_wakeup_info *wi = NULL; struct timeval start; struct timeval now; int num_semids = 0; int wake_num = 256; int run_secs = 30; int pagesize = getpagesize(); char *buf = malloc(pagesize); struct sem_operations *ops = allops[0]; cpu_set_t cpu_mask; cpu_set_t target_mask; int target_cpu = 0; int max_cpu = -1; if (!buf) { perror("malloc"); exit(1); } for (i = 1; i < ac; i++) { if (strcmp(av[i], "-t") == 0) { if (i == ac -1) print_usage(); num_threads = atoi(av[i+1]); i++; } else if (strcmp(av[i], "-w") == 0) { if (i == ac -1) print_usage(); wake_num = atoi(av[i+1]); i++; } else if (strcmp(av[i], "-r") == 0) { if (i == ac -1) print_usage(); run_secs = atoi(av[i+1]); i++; } else if (strcmp(av[i], "-o") == 0) { int index; if (i == ac -1) print_usage(); index = atoi(av[i+1]); if (index >= NUM_OPERATIONS) { fprintf(stderr, "invalid operations %d\n", index); exit(1); } ops = allops[index]; i++; } else if (strcmp(av[i], "-T") == 0) { timeout_test = 1; } else if (strcmp(av[i], "-h") == 0) { print_usage(); } } num_semids = (num_threads + SEMS_PERID - 1) / SEMS_PERID; ops->setup(&wi, num_semids); ret = sched_getaffinity(0, sizeof(cpu_set_t), &cpu_mask); if (ret) { perror("sched_getaffinity"); exit(1); } for (i = 0; i < CPU_SETSIZE; i++) if (CPU_ISSET(i, &cpu_mask)) max_cpu = i; if (max_cpu == -1) { fprintf(stderr, "sched_getaffinity returned empty mask\n"); exit(1); } CPU_ZERO(&target_mask); worklist = malloc(sizeof(*worklist) * num_threads); memset(worklist, 0, sizeof(*worklist) * num_threads); for (i = 0; i < num_threads; i++) { struct lockinfo *l; pthread_t tid; thread_count++; l = worklist + i; if (!l) { perror("malloc"); exit(1); } l->id = semid; l->index = sem_num++; l->ops = ops; if (sem_num >= SEMS_PERID) { semid++; sem_num = 0; } ret = pthread_create(&tid, NULL, worker, (void *)l); if (ret) { perror("pthread_create"); exit(1); } while (!CPU_ISSET(target_cpu, &cpu_mask)) { target_cpu++; if (target_cpu > max_cpu) target_cpu = 0; } CPU_SET(target_cpu, &target_mask); ret = pthread_setaffinity_np(tid, sizeof(cpu_set_t), &target_mask); CPU_CLR(target_cpu, &target_mask); target_cpu++; ret = pthread_detach(tid); if (ret) { perror("pthread_detach"); exit(1); } } while(!workers_started) { smp_mb(); usleep(200); } gettimeofday(&start, NULL); while(1) { ops->wake(wi, num_semids, wake_num); burn_count++; gettimeofday(&now, NULL); if (now.tv_sec - start.tv_sec >= run_secs) break; } all_done = 1; while(thread_count > 0) { ops->wake(wi, num_semids, wake_num); usleep(200); } printf("%d threads, waking %d at a time\n", num_threads, wake_num); printf("using %s\n", ops->name); printf("main thread burns: %d\n", burn_count); printf("worker burn count total %lu min %lu max %lu avg %.3f +- %.3f%%\n", total_burns, min_burns, max_burns, avg_stats(&burn_stats), 100 * stddev_stats(&burn_stats) / avg_stats(&burn_stats)); printf("run time %d seconds %lu worker burns per second\n", (int)(now.tv_sec - start.tv_sec), total_burns / (now.tv_sec - start.tv_sec)); ops->cleanup(num_semids); return 0; }