workqueue.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. // workqueue.h -- the work queue for gold -*- C++ -*-
  2. // Copyright (C) 2006-2022 Free Software Foundation, Inc.
  3. // Written by Ian Lance Taylor <iant@google.com>.
  4. // This file is part of gold.
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 3 of the License, or
  8. // (at your option) any later version.
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program; if not, write to the Free Software
  15. // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  16. // MA 02110-1301, USA.
  17. // After processing the command line, everything the linker does is
  18. // driven from a work queue. This permits us to parallelize the
  19. // linker where possible.
  20. #ifndef GOLD_WORKQUEUE_H
  21. #define GOLD_WORKQUEUE_H
  22. #include <string>
  23. #include "gold-threads.h"
  24. #include "token.h"
  25. namespace gold
  26. {
  27. class General_options;
  28. class Workqueue;
  29. // The superclass for tasks to be placed on the workqueue. Each
  30. // specific task class will inherit from this one.
  31. class Task
  32. {
  33. public:
  34. Task()
  35. : list_next_(NULL), name_(), should_run_soon_(false)
  36. { }
  37. virtual ~Task()
  38. { }
  39. // Check whether the Task can be run now. This method is only
  40. // called with the workqueue lock held. If the Task can run, this
  41. // returns NULL. Otherwise it returns a pointer to a token which
  42. // must be released before the Task can run.
  43. virtual Task_token*
  44. is_runnable() = 0;
  45. // Lock all the resources required by the Task, and store the locks
  46. // in a Task_locker. This method does not need to do anything if no
  47. // locks are required. This method is only called with the
  48. // workqueue lock held.
  49. virtual void
  50. locks(Task_locker*) = 0;
  51. // Run the task.
  52. virtual void
  53. run(Workqueue*) = 0;
  54. // Return whether this task should run soon.
  55. bool
  56. should_run_soon() const
  57. { return this->should_run_soon_; }
  58. // Note that this task should run soon.
  59. void
  60. set_should_run_soon()
  61. { this->should_run_soon_ = true; }
  62. // Get the next Task on the list of Tasks. Called by Task_list.
  63. Task*
  64. list_next() const
  65. { return this->list_next_; }
  66. // Set the next Task on the list of Tasks. Called by Task_list.
  67. void
  68. set_list_next(Task* t)
  69. {
  70. gold_assert(this->list_next_ == NULL);
  71. this->list_next_ = t;
  72. }
  73. // Clear the next Task on the list of Tasks. Called by Task_list.
  74. void
  75. clear_list_next()
  76. { this->list_next_ = NULL; }
  77. // Return the name of the Task. This is only used for debugging
  78. // purposes.
  79. const std::string&
  80. name()
  81. {
  82. if (this->name_.empty())
  83. this->name_ = this->get_name();
  84. return this->name_;
  85. }
  86. protected:
  87. // Get the name of the task. This must be implemented by the child
  88. // class.
  89. virtual std::string
  90. get_name() const = 0;
  91. private:
  92. // Tasks may not be copied.
  93. Task(const Task&);
  94. Task& operator=(const Task&);
  95. // If this Task is on a list, this is a pointer to the next Task on
  96. // the list. We use this simple list structure rather than building
  97. // a container, in order to avoid memory allocation while holding
  98. // the Workqueue lock.
  99. Task* list_next_;
  100. // Task name, for debugging purposes.
  101. std::string name_;
  102. // Whether this Task should be executed soon. This is used for
  103. // Tasks which can be run after some data is read.
  104. bool should_run_soon_;
  105. };
  106. // An interface for Task_function. This is a convenience class to run
  107. // a single function.
  108. class Task_function_runner
  109. {
  110. public:
  111. virtual ~Task_function_runner()
  112. { }
  113. virtual void
  114. run(Workqueue*, const Task*) = 0;
  115. };
  116. // A simple task which waits for a blocker and then runs a function.
  117. class Task_function : public Task
  118. {
  119. public:
  120. // RUNNER and BLOCKER should be allocated using new, and will be
  121. // deleted after the task runs.
  122. Task_function(Task_function_runner* runner, Task_token* blocker,
  123. const char* name)
  124. : runner_(runner), blocker_(blocker), name_(name)
  125. { gold_assert(blocker != NULL); }
  126. ~Task_function()
  127. {
  128. delete this->runner_;
  129. delete this->blocker_;
  130. }
  131. // The standard task methods.
  132. // Wait until the task is unblocked.
  133. Task_token*
  134. is_runnable()
  135. { return this->blocker_->is_blocked() ? this->blocker_ : NULL; }
  136. // This type of task does not normally hold any locks.
  137. virtual void
  138. locks(Task_locker*)
  139. { }
  140. // Run the action.
  141. void
  142. run(Workqueue* workqueue)
  143. { this->runner_->run(workqueue, this); }
  144. // The debugging name.
  145. std::string
  146. get_name() const
  147. { return this->name_; }
  148. private:
  149. Task_function(const Task_function&);
  150. Task_function& operator=(const Task_function&);
  151. Task_function_runner* runner_;
  152. Task_token* blocker_;
  153. const char* name_;
  154. };
  155. // The workqueue itself.
  156. class Workqueue_threader;
  157. class Workqueue
  158. {
  159. public:
  160. Workqueue(const General_options&);
  161. ~Workqueue();
  162. // Add a new task to the work queue.
  163. void
  164. queue(Task*);
  165. // Add a new task to the work queue which should run soon. If the
  166. // task is ready, it will be run before any tasks added using
  167. // queue().
  168. void
  169. queue_soon(Task*);
  170. // Add a new task to the work queue which should run next if it is
  171. // ready.
  172. void
  173. queue_next(Task*);
  174. // Process all the tasks on the work queue. This function runs
  175. // until all tasks have completed. The argument is the thread
  176. // number, used only for debugging.
  177. void
  178. process(int);
  179. // Set the desired thread count--the number of threads we want to
  180. // have running.
  181. void
  182. set_thread_count(int);
  183. // Add a new blocker to an existing Task_token. This must be done
  184. // with the workqueue lock held. This should not be done routinely,
  185. // only in special circumstances.
  186. void
  187. add_blocker(Task_token*);
  188. private:
  189. // This class can not be copied.
  190. Workqueue(const Workqueue&);
  191. Workqueue& operator=(const Workqueue&);
  192. // Add a task to a queue.
  193. void
  194. add_to_queue(Task_list* queue, Task* t, bool front);
  195. // Find a runnable task, or wait for one.
  196. Task*
  197. find_runnable_or_wait(int thread_number);
  198. // Find a runnable task.
  199. Task*
  200. find_runnable();
  201. // Find a runnable task in a list.
  202. Task*
  203. find_runnable_in_list(Task_list*);
  204. // Find an run a task.
  205. bool
  206. find_and_run_task(int);
  207. // Release the locks for a Task. Return the next Task to run.
  208. Task*
  209. release_locks(Task*, Task_locker*);
  210. // Store T into *PRET, or queue it as appropriate.
  211. bool
  212. return_or_queue(Task* t, bool is_blocker, Task** pret);
  213. // Return whether to cancel this thread.
  214. bool
  215. should_cancel_thread(int thread_number);
  216. // Master Workqueue lock. This controls access to the following
  217. // member variables.
  218. Lock lock_;
  219. // List of tasks to execute soon.
  220. Task_list first_tasks_;
  221. // List of tasks to execute after the ones in first_tasks_.
  222. Task_list tasks_;
  223. // Number of tasks currently running.
  224. int running_;
  225. // Number of tasks waiting for a lock to release.
  226. int waiting_;
  227. // Condition variable associated with lock_. This is signalled when
  228. // there may be a new Task to execute.
  229. Condvar condvar_;
  230. // The threading implementation. This is set at construction time
  231. // and not changed thereafter.
  232. Workqueue_threader* threader_;
  233. };
  234. } // End namespace gold.
  235. #endif // !defined(GOLD_WORKQUEUE_H)