#include #include #include #include "atomic_ops.h" /* Timing code stolen from Ellis/Kovac/Boehm GCBench. */ #define currentTime() stats_rtclock() #define elapsedTime(x) (x) unsigned long stats_rtclock( void ) { struct timeval t; struct timezone tz; if (gettimeofday( &t, &tz ) == -1) return 0; return (t.tv_sec * 1000 + t.tv_usec / 1000); } AO_TS_T my_spin_lock = AO_TS_INITIALIZER; pthread_mutex_t my_pthread_lock = PTHREAD_MUTEX_INITIALIZER; void spin_lock_ool(AO_TS_T *lock) { /* Should repeatly retry the AO_test_and_set_acquire, perhaps */ /* after trying a plain read. Should "exponentially" back off */ /* between tries. For short time periods it should spin, for */ /* medium ones it should use sched_yield, and for longer ones usleep. */ /* For now we punt, since this is a contention-free test. */ abort(); } inline void spin_lock(AO_TS_T *lock) { if (__builtin_expect(AO_test_and_set_acquire(lock) != AO_TS_CLEAR, 0)) spin_lock_ool(lock); } inline void spin_unlock(AO_TS_T *lock) { AO_CLEAR(lock); } int main() { unsigned long start_time, end_time; int i; start_time = currentTime(); for (i = 0; i < 10000000; ++i) { spin_lock(&my_spin_lock); spin_unlock(&my_spin_lock); } end_time = currentTime(); fprintf(stderr, "Custom lock: %lu msecs\n", elapsedTime(end_time - start_time)); start_time = currentTime(); for (i = 0; i < 10000000; ++i) { pthread_mutex_lock(&my_pthread_lock); pthread_mutex_unlock(&my_pthread_lock); } end_time = currentTime(); fprintf(stderr, "Pthread lock: %lu msecs\n", elapsedTime(end_time - start_time)); return 0; }