gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gold / gold-threads.h
CommitLineData
bae7f79e
ILT
1// gold-threads.h -- thread support for gold -*- C++ -*-
2
b3adc24a 3// Copyright (C) 2006-2020 Free Software Foundation, Inc.
6cb15b7f
ILT
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
bae7f79e
ILT
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
34namespace gold
35{
36
bae7f79e 37class Condvar;
114dfbe1 38class Once_initialize;
7f055c20 39class Initialize_lock_once;
bae7f79e 40
c7912668
ILT
41// The interface for the implementation of a Lock.
42
43class Lock_impl
44{
45 public:
46 Lock_impl()
47 { }
48
49 virtual
50 ~Lock_impl()
51 { }
52
53 virtual void
54 acquire() = 0;
55
56 virtual void
57 release() = 0;
58};
59
bae7f79e
ILT
60// A simple lock class.
61
62class Lock
63{
64 public:
65 Lock();
c7912668 66
bae7f79e
ILT
67 ~Lock();
68
69 // Acquire the lock.
70 void
c7912668
ILT
71 acquire()
72 { this->lock_->acquire(); }
bae7f79e
ILT
73
74 // Release the lock.
75 void
c7912668
ILT
76 release()
77 { this->lock_->release(); }
bae7f79e
ILT
78
79 private:
80 // This class can not be copied.
81 Lock(const Lock&);
82 Lock& operator=(const Lock&);
83
84 friend class Condvar;
85 Lock_impl*
86 get_impl() const
87 { return this->lock_; }
88
89 Lock_impl* lock_;
90};
91
92// RAII for Lock.
93
94class Hold_lock
95{
96 public:
97 Hold_lock(Lock& lock)
98 : lock_(lock)
99 { this->lock_.acquire(); }
100
101 ~Hold_lock()
102 { this->lock_.release(); }
103
104 private:
105 // This class can not be copied.
106 Hold_lock(const Hold_lock&);
107 Hold_lock& operator=(const Hold_lock&);
108
109 Lock& lock_;
110};
111
2a00e4fb
ILT
112class Hold_optional_lock
113{
114 public:
115 Hold_optional_lock(Lock* lock)
116 : lock_(lock)
117 {
118 if (this->lock_ != NULL)
119 this->lock_->acquire();
120 }
121
122 ~Hold_optional_lock()
123 {
124 if (this->lock_ != NULL)
125 this->lock_->release();
126 }
127
128 private:
129 Hold_optional_lock(const Hold_optional_lock&);
130 Hold_optional_lock& operator=(const Hold_optional_lock&);
131
132 Lock* lock_;
133};
134
c7912668
ILT
135// The interface for the implementation of a condition variable.
136
137class Condvar_impl
138{
139 public:
140 Condvar_impl()
141 { }
142
143 virtual
144 ~Condvar_impl()
145 { }
146
147 virtual void
148 wait(Lock_impl*) = 0;
149
150 virtual void
151 signal() = 0;
152
153 virtual void
154 broadcast() = 0;
155};
bae7f79e
ILT
156
157// A simple condition variable class. It is always associated with a
158// specific lock.
159
160class Condvar
161{
162 public:
163 Condvar(Lock& lock);
164 ~Condvar();
165
166 // Wait for the condition variable to be signalled. This should
167 // only be called when the lock is held.
168 void
c7912668
ILT
169 wait()
170 { this->condvar_->wait(this->lock_.get_impl()); }
171
172 // Signal the condition variable--wake up at least one thread
173 // waiting on the condition variable. This should only be called
174 // when the lock is held.
175 void
176 signal()
177 { this->condvar_->signal(); }
bae7f79e 178
c7912668
ILT
179 // Broadcast the condition variable--wake up all threads waiting on
180 // the condition variable. This should only be called when the lock
181 // is held.
bae7f79e 182 void
c7912668
ILT
183 broadcast()
184 { this->condvar_->broadcast(); }
bae7f79e
ILT
185
186 private:
187 // This class can not be copied.
188 Condvar(const Condvar&);
189 Condvar& operator=(const Condvar&);
190
191 Lock& lock_;
192 Condvar_impl* condvar_;
193};
194
114dfbe1
ILT
195// A class used to do something once. This is an abstract parent
196// class; any actual use will involve a child of this.
197
198class Once
199{
200 public:
201 Once();
202
bb0bfe4f
DK
203 virtual
204 ~Once()
205 { }
206
114dfbe1
ILT
207 // Call this function to do whatever it is. We pass an argument
208 // even though you have to use a child class because in some uses
209 // setting the argument would itself require a Once class.
210 void
211 run_once(void* arg);
212
213 // This is an internal function, which must be public because it is
214 // run by an extern "C" function called via pthread_once.
215 void
216 internal_run(void* arg);
217
218 protected:
219 // This must be implemented by the child class.
220 virtual void
221 do_run_once(void* arg) = 0;
222
223 private:
224 // True if we have already run the function.
225 bool was_run_;
39d9ead7 226#if defined(ENABLE_THREADS) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
114dfbe1
ILT
227 // Internal compare-and-swap lock on was_run_;
228 uint32_t was_run_lock_;
39d9ead7 229#endif
114dfbe1
ILT
230 // The lock to run the function only once.
231 Once_initialize* once_;
232};
233
7f055c20
ILT
234// A class used to initialize a lock exactly once, after the options
235// have been read. This is needed because the implementation of locks
236// depends on whether we've seen the --threads option. Before the
237// options have been read, we know we are single-threaded, so we can
238// get by without using a lock. This class should be an instance
239// variable of the class which has a lock which needs to be
240// initialized.
241
114dfbe1 242class Initialize_lock : public Once
7f055c20
ILT
243{
244 public:
245 // The class which uses this will have a pointer to a lock. This
246 // must be constructed with a pointer to that pointer.
114dfbe1
ILT
247 Initialize_lock(Lock** pplock)
248 : pplock_(pplock)
249 { }
7f055c20
ILT
250
251 // Initialize the lock. Return true if the lock is now initialized,
252 // false if it is not (because the options have not yet been read).
253 bool
254 initialize();
255
114dfbe1
ILT
256 protected:
257 void
258 do_run_once(void*);
259
7f055c20
ILT
260 private:
261 // A pointer to the lock pointer which must be initialized.
262 Lock** const pplock_;
7f055c20
ILT
263};
264
bae7f79e
ILT
265} // End namespace gold.
266
267#endif // !defined(GOLD_THREADS_H)
This page took 0.549114 seconds and 4 git commands to generate.