* elfxx-mips.c (mips_elf_merge_gots): Always use maxcnt.
[binutils.git] / gold / workqueue.cc
blob3ef342257377f551c061cbf40cf8943b818e6a19
1 // workqueue.cc -- the workqueue for gold
3 #include "gold.h"
5 #include <cassert>
7 #include "workqueue.h"
9 namespace gold
12 // Task_token methods.
14 Task_token::Task_token()
15 : is_blocker_(false), readers_(0), writer_(NULL)
19 Task_token::~Task_token()
21 assert(this->readers_ == 0 && this->writer_ == NULL);
24 bool
25 Task_token::is_readable() const
27 assert(!this->is_blocker_);
28 return this->writer_ == NULL;
31 void
32 Task_token::add_reader()
34 assert(!this->is_blocker_);
35 assert(this->is_readable());
36 ++this->readers_;
39 void
40 Task_token::remove_reader()
42 assert(!this->is_blocker_);
43 assert(this->readers_ > 0);
44 --this->readers_;
47 bool
48 Task_token::is_writable() const
50 assert(!this->is_blocker_);
51 return this->writer_ == NULL && this->readers_ == 0;
54 void
55 Task_token::add_writer(const Task* t)
57 assert(!this->is_blocker_);
58 assert(this->is_writable());
59 this->writer_ = t;
62 void
63 Task_token::remove_writer(const Task* t)
65 assert(!this->is_blocker_);
66 assert(this->writer_ == t);
67 this->writer_ = NULL;
70 bool
71 Task_token::has_write_lock(const Task* t)
73 assert(!this->is_blocker_);
74 return this->writer_ == t;
77 // For blockers, we just use the readers_ field.
79 void
80 Task_token::add_blocker()
82 if (this->readers_ == 0 && this->writer_ == NULL)
83 this->is_blocker_ = true;
84 else
85 assert(this->is_blocker_);
86 ++this->readers_;
89 bool
90 Task_token::remove_blocker()
92 assert(this->is_blocker_ && this->readers_ > 0);
93 --this->readers_;
94 return this->readers_ == 0;
97 bool
98 Task_token::is_blocked() const
100 assert(this->is_blocker_ || (this->readers_ == 0 && this->writer_ == NULL));
101 return this->readers_ > 0;
104 // The Task_block_token class.
106 Task_block_token::Task_block_token(Task_token& token, Workqueue* workqueue)
107 : token_(token), workqueue_(workqueue)
109 // We must increment the block count when the task is created and
110 // put on the queue. This object is created when the task is run,
111 // so we don't increment the block count here.
112 assert(this->token_.is_blocked());
115 Task_block_token::~Task_block_token()
117 if (this->token_.remove_blocker())
119 // Tell the workqueue that a blocker was cleared. This is
120 // always called in the main thread, so no locking is required.
121 this->workqueue_->cleared_blocker();
125 // The Workqueue_runner abstract class.
127 class Workqueue_runner
129 public:
130 Workqueue_runner(Workqueue* workqueue)
131 : workqueue_(workqueue)
133 virtual ~Workqueue_runner()
136 // Run a task. This is always called in the main thread.
137 virtual void run(Task*, Task_locker*) = 0;
139 protected:
140 // This is called by an implementation when a task is completed.
141 void completed(Task* t, Task_locker* tl)
142 { this->workqueue_->completed(t, tl); }
144 Workqueue* get_workqueue() const
145 { return this->workqueue_; }
147 private:
148 Workqueue* workqueue_;
151 // The simple single-threaded implementation of Workqueue_runner.
153 class Workqueue_runner_single : public Workqueue_runner
155 public:
156 Workqueue_runner_single(Workqueue* workqueue)
157 : Workqueue_runner(workqueue)
159 ~Workqueue_runner_single()
162 void run(Task*, Task_locker*);
165 void
166 Workqueue_runner_single::run(Task* t, Task_locker* tl)
168 t->run(this->get_workqueue());
169 this->completed(t, tl);
172 // Workqueue methods.
174 Workqueue::Workqueue(const General_options&)
175 : tasks_lock_(),
176 tasks_(),
177 completed_lock_(),
178 completed_(),
179 running_(0),
180 completed_condvar_(this->completed_lock_),
181 cleared_blockers_(0)
183 // At some point we will select the specific implementation of
184 // Workqueue_runner to use based on the command line options.
185 this->runner_ = new Workqueue_runner_single(this);
188 Workqueue::~Workqueue()
190 assert(this->tasks_.empty());
191 assert(this->completed_.empty());
192 assert(this->running_ == 0);
195 // Add a task to the queue.
197 void
198 Workqueue::queue(Task* t)
200 Hold_lock hl(this->tasks_lock_);
201 this->tasks_.push_back(t);
204 // Add a task to the front of the queue.
206 void
207 Workqueue::queue_front(Task* t)
209 Hold_lock hl(this->tasks_lock_);
210 this->tasks_.push_front(t);
213 // Clear the list of completed tasks. Return whether we cleared
214 // anything. The completed_lock_ must be held when this is called.
216 bool
217 Workqueue::clear_completed()
219 if (this->completed_.empty())
220 return false;
223 delete this->completed_.front();
224 this->completed_.pop_front();
226 while (!this->completed_.empty());
227 return true;
230 // Find a runnable task in TASKS, which is non-empty. Return NULL if
231 // none could be found. The tasks_lock_ must be held when this is
232 // called. Sets ALL_BLOCKED if all non-runnable tasks are waiting on
233 // a blocker.
235 Task*
236 Workqueue::find_runnable(Task_list& tasks, bool* all_blocked)
238 Task* tlast = tasks.back();
239 *all_blocked = true;
240 while (true)
242 Task* t = tasks.front();
243 tasks.pop_front();
245 Task::Is_runnable_type is_runnable = t->is_runnable(this);
246 if (is_runnable == Task::IS_RUNNABLE)
247 return t;
249 if (is_runnable != Task::IS_BLOCKED)
250 *all_blocked = false;
252 tasks.push_back(t);
254 if (t == tlast)
256 // We couldn't find any runnable task. If there are any
257 // completed tasks, free their locks and try again.
260 Hold_lock hl2(this->completed_lock_);
262 if (!this->clear_completed())
264 // There had better be some tasks running, or we will
265 // never find a runnable task.
266 assert(this->running_ > 0);
268 // We couldn't find any runnable tasks, and we
269 // couldn't release any locks.
270 return NULL;
274 // We're going around again, so recompute ALL_BLOCKED.
275 *all_blocked = true;
280 // Process all the tasks on the workqueue. This is the main loop in
281 // the linker. Note that as we process tasks, new tasks will be
282 // added.
284 void
285 Workqueue::process()
287 while (true)
289 Task* t;
290 bool empty;
291 bool all_blocked;
294 Hold_lock hl(this->tasks_lock_);
296 if (this->tasks_.empty())
298 t = NULL;
299 empty = true;
300 all_blocked = false;
302 else
304 t = this->find_runnable(this->tasks_, &all_blocked);
305 empty = false;
309 // If T != NULL, it is a task we can run.
310 // If T == NULL && empty, then there are no tasks waiting to
311 // be run at this level.
312 // If T == NULL && !empty, then there tasks waiting to be
313 // run at this level, but they are waiting for something to
314 // unlock.
316 if (t != NULL)
317 this->run(t);
318 else if (!empty)
321 Hold_lock hl(this->completed_lock_);
323 // There must be something for us to wait for, or we won't
324 // be able to make progress.
325 assert(this->running_ > 0 || !this->completed_.empty());
327 if (all_blocked)
329 this->cleared_blockers_ = 0;
330 this->clear_completed();
331 while (this->cleared_blockers_ == 0)
333 assert(this->running_ > 0);
334 this->completed_condvar_.wait();
335 this->clear_completed();
338 else
340 if (this->running_ > 0)
342 // Wait for a task to finish.
343 this->completed_condvar_.wait();
345 this->clear_completed();
349 else
352 Hold_lock hl(this->completed_lock_);
354 // If there are no running tasks, then we are done.
355 if (this->running_ == 0)
357 this->clear_completed();
358 return;
361 // Wait for a task to finish. Then we have to loop around
362 // again in case it added any new tasks before finishing.
363 this->completed_condvar_.wait();
364 this->clear_completed();
370 // Run a task. This is always called in the main thread.
372 void
373 Workqueue::run(Task* t)
375 ++this->running_;
376 this->runner_->run(t, t->locks(this));
379 // This is called when a task is completed to put the locks on the
380 // list to be released. We use a list because we only want the locks
381 // to be released in the main thread.
383 void
384 Workqueue::completed(Task* t, Task_locker* tl)
387 Hold_lock hl(this->completed_lock_);
388 assert(this->running_ > 0);
389 --this->running_;
390 this->completed_.push_back(tl);
391 this->completed_condvar_.signal();
393 delete t;
396 // This is called when the last task for a blocker has completed.
397 // This is always called in the main thread.
399 void
400 Workqueue::cleared_blocker()
402 ++this->cleared_blockers_;
405 } // End namespace gold.