From c79126688f8211ab17a893c5e80b09811d424fc1 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 22 Nov 2007 00:05:51 +0000 Subject: Add threading support. --- gold/workqueue-internal.h | 129 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 gold/workqueue-internal.h (limited to 'gold/workqueue-internal.h') diff --git a/gold/workqueue-internal.h b/gold/workqueue-internal.h new file mode 100644 index 0000000..d9fd160 --- /dev/null +++ b/gold/workqueue-internal.h @@ -0,0 +1,129 @@ +// workqueue-internal.h -- internal work queue header for gold -*- C++ -*- + +// Copyright 2006, 2007 Free Software Foundation, Inc. +// Written by Ian Lance Taylor . + +// This file is part of gold. + +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +// MA 02110-1301, USA. + +#ifndef GOLD_WORKQUEUE_INTERNAL_H +#define GOLD_WORKQUEUE_INTERNAL_H + +#include + +#include "gold-threads.h" +#include "workqueue.h" + +// This is an internal header file for different gold workqueue +// implementations. + +namespace gold +{ + +class Workqueue_thread; + +// The Workqueue_runner abstract class. This is the interface used by +// the general workqueue code to actually run a task. + +class Workqueue_runner +{ + public: + Workqueue_runner(Workqueue* workqueue) + : workqueue_(workqueue) + { } + virtual ~Workqueue_runner() + { } + + // Run a task. This is always called in the main thread. + virtual void + run(Task*, Task_locker*) = 0; + + // Set the number of threads to use. This is ignored when not using + // threads. + virtual void + set_thread_count(int) = 0; + + protected: + // This is called by an implementation when a task is completed. + void completed(Task* t, Task_locker* tl) + { this->workqueue_->completed(t, tl); } + + Workqueue* get_workqueue() const + { return this->workqueue_; } + + private: + Workqueue* workqueue_; +}; + +// The threaded instantiation of Workqueue_runner. + +class Workqueue_runner_threadpool : public Workqueue_runner +{ + public: + Workqueue_runner_threadpool(Workqueue* workqueue); + + ~Workqueue_runner_threadpool(); + + void + run(Task*, Task_locker*); + + void + set_thread_count(int); + + private: + // This class can not be copied. + Workqueue_runner_threadpool(const Workqueue_runner_threadpool&); + Workqueue_runner_threadpool& operator=(const Workqueue_runner_threadpool&); + + // Return the next Task and Task_locker to run. This returns false + // if the calling thread should simply exit. + bool + get_next(Task**, Task_locker**); + + // This is called when the thread completes a task. + void + thread_completed(Task*, Task_locker*); + + // The Workqueue_thread class calls functions from this and from the + // parent Workqueue_runner. + friend class Workqueue_thread; + + // An entry on the queue of tasks to run. + typedef std::pair Task_queue_entry; + + // A queue of tasks to run. + typedef std::queue Task_queue; + + // The number of threads we want to create. This is only changed in + // the main thread or when only one thread is running. This is set + // to zero when all threads should exit. + int desired_thread_count_; + // A lock controlling access to the remaining fields. + Lock lock_; + // The number of threads we have created. + int actual_thread_count_; + // The number of threads which are running a task. + int running_thread_count_; + // A queue of tasks to run. + Task_queue task_queue_; + // A condition variable which signals when the task_queue_ changed. + Condvar task_queue_condvar_; +}; + +} // End namespace gold. + +#endif // !defined(GOLD_WORKQUEUE_INTERNAL_H) -- cgit v1.1