// gold-threads.cc -- thread support for gold #include "gold.h" #ifdef ENABLE_THREADS #include #endif #include "gold-threads.h" namespace gold { // Class Lock_impl. class Lock_impl { public: Lock_impl(); ~Lock_impl(); void acquire(); void release(); private: // This class can not be copied. Lock_impl(const Lock_impl&); Lock_impl& operator=(const Lock_impl&); friend class Condvar_impl; #ifdef ENABLE_THREADS pthread_mutex_t mutex_; #else bool acquired_; #endif }; #ifdef ENABLE_THREADS Lock_impl::Lock_impl() { pthread_mutexattr_t attr; if (pthread_mutexattr_init(&attr) != 0) gold_fatal(_("pthead_mutextattr_init failed"), true); #ifdef PTHREAD_MUTEXT_ADAPTIVE_NP if (pthread_mutextattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP) != 0) gold_fatal(_("pthread_mutextattr_settype failed"), true); #endif if (pthread_mutex_init (&this->mutex_, &attr) != 0) gold_fatal(_("pthread_mutex_init failed"), true); if (pthread_mutexattr_destroy(&attr) != 0) gold_fatal(_("pthread_mutexattr_destroy failed"), true); } Lock_impl::~Lock_impl() { if (pthread_mutex_destroy(&this->mutex_) != 0) gold_fatal(_("pthread_mutex_destroy failed"), true); } void Lock_impl::acquire() { if (pthread_mutex_lock(&this->mutex_) != 0) gold_fatal(_("pthread_mutex_lock failed"), true); } void Lock_impl::release() { if (pthread_mutex_unlock(&this->mutex_) != 0) gold_fatal(_("pthread_mutex_unlock failed"), true); } #else // !defined(ENABLE_THREADS) Lock_impl::Lock_impl() : acquired_(false) { } Lock_impl::~Lock_impl() { gold_assert(!this->acquired_); } void Lock_impl::acquire() { gold_assert(!this->acquired_); this->acquired_ = true; } void Lock_impl::release() { gold_assert(this->acquired_); this->acquired_ = false; } #endif // !defined(ENABLE_THREADS) // Methods for Lock class. Lock::Lock() { this->lock_ = new Lock_impl; } Lock::~Lock() { delete this->lock_; } void Lock::acquire() { this->lock_->acquire(); } void Lock::release() { this->lock_->release(); } // Class Condvar_impl. class Condvar_impl { public: Condvar_impl(); ~Condvar_impl(); void wait(Lock_impl*); void signal(); private: // This class can not be copied. Condvar_impl(const Condvar_impl&); Condvar_impl& operator=(const Condvar_impl&); #ifdef ENABLE_THREADS pthread_cond_t cond_; #endif }; #ifdef ENABLE_THREADS Condvar_impl::Condvar_impl() { if (pthread_cond_init(&this->cond_, NULL) != 0) gold_fatal(_("pthread_cond_init failed"), true); } Condvar_impl::~Condvar_impl() { if (pthread_cond_destroy(&this->cond_) != 0) gold_fatal(_("pthread_cond_destroy failed"), true); } void Condvar_impl::wait(Lock_impl* li) { if (pthread_cond_wait(&this->cond_, &li->mutex_) != 0) gold_fatal(_("pthread_cond_wait failed"), true); } void Condvar_impl::signal() { if (pthread_cond_signal(&this->cond_) != 0) gold_fatal(_("pthread_cond_signal failed"), true); } #else // !defined(ENABLE_THREADS) Condvar_impl::Condvar_impl() { } Condvar_impl::~Condvar_impl() { } void Condvar_impl::wait(Lock_impl* li) { gold_assert(li->acquired_); } void Condvar_impl::signal() { } #endif // !defined(ENABLE_THREADS) // Methods for Condvar class. Condvar::Condvar(Lock& lock) : lock_(lock) { this->condvar_ = new Condvar_impl; } Condvar::~Condvar() { delete this->condvar_; } void Condvar::wait() { this->condvar_->wait(this->lock_.get_impl()); } void Condvar::signal() { this->condvar_->signal(); } } // End namespace gold.