void* power_measurement(void* arg) { struct mstimer timer; // according to the Intel docs, the counter wraps a most once per second // 100 ms should be short enough to always get good information init_msTimer(&timer, 100); init_data(); read_rapl_init(); start = now_ms(); timer_sleep(&timer); while(running) { take_measurement(); timer_sleep(&timer); } }
int main(int argc, char**argv) { printf("starting wrapper\n"); if (argc < 3) { printf("Usage: %s <watt_cap> <executable> <args>...\n", argv[0]); return 1; } if (highlander()) { /* Start the log file. */ int logfd; char hostname[64]; gethostname(hostname, 64); char *fname; int ret = asprintf(&fname, "%s.power.dat", hostname); if (ret < 0) { printf("Fatal Error: Cannot allocate memory for fname.\n"); return 1; } logfd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_NOATIME|O_NDELAY, S_IRUSR|S_IWUSR); if (logfd < 0) { printf("Fatal Error: %s on %s cannot open the appropriate fd.\n", argv[0], hostname); return 1; } logfile = fdopen(logfd, "w"); read_rapl_init(); /* Set the cap. */ watt_cap = strtod(argv[1], NULL); set_rapl_power(watt_cap, watt_cap); /* Start power measurement thread. */ pthread_t mthread; pthread_create(&mthread, NULL, power_set_measurement, NULL); /* Fork. */ pid_t app_pid = fork(); if (app_pid == 0) { /* I'm the child. */ execvp(argv[2], &argv[2]); return 1; } /* Wait. */ waitpid(app_pid, NULL, 0); sleep(1); highlander_wait(); /* Stop power measurement thread. */ running = 0; take_measurement(); end = now_ms(); /* Output summary data. */ char *msg; ret = asprintf(&msg, "host: %s\npid: %d\ntotal: %lf\nallocated: %lf\nmax_watts: %lf\nmin_watts: %lf\nruntime ms: %lu\n,start: %lu\nend: %lu\n", hostname, app_pid, total_joules, limit_joules, max_watts, min_watts, end-start, start, end); if (ret < 0) { printf("Fatal Error: Cannot allocate memory for msg.\n"); return 1; } fprintf(logfile, "%s", msg); fclose(logfile); close(logfd); shmctl(shmid, IPC_RMID, NULL); shmdt(shmseg); } else { /* Fork. */ pid_t app_pid = fork(); if (app_pid == 0) { /* I'm the child. */ execvp(argv[2], &argv[2]); return 1; } /* Wait. */ waitpid(app_pid, NULL, 0); highlander_wait(); } return 0; }