/* * Written by Josh Dybnis and released to the public domain, as explained at * http://creativecommons.org/licenses/publicdomain */ #include #include #include #include //#define USE_MFENCE #define NUM_ITERATIONS 10000000 static volatile int wait_; static volatile int count_ = 0; static volatile int guard0_ = 0; static volatile int guard1_ = 0; void *worker0 (void *arg) { __sync_fetch_and_add(&wait_, -1); do {} while (wait_); // Wait for all the worker threads to be ready. int i; for (i = 0; i < NUM_ITERATIONS; ++ i) { guard0_ = 1; // prevent re-ordering of the above store (guard0_ = 1) and subsequent loads #ifdef USE_MFENCE __asm__ __volatile__("mfence"); #else { int dummy = guard0_; dummy = dummy; } #endif while (guard1_) { __asm__ __volatile__("rep;nop"); } count_ = count_ + 1; guard0_ = 0; } return NULL; } void *worker1 (void *arg) { __sync_fetch_and_add(&wait_, -1); do {} while (wait_); // Wait for all the worker threads to be ready. int i; for (i = 0; i < NUM_ITERATIONS; ++ i) { guard1_ = 1; // prevent re-ordering of the above store (guard1_ = 1) and subsequent loads #ifdef USE_MFENCE __asm__ __volatile__("mfence"); #else { int dummy = guard1_; dummy = dummy; } #endif while (guard0_) { guard1_ = 0; // prevent re-ordering of the above store (guard1_ = 0) and subsequent loads #ifdef USE_MFENCE __asm__ __volatile__("mfence"); #else { int dummy = guard1_; dummy = dummy; } #endif while (guard0_) { __asm__ __volatile__("rep;nop"); } guard1_ = 1; // prevent re-ordering of the above store (guard1_ = 1) and subsequent loads #ifdef USE_MFENCE __asm__ __volatile__("mfence"); #else { int dummy = guard1_; dummy = dummy; } #endif } count_ = count_ + 1; guard1_ = 0; } return NULL; } int main (int argc, char **argv) { struct timeval tv1, tv2; gettimeofday(&tv1, NULL); wait_ = 2; int rc; pthread_t thread0, thread1; rc = pthread_create(&thread0, NULL, worker0, NULL); if (rc != 0) { perror("pthread_create"); return rc; } rc = pthread_create(&thread1, NULL, worker1, NULL); if (rc != 0) { perror("pthread_create"); return rc; } pthread_join(thread0, NULL); pthread_join(thread1, NULL); gettimeofday(&tv2, NULL); int ms = (int)(1000000*(tv2.tv_sec - tv1.tv_sec) + tv2.tv_usec - tv1.tv_usec) / 1000; printf("Count: %d Time:%dms\n\n", count_, ms); fflush(stdout); return 0; }