/** * The main function. */ int main() { /* Seeding random number generator */ srand( time(NULL) ); int my_pid = getpid(); unsigned int period = get_period(); unsigned int computation_time = get_comp_time(period); register_process(my_pid, period, computation_time); if(!is_registered(my_pid)) { printf("%d: I was unable to register. ;_;\n", my_pid); exit(1); } printf("%d: Registered! \n", my_pid); unsigned int iterations = get_iterations(); yield(my_pid); while(iterations > 0) { struct timeval time; gettimeofday(&time); unsigned int start_time = time.tv_usec; unsigned int time_elapsed = 0; while(time_elapsed < computation_time) { int i; for(i = 0; i < 100; i++) { factorial((i % 20)+1); } gettimeofday(&time); time_elapsed = time.tv_usec - start_time; } yield(my_pid); iterations--; } unregister(my_pid); return 0; }
int main(int argc, char** argv) { if (argc != 2) { fprintf(stderr, "usage: %s <size of working set in 4K pages>\n", *argv); return 1; } const long ws_pages = strtol(argv[1], NULL, 10); if (ws_pages < 0) { fprintf(stderr, "Invalid usage: working set size must be positive\n"); return 1; } const int iterations = get_iterations(ws_pages); struct timespec ts; long long unsigned memset_time = 0; if (ws_pages) { void* buf = malloc(ws_pages * 4096); memset_time = time_ns(&ts); for (int i = 0; i < iterations; i++) { memset(buf, i, ws_pages * 4096); } memset_time = time_ns(&ts) - memset_time; printf("%i memset on %4liK in %10lluns (%.1fns/page)\n", iterations, ws_pages * 4, memset_time, (memset_time / ((float) ws_pages * iterations))); free(buf); } const int shm_id = shmget(IPC_PRIVATE, (ws_pages + 1) * 4096, IPC_CREAT | 0666); const pid_t other = fork(); int* futex = shmat(shm_id, NULL, 0); void* ws = ((char *) futex) + 4096; *futex = 0xA; if (other == 0) { for (int i = 0; i < iterations; i++) { sched_yield(); while (syscall(SYS_futex, futex, FUTEX_WAIT, 0xA, NULL, NULL, 42)) { // retry sched_yield(); } *futex = 0xB; if (ws_pages) { memset(ws, i, ws_pages * 4096); } while (!syscall(SYS_futex, futex, FUTEX_WAKE, 1, NULL, NULL, 42)) { // retry sched_yield(); } } return 0; } const long long unsigned start_ns = time_ns(&ts); for (int i = 0; i < iterations; i++) { *futex = 0xA; if (ws_pages) { memset(ws, i, ws_pages * 4096); } while (!syscall(SYS_futex, futex, FUTEX_WAKE, 1, NULL, NULL, 42)) { // retry sched_yield(); } sched_yield(); while (syscall(SYS_futex, futex, FUTEX_WAIT, 0xB, NULL, NULL, 42)) { // retry sched_yield(); } } const long long unsigned delta = time_ns(&ts) - start_ns - memset_time * 2; const int nswitches = iterations * 4; printf("%i process context switches (wss:%4liK) in %12lluns (%.1fns/ctxsw)\n", nswitches, ws_pages * 4, delta, (delta / (float) nswitches)); wait(futex); return 0; }