int thrd_create(thrd_t* thr, thrd_start_t func, void* arg) { int ret = __pthread_create(thr, __ATTRP_C11_THREAD, (void* (*)(void*))func, arg); switch (ret) { case 0: return thrd_success; case EAGAIN: return thrd_nomem; default: return thrd_error; } }
int main(int argc, char** argv) { struct timeval start_tv = {0}; struct timeval end_tv = {0}; long usec_diff; long nr_ctx_switches; void *join_ret; if (argc > 1) nr_switch_loops = strtol(argv[1], 0, 10); printf("Making 2 threads of %d switches each\n", nr_switch_loops); pthread_can_vcore_request(FALSE); /* 2LS won't manage vcores */ pthread_need_tls(FALSE); pthread_lib_init(); /* gives us one vcore */ /* each is passed the other's pthread_t. th1 starts the switching. */ if (pthread_create(&th1, NULL, &switch_thread, &th2)) perror("pth_create 1 failed"); /* thread 2 is created, but not put on the runnable list */ if (__pthread_create(&th2, NULL, &switch_thread, &th1)) perror("pth_create 2 failed"); if (gettimeofday(&start_tv, 0)) perror("Start time error..."); ready = TRUE; /* signal to any spinning uthreads to start */ pthread_join(th1, &join_ret); pthread_join(th2, &join_ret); if (gettimeofday(&end_tv, 0)) perror("End time error..."); nr_ctx_switches = 2 * nr_switch_loops; usec_diff = (end_tv.tv_sec - start_tv.tv_sec) * 1000000 + (end_tv.tv_usec - start_tv.tv_usec); printf("Done: %d loops\n", nr_switch_loops); printf("Nr context switches: %ld\n", nr_ctx_switches); printf("Time to run: %ld usec\n", usec_diff); printf("Context switch latency: %d nsec\n", (int)(1000LL*usec_diff / nr_ctx_switches)); printf("Context switches / sec: %d\n\n", (int)(1000000LL*nr_ctx_switches / usec_diff)); }