#include #include #include #include // compile command line // gcc pthread_concurrency.c -D_GNU_SOURCE -o pthread_concurrency -lpthread -lrt struct timespec diff_timespec(struct timespec start, struct timespec end); long long millisec_elapsed(struct timespec diff); #define FIFTY_MILLION 50000000 int main(int argc, char** argv) { struct timespec start; struct timespec end; struct timespec diff; int i; pthread_mutex_t mutex; pthread_mutex_init(&mutex, NULL); pthread_rwlock_t rwlock; pthread_rwlock_init(&rwlock, NULL); pthread_spinlock_t spinlock; pthread_spin_init(&spinlock, 0); // TEST speed of mutex ////////////////////////////////////////// clock_gettime(CLOCK_MONOTONIC, &start); for (i = 0 ; i < FIFTY_MILLION; ++i) { pthread_mutex_lock(&mutex); pthread_mutex_unlock(&mutex); } clock_gettime(CLOCK_MONOTONIC, &end); diff = diff_timespec(start, end); printf("mutex took %lld milliseconds\n", millisec_elapsed(diff)); ///////////////////////////////////////////////////////////////// // TEST speed of read lock ////////////////////////////////////////// clock_gettime(CLOCK_MONOTONIC, &start); for (i = 0 ; i < FIFTY_MILLION; ++i) { pthread_rwlock_rdlock(&rwlock); pthread_rwlock_unlock(&rwlock); } clock_gettime(CLOCK_MONOTONIC, &end); diff = diff_timespec(start, end); printf("read lock took %lld milliseconds\n", millisec_elapsed(diff)); ///////////////////////////////////////////////////////////////// // TEST speed of write lock ////////////////////////////////////////// clock_gettime(CLOCK_MONOTONIC, &start); for (i = 0 ; i < FIFTY_MILLION; ++i) { pthread_rwlock_wrlock(&rwlock); pthread_rwlock_unlock(&rwlock); } clock_gettime(CLOCK_MONOTONIC, &end); diff = diff_timespec(start, end); printf("write lock took %lld milliseconds\n", millisec_elapsed(diff)); ///////////////////////////////////////////////////////////////// // TEST speed of spin lock ////////////////////////////////////////// clock_gettime(CLOCK_MONOTONIC, &start); for (i = 0 ; i < FIFTY_MILLION; ++i) { pthread_spin_lock(&spinlock); pthread_spin_unlock(&spinlock); } clock_gettime(CLOCK_MONOTONIC, &end); diff = diff_timespec(start, end); printf("spin lock took %lld milliseconds\n", millisec_elapsed(diff)); ///////////////////////////////////////////////////////////////// pthread_mutex_destroy(&mutex); pthread_rwlock_destroy(&rwlock); pthread_spin_destroy(&spinlock); return 0; } struct timespec diff_timespec(struct timespec start, struct timespec end) { struct timespec result; if (end.tv_nsec < start.tv_nsec){ // peform carry like in normal subtraction // 123456789 result.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec; result.tv_sec = end.tv_sec - 1 - start.tv_sec; } else{ result.tv_nsec = end.tv_nsec - start.tv_nsec; result.tv_sec = end.tv_sec - start.tv_sec; } return result; } long long millisec_elapsed(struct timespec diff){ // 123 123456 return ((long long)diff.tv_sec * 1000) + (diff.tv_nsec / 1000000); }