diff options
Diffstat (limited to 'gold/gold-threads.cc')
-rw-r--r-- | gold/gold-threads.cc | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/gold/gold-threads.cc b/gold/gold-threads.cc new file mode 100644 index 0000000..c6e1170 --- /dev/null +++ b/gold/gold-threads.cc @@ -0,0 +1,230 @@ +// gold-threads.cc -- thread support for gold + +#include <cassert> + +#include "gold.h" + +#ifdef ENABLE_THREADS +#include <pthread.h> +#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() +{ + assert(!this->acquired_); +} + +void +Lock_impl::acquire() +{ + assert(!this->acquired_); + this->acquired_ = true; +} + +void +Lock_impl::release() +{ + 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) +{ + 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. |