1 // gold-threads.h -- thread support for gold -*- C++ -*- 2 3 // Copyright 2006, 2007, 2008 Free Software Foundation, Inc. 4 // Written by Ian Lance Taylor <iant@google.com>. 5 6 // This file is part of gold. 7 8 // This program is free software; you can redistribute it and/or modify 9 // it under the terms of the GNU General Public License as published by 10 // the Free Software Foundation; either version 3 of the License, or 11 // (at your option) any later version. 12 13 // This program is distributed in the hope that it will be useful, 14 // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 // GNU General Public License for more details. 17 18 // You should have received a copy of the GNU General Public License 19 // along with this program; if not, write to the Free Software 20 // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21 // MA 02110-1301, USA. 22 23 // gold can be configured to support threads. If threads are 24 // supported, the user can specify at runtime whether or not to 25 // support them. This provides an interface to manage locking 26 // accordingly. 27 28 // Lock 29 // A simple lock class. 30 31 #ifndef GOLD_THREADS_H 32 #define GOLD_THREADS_H 33 34 namespace gold 35 { 36 37 class Condvar; 38 39 // The interface for the implementation of a Lock. 40 41 class Lock_impl 42 { 43 public: 44 Lock_impl() 45 { } 46 47 virtual 48 ~Lock_impl() 49 { } 50 51 virtual void 52 acquire() = 0; 53 54 virtual void 55 release() = 0; 56 }; 57 58 // A simple lock class. 59 60 class Lock 61 { 62 public: 63 Lock(); 64 65 ~Lock(); 66 67 // Acquire the lock. 68 void 69 acquire() 70 { this->lock_->acquire(); } 71 72 // Release the lock. 73 void 74 release() 75 { this->lock_->release(); } 76 77 private: 78 // This class can not be copied. 79 Lock(const Lock&); 80 Lock& operator=(const Lock&); 81 82 friend class Condvar; 83 Lock_impl* 84 get_impl() const 85 { return this->lock_; } 86 87 Lock_impl* lock_; 88 }; 89 90 // RAII for Lock. 91 92 class Hold_lock 93 { 94 public: 95 Hold_lock(Lock& lock) 96 : lock_(lock) 97 { this->lock_.acquire(); } 98 99 ~Hold_lock() 100 { this->lock_.release(); } 101 102 private: 103 // This class can not be copied. 104 Hold_lock(const Hold_lock&); 105 Hold_lock& operator=(const Hold_lock&); 106 107 Lock& lock_; 108 }; 109 110 class Hold_optional_lock 111 { 112 public: 113 Hold_optional_lock(Lock* lock) 114 : lock_(lock) 115 { 116 if (this->lock_ != NULL) 117 this->lock_->acquire(); 118 } 119 120 ~Hold_optional_lock() 121 { 122 if (this->lock_ != NULL) 123 this->lock_->release(); 124 } 125 126 private: 127 Hold_optional_lock(const Hold_optional_lock&); 128 Hold_optional_lock& operator=(const Hold_optional_lock&); 129 130 Lock* lock_; 131 }; 132 133 // The interface for the implementation of a condition variable. 134 135 class Condvar_impl 136 { 137 public: 138 Condvar_impl() 139 { } 140 141 virtual 142 ~Condvar_impl() 143 { } 144 145 virtual void 146 wait(Lock_impl*) = 0; 147 148 virtual void 149 signal() = 0; 150 151 virtual void 152 broadcast() = 0; 153 }; 154 155 // A simple condition variable class. It is always associated with a 156 // specific lock. 157 158 class Condvar 159 { 160 public: 161 Condvar(Lock& lock); 162 ~Condvar(); 163 164 // Wait for the condition variable to be signalled. This should 165 // only be called when the lock is held. 166 void 167 wait() 168 { this->condvar_->wait(this->lock_.get_impl()); } 169 170 // Signal the condition variable--wake up at least one thread 171 // waiting on the condition variable. This should only be called 172 // when the lock is held. 173 void 174 signal() 175 { this->condvar_->signal(); } 176 177 // Broadcast the condition variable--wake up all threads waiting on 178 // the condition variable. This should only be called when the lock 179 // is held. 180 void 181 broadcast() 182 { this->condvar_->broadcast(); } 183 184 private: 185 // This class can not be copied. 186 Condvar(const Condvar&); 187 Condvar& operator=(const Condvar&); 188 189 Lock& lock_; 190 Condvar_impl* condvar_; 191 }; 192 193 } // End namespace gold. 194 195 #endif // !defined(GOLD_THREADS_H) 196