#include #include #include #include #include #include #include int usage() { printf("measure multi-thread work scheduling overhead\n"); printf("-nthreads N (number of worker threads, default 1)\n"); printf("-nworkitems N (number of work items, default 1)\n"); printf("-usleeptime N (work time, default 100)\n"); printf("-ntests N (number of test iterations, default 1)\n"); printf("-adaptive (use adaptive mutex locks, default no)\n"); return 1; } typedef struct workitem *WORKITEM; struct workitem { struct workitem *next_wq; int usleeptime; }; #include "workqueue.h" #include "threadpool.h" int usleeptime = 100; void do_work(WORKITEM wi __attribute__((unused))) { #if 0 // sleep for usleeptime microseconds usleep(usleeptime); #else // busy wait for usleeptime loop interations int n = wi->usleeptime; volatile int i; for (i=0; ilock); assert(r == 0); while (1) { WORKITEM wi; r = workqueue_deq(runner->wq, runner->lock, &wi); if (r != 0) break; r = pthread_mutex_unlock(runner->lock); assert(r == 0); do_work(wi); r = pthread_mutex_lock(runner->lock); assert(r == 0); workqueue_enq(runner->cq, wi); } r = pthread_mutex_unlock(runner->lock); assert(r == 0); return arg; } static inline void lockit(pthread_mutex_t *lock, int nthreads) { if (nthreads > 0) { int r = pthread_mutex_lock(lock); assert(r == 0); } } static inline void unlockit(pthread_mutex_t *lock, int nthreads) { if (nthreads > 0) { int r = pthread_mutex_unlock(lock); assert(r == 0); } } int main(int argc, char *argv[]) { int ntests = 1; int nworkitems = 1; int nthreads = 1; int adaptive = 0; int r; int i; for (i=1; i