#include #include #include #include #include #include #define LOOP_ITERATIONS 10000000 #define TWO_THREADS() 1 #define USE_MUTEX() 1 sem_t thread1sem; sem_t thread2sem; #if USE_MUTEX() pthread_mutex_t thread1mutex; pthread_mutex_t thread2mutex; #endif unsigned long counter1; unsigned long counter2; unsigned long long startTime1; unsigned long long endTime1; unsigned long long startTime2; unsigned long long endTime2; extern "C" long long timespec_to_nanosecond(struct timespec const *ts) { long long nanosecond = ts->tv_sec; nanosecond *= 1000000000; nanosecond += ts->tv_nsec; return nanosecond; } void * thread1(void *arg) { struct timespec currentTime; sem_wait(&thread1sem); // Wait on signal from parent. sleep(1); // Sleep to make sure this thread doesn't // finish before the parent has a chance // to create the other thread(s) clock_gettime(CLOCK_REALTIME, ¤tTime); startTime1 = timespec_to_nanosecond(¤tTime); for(unsigned long long i = 0; i < LOOP_ITERATIONS; ++i); { #if USE_MUTEX() pthread_mutex_lock(&thread1mutex); #endif ++counter1; #if USE_MUTEX() pthread_mutex_unlock(&thread1mutex); #endif #if TWO_THREADS() == 0 #if USE_MUTEX() pthread_mutex_lock(&thread2mutex); #endif ++counter2; #if USE_MUTEX() pthread_mutex_unlock(&thread2mutex); #endif #endif } clock_gettime(CLOCK_REALTIME, ¤tTime); endTime1 = timespec_to_nanosecond(¤tTime); } #if TWO_THREADS() void * thread2(void *arg) { struct timespec currentTime; sem_wait(&thread2sem); // Wait on signal from parent. sleep(1); // Sleep to make sure this thread doesn't // finish before the parent has a chance // to create the other thread(s) clock_gettime(CLOCK_REALTIME, ¤tTime); startTime2 = timespec_to_nanosecond(¤tTime); for(unsigned long long i = 0; i < LOOP_ITERATIONS; ++i) { #if USE_MUTEX() pthread_mutex_lock(&thread2mutex); #endif ++counter2; #if USE_MUTEX() pthread_mutex_unlock(&thread2mutex); #endif } clock_gettime(CLOCK_REALTIME, ¤tTime); endTime2 = timespec_to_nanosecond(¤tTime); } #endif int main() { #if (USE_MUTEX() == 0) #if (TWO_THREADS() == 0) std::cout << "One Thread, no protection" << std::endl; #else std::cout << "Two Threads, no protection" << std::endl; #endif #else #if (TWO_THREADS() == 0) std::cout << "One Thread, mutexes" << std::endl; #else std::cout << "Two Threads, mutexes" << std::endl; #endif #endif sem_init(&thread1sem,0,0); sem_init(&thread2sem,0,0); #if USE_MUTEX() pthread_mutex_init(&thread1mutex, 0); pthread_mutex_init(&thread2mutex, 0); #endif pthread_t tid1; pthread_attr_t attr1; pthread_attr_init(&attr1); struct sched_param param1; param1.sched_priority = sched_get_priority_max(SCHED_RR); pthread_create(&tid1, &attr1, &thread1, NULL); pthread_setschedparam(tid1, SCHED_RR, ¶m1); #if TWO_THREADS() pthread_t tid2; pthread_attr_t attr2; pthread_attr_init(&attr2); struct sched_param param2; param2.sched_priority = sched_get_priority_max(SCHED_RR); pthread_create(&tid2, &attr2, &thread2, NULL); pthread_setschedparam(tid2, SCHED_RR, ¶m2); #endif // timed section sem_post(&thread1sem); sem_post(&thread2sem); pthread_join(tid1, NULL); #if TWO_THREADS() pthread_join(tid2, NULL); #endif // end timed section // sleep(10); #if TWO_THREADS() unsigned long long startTime = std::min(startTime1, startTime2); unsigned long long endTime = std::max(endTime1, endTime2); #else unsigned long long startTime = startTime1; unsigned long long endTime = endTime1; #endif printf("Total time: %20llu ns\n", (endTime - startTime)); return 0; }