X-Git-Url: https://oss.titaniummirror.com/gitweb?p=msp430-binutils.git;a=blobdiff_plain;f=gold%2Fgold-threads.h;fp=gold%2Fgold-threads.h;h=9c49b57d071697927f1a40618ccc1bf86fe3a628;hp=0000000000000000000000000000000000000000;hb=88750007d7869f178f0ba528f41efd3b74c424cf;hpb=6df9443a374e2b81278c61b8afc0a1eef7db280b diff --git a/gold/gold-threads.h b/gold/gold-threads.h new file mode 100644 index 0000000..9c49b57 --- /dev/null +++ b/gold/gold-threads.h @@ -0,0 +1,223 @@ +// gold-threads.h -- thread support for gold -*- C++ -*- + +// Copyright 2006, 2007, 2008 Free Software Foundation, Inc. +// Written by Ian Lance Taylor . + +// This file is part of gold. + +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +// MA 02110-1301, USA. + +// gold can be configured to support threads. If threads are +// supported, the user can specify at runtime whether or not to +// support them. This provides an interface to manage locking +// accordingly. + +// Lock +// A simple lock class. + +#ifndef GOLD_THREADS_H +#define GOLD_THREADS_H + +namespace gold +{ + +class Condvar; +class Initialize_lock_once; + +// The interface for the implementation of a Lock. + +class Lock_impl +{ + public: + Lock_impl() + { } + + virtual + ~Lock_impl() + { } + + virtual void + acquire() = 0; + + virtual void + release() = 0; +}; + +// A simple lock class. + +class Lock +{ + public: + Lock(); + + ~Lock(); + + // Acquire the lock. + void + acquire() + { this->lock_->acquire(); } + + // Release the lock. + void + release() + { this->lock_->release(); } + + private: + // This class can not be copied. + Lock(const Lock&); + Lock& operator=(const Lock&); + + friend class Condvar; + Lock_impl* + get_impl() const + { return this->lock_; } + + Lock_impl* lock_; +}; + +// RAII for Lock. + +class Hold_lock +{ + public: + Hold_lock(Lock& lock) + : lock_(lock) + { this->lock_.acquire(); } + + ~Hold_lock() + { this->lock_.release(); } + + private: + // This class can not be copied. + Hold_lock(const Hold_lock&); + Hold_lock& operator=(const Hold_lock&); + + Lock& lock_; +}; + +class Hold_optional_lock +{ + public: + Hold_optional_lock(Lock* lock) + : lock_(lock) + { + if (this->lock_ != NULL) + this->lock_->acquire(); + } + + ~Hold_optional_lock() + { + if (this->lock_ != NULL) + this->lock_->release(); + } + + private: + Hold_optional_lock(const Hold_optional_lock&); + Hold_optional_lock& operator=(const Hold_optional_lock&); + + Lock* lock_; +}; + +// The interface for the implementation of a condition variable. + +class Condvar_impl +{ + public: + Condvar_impl() + { } + + virtual + ~Condvar_impl() + { } + + virtual void + wait(Lock_impl*) = 0; + + virtual void + signal() = 0; + + virtual void + broadcast() = 0; +}; + +// A simple condition variable class. It is always associated with a +// specific lock. + +class Condvar +{ + public: + Condvar(Lock& lock); + ~Condvar(); + + // Wait for the condition variable to be signalled. This should + // only be called when the lock is held. + void + wait() + { this->condvar_->wait(this->lock_.get_impl()); } + + // Signal the condition variable--wake up at least one thread + // waiting on the condition variable. This should only be called + // when the lock is held. + void + signal() + { this->condvar_->signal(); } + + // Broadcast the condition variable--wake up all threads waiting on + // the condition variable. This should only be called when the lock + // is held. + void + broadcast() + { this->condvar_->broadcast(); } + + private: + // This class can not be copied. + Condvar(const Condvar&); + Condvar& operator=(const Condvar&); + + Lock& lock_; + Condvar_impl* condvar_; +}; + +// A class used to initialize a lock exactly once, after the options +// have been read. This is needed because the implementation of locks +// depends on whether we've seen the --threads option. Before the +// options have been read, we know we are single-threaded, so we can +// get by without using a lock. This class should be an instance +// variable of the class which has a lock which needs to be +// initialized. + +class Initialize_lock +{ + public: + // The class which uses this will have a pointer to a lock. This + // must be constructed with a pointer to that pointer. + Initialize_lock(Lock** pplock); + + // Initialize the lock. Return true if the lock is now initialized, + // false if it is not (because the options have not yet been read). + bool + initialize(); + + private: + // A pointer to the lock pointer which must be initialized. + Lock** const pplock_; + // If needed, a pointer to a pthread_once_t structure. + Initialize_lock_once* once_; +}; + +} // End namespace gold. + +#endif // !defined(GOLD_THREADS_H)