1// workqueue.h -- the work queue for gold   -*- C++ -*-
2
3// Copyright (C) 2006-2017 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// After processing the command line, everything the linker does is
24// driven from a work queue.  This permits us to parallelize the
25// linker where possible.
26
27#ifndef GOLD_WORKQUEUE_H
28#define GOLD_WORKQUEUE_H
29
30#include <string>
31
32#include "gold-threads.h"
33#include "token.h"
34
35namespace gold
36{
37
38class General_options;
39class Workqueue;
40
41// The superclass for tasks to be placed on the workqueue.  Each
42// specific task class will inherit from this one.
43
44class Task
45{
46 public:
47  Task()
48    : list_next_(NULL), name_(), should_run_soon_(false)
49  { }
50  virtual ~Task()
51  { }
52
53  // Check whether the Task can be run now.  This method is only
54  // called with the workqueue lock held.  If the Task can run, this
55  // returns NULL.  Otherwise it returns a pointer to a token which
56  // must be released before the Task can run.
57  virtual Task_token*
58  is_runnable() = 0;
59
60  // Lock all the resources required by the Task, and store the locks
61  // in a Task_locker.  This method does not need to do anything if no
62  // locks are required.  This method is only called with the
63  // workqueue lock held.
64  virtual void
65  locks(Task_locker*) = 0;
66
67  // Run the task.
68  virtual void
69  run(Workqueue*) = 0;
70
71  // Return whether this task should run soon.
72  bool
73  should_run_soon() const
74  { return this->should_run_soon_; }
75
76  // Note that this task should run soon.
77  void
78  set_should_run_soon()
79  { this->should_run_soon_ = true; }
80
81  // Get the next Task on the list of Tasks.  Called by Task_list.
82  Task*
83  list_next() const
84  { return this->list_next_; }
85
86  // Set the next Task on the list of Tasks.  Called by Task_list.
87  void
88  set_list_next(Task* t)
89  {
90    gold_assert(this->list_next_ == NULL);
91    this->list_next_ = t;
92  }
93
94  // Clear the next Task on the list of Tasks.  Called by Task_list.
95  void
96  clear_list_next()
97  { this->list_next_ = NULL; }
98
99  // Return the name of the Task.  This is only used for debugging
100  // purposes.
101  const std::string&
102  name()
103  {
104    if (this->name_.empty())
105      this->name_ = this->get_name();
106    return this->name_;
107  }
108
109 protected:
110  // Get the name of the task.  This must be implemented by the child
111  // class.
112  virtual std::string
113  get_name() const = 0;
114
115 private:
116  // Tasks may not be copied.
117  Task(const Task&);
118  Task& operator=(const Task&);
119
120  // If this Task is on a list, this is a pointer to the next Task on
121  // the list.  We use this simple list structure rather than building
122  // a container, in order to avoid memory allocation while holding
123  // the Workqueue lock.
124  Task* list_next_;
125  // Task name, for debugging purposes.
126  std::string name_;
127  // Whether this Task should be executed soon.  This is used for
128  // Tasks which can be run after some data is read.
129  bool should_run_soon_;
130};
131
132// An interface for Task_function.  This is a convenience class to run
133// a single function.
134
135class Task_function_runner
136{
137 public:
138  virtual ~Task_function_runner()
139  { }
140
141  virtual void
142  run(Workqueue*, const Task*) = 0;
143};
144
145// A simple task which waits for a blocker and then runs a function.
146
147class Task_function : public Task
148{
149 public:
150  // RUNNER and BLOCKER should be allocated using new, and will be
151  // deleted after the task runs.
152  Task_function(Task_function_runner* runner, Task_token* blocker,
153		const char* name)
154    : runner_(runner), blocker_(blocker), name_(name)
155  { gold_assert(blocker != NULL); }
156
157  ~Task_function()
158  {
159    delete this->runner_;
160    delete this->blocker_;
161  }
162
163  // The standard task methods.
164
165  // Wait until the task is unblocked.
166  Task_token*
167  is_runnable()
168  { return this->blocker_->is_blocked() ? this->blocker_ : NULL; }
169
170  // This type of task does not normally hold any locks.
171  virtual void
172  locks(Task_locker*)
173  { }
174
175  // Run the action.
176  void
177  run(Workqueue* workqueue)
178  { this->runner_->run(workqueue, this); }
179
180  // The debugging name.
181  std::string
182  get_name() const
183  { return this->name_; }
184
185 private:
186  Task_function(const Task_function&);
187  Task_function& operator=(const Task_function&);
188
189  Task_function_runner* runner_;
190  Task_token* blocker_;
191  const char* name_;
192};
193
194// The workqueue itself.
195
196class Workqueue_threader;
197
198class Workqueue
199{
200 public:
201  Workqueue(const General_options&);
202  ~Workqueue();
203
204  // Add a new task to the work queue.
205  void
206  queue(Task*);
207
208  // Add a new task to the work queue which should run soon.  If the
209  // task is ready, it will be run before any tasks added using
210  // queue().
211  void
212  queue_soon(Task*);
213
214  // Add a new task to the work queue which should run next if it is
215  // ready.
216  void
217  queue_next(Task*);
218
219  // Process all the tasks on the work queue.  This function runs
220  // until all tasks have completed.  The argument is the thread
221  // number, used only for debugging.
222  void
223  process(int);
224
225  // Set the desired thread count--the number of threads we want to
226  // have running.
227  void
228  set_thread_count(int);
229
230  // Add a new blocker to an existing Task_token. This must be done
231  // with the workqueue lock held.  This should not be done routinely,
232  // only in special circumstances.
233  void
234  add_blocker(Task_token*);
235
236 private:
237  // This class can not be copied.
238  Workqueue(const Workqueue&);
239  Workqueue& operator=(const Workqueue&);
240
241  // Add a task to a queue.
242  void
243  add_to_queue(Task_list* queue, Task* t, bool front);
244
245  // Find a runnable task, or wait for one.
246  Task*
247  find_runnable_or_wait(int thread_number);
248
249  // Find a runnable task.
250  Task*
251  find_runnable();
252
253  // Find a runnable task in a list.
254  Task*
255  find_runnable_in_list(Task_list*);
256
257  // Find an run a task.
258  bool
259  find_and_run_task(int);
260
261  // Release the locks for a Task.  Return the next Task to run.
262  Task*
263  release_locks(Task*, Task_locker*);
264
265  // Store T into *PRET, or queue it as appropriate.
266  bool
267  return_or_queue(Task* t, bool is_blocker, Task** pret);
268
269  // Return whether to cancel this thread.
270  bool
271  should_cancel_thread(int thread_number);
272
273  // Master Workqueue lock.  This controls access to the following
274  // member variables.
275  Lock lock_;
276  // List of tasks to execute soon.
277  Task_list first_tasks_;
278  // List of tasks to execute after the ones in first_tasks_.
279  Task_list tasks_;
280  // Number of tasks currently running.
281  int running_;
282  // Number of tasks waiting for a lock to release.
283  int waiting_;
284  // Condition variable associated with lock_.  This is signalled when
285  // there may be a new Task to execute.
286  Condvar condvar_;
287
288  // The threading implementation.  This is set at construction time
289  // and not changed thereafter.
290  Workqueue_threader* threader_;
291};
292
293} // End namespace gold.
294
295#endif // !defined(GOLD_WORKQUEUE_H)
296