text: // Copyright 2010-2012 RethinkDB, all rights reserved.
  #ifndef ARCH_SPINLOCK_HPP_
  #define ARCH_SPINLOCK_HPP_
  
  #include <pthread.h>
  #include <string.h>
  
  #include "errors.hpp"
  
  // I don't know the "clean" way to detect the availability of the pthread
  // spinlock feature.  For now we just use __MACH__ to default to mutex (which
  // will just work) on Apple systems.  If it's ever useful, making our own
  // spinlock implementation could be an option.
  #if defined(__MACH__) || defined(_WIN32)
  #define PTHREAD_HAS_SPINLOCK 0
  #else
  #define PTHREAD_HAS_SPINLOCK 1
  #endif
  
  // TODO: we should use regular mutexes on single core CPU
  // instead of spinlocks
  
  class spinlock_t {
  public:
      friend class spinlock_acq_t;
  
      spinlock_t();
      ~spinlock_t();
  
  private:
      void lock();
      void unlock();
  
  #if PTHREAD_HAS_SPINLOCK
      pthread_spinlock_t l;
  #else
      pthread_mutex_t l;
  #endif
  
      DISABLE_COPYING(spinlock_t);
  };
  
  class spinlock_acq_t {
  public:
      explicit spinlock_acq_t(spinlock_t *the_lock) : the_lock_(the_lock) {
          the_lock_->lock();
      }
      ~spinlock_acq_t() {
          the_lock_->unlock();
      }
  
  private:
      spinlock_t *the_lock_;
  
      DISABLE_COPYING(spinlock_acq_t);
  };
  
  #endif /* ARCH_SPINLOCK_HPP_ */
  