// workqueue.h -- the work queue for gold   -*- C++ -*-

// Copyright (C) 2006-2016 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.

// 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.

// After processing the command line, everything the linker does is
// driven from a work queue.  This permits us to parallelize the
// linker where possible.

#ifndef GOLD_WORKQUEUE_H
#define GOLD_WORKQUEUE_H

#include <string>

#include "gold-threads.h"
#include "token.h"

namespace gold
{

class General_options;
class Workqueue;

// The superclass for tasks to be placed on the workqueue.  Each
// specific task class will inherit from this one.

class Task
{
 public:
  Task()
    : list_next_(NULL), name_(), should_run_soon_(false)
  { }
  virtual ~Task()
  { }

  // Check whether the Task can be run now.  This method is only
  // called with the workqueue lock held.  If the Task can run, this
  // returns NULL.  Otherwise it returns a pointer to a token which
  // must be released before the Task can run.
  virtual Task_token*
  is_runnable() = 0;

  // Lock all the resources required by the Task, and store the locks
  // in a Task_locker.  This method does not need to do anything if no
  // locks are required.  This method is only called with the
  // workqueue lock held.
  virtual void
  locks(Task_locker*) = 0;

  // Run the task.
  virtual void
  run(Workqueue*) = 0;

  // Return whether this task should run soon.
  bool
  should_run_soon() const
  { return this->should_run_soon_; }

  // Note that this task should run soon.
  void
  set_should_run_soon()
  { this->should_run_soon_ = true; }

  // Get the next Task on the list of Tasks.  Called by Task_list.
  Task*
  list_next() const
  { return this->list_next_; }

  // Set the next Task on the list of Tasks.  Called by Task_list.
  void
  set_list_next(Task* t)
  {
    gold_assert(this->list_next_ == NULL);
    this->list_next_ = t;
  }

  // Clear the next Task on the list of Tasks.  Called by Task_list.
  void
  clear_list_next()
  { this->list_next_ = NULL; }

  // Return the name of the Task.  This is only used for debugging
  // purposes.
  const std::string&
  name()
  {
    if (this->name_.empty())
      this->name_ = this->get_name();
    return this->name_;
  }

 protected:
  // Get the name of the task.  This must be implemented by the child
  // class.
  virtual std::string
  get_name() const = 0;

 private:
  // Tasks may not be copied.
  Task(const Task&);
  Task& operator=(const Task&);

  // If this Task is on a list, this is a pointer to the next Task on
  // the list.  We use this simple list structure rather than building
  // a container, in order to avoid memory allocation while holding
  // the Workqueue lock.
  Task* list_next_;
  // Task name, for debugging purposes.
  std::string name_;
  // Whether this Task should be executed soon.  This is used for
  // Tasks which can be run after some data is read.
  bool should_run_soon_;
};

// An interface for Task_function.  This is a convenience class to run
// a single function.

class Task_function_runner
{
 public:
  virtual ~Task_function_runner()
  { }

  virtual void
  run(Workqueue*, const Task*) = 0;
};

// A simple task which waits for a blocker and then runs a function.

class Task_function : public Task
{
 public:
  // RUNNER and BLOCKER should be allocated using new, and will be
  // deleted after the task runs.
  Task_function(Task_function_runner* runner, Task_token* blocker,
		const char* name)
    : runner_(runner), blocker_(blocker), name_(name)
  { gold_assert(blocker != NULL); }

  ~Task_function()
  {
    delete this->runner_;
    delete this->blocker_;
  }

  // The standard task methods.

  // Wait until the task is unblocked.
  Task_token*
  is_runnable()
  { return this->blocker_->is_blocked() ? this->blocker_ : NULL; }

  // This type of task does not normally hold any locks.
  virtual void
  locks(Task_locker*)
  { }

  // Run the action.
  void
  run(Workqueue* workqueue)
  { this->runner_->run(workqueue, this); }

  // The debugging name.
  std::string
  get_name() const
  { return this->name_; }

 private:
  Task_function(const Task_function&);
  Task_function& operator=(const Task_function&);

  Task_function_runner* runner_;
  Task_token* blocker_;
  const char* name_;
};

// The workqueue itself.

class Workqueue_threader;

class Workqueue
{
 public:
  Workqueue(const General_options&);
  ~Workqueue();

  // Add a new task to the work queue.
  void
  queue(Task*);

  // Add a new task to the work queue which should run soon.  If the
  // task is ready, it will be run before any tasks added using
  // queue().
  void
  queue_soon(Task*);

  // Add a new task to the work queue which should run next if it is
  // ready.
  void
  queue_next(Task*);

  // Process all the tasks on the work queue.  This function runs
  // until all tasks have completed.  The argument is the thread
  // number, used only for debugging.
  void
  process(int);

  // Set the desired thread count--the number of threads we want to
  // have running.
  void
  set_thread_count(int);

  // Add a new blocker to an existing Task_token. This must be done
  // with the workqueue lock held.  This should not be done routinely,
  // only in special circumstances.
  void
  add_blocker(Task_token*);

 private:
  // This class can not be copied.
  Workqueue(const Workqueue&);
  Workqueue& operator=(const Workqueue&);

  // Add a task to a queue.
  void
  add_to_queue(Task_list* queue, Task* t, bool front);

  // Find a runnable task, or wait for one.
  Task*
  find_runnable_or_wait(int thread_number);

  // Find a runnable task.
  Task*
  find_runnable();

  // Find a runnable task in a list.
  Task*
  find_runnable_in_list(Task_list*);

  // Find an run a task.
  bool
  find_and_run_task(int);

  // Release the locks for a Task.  Return the next Task to run.
  Task*
  release_locks(Task*, Task_locker*);

  // Store T into *PRET, or queue it as appropriate.
  bool
  return_or_queue(Task* t, bool is_blocker, Task** pret);

  // Return whether to cancel this thread.
  bool
  should_cancel_thread(int thread_number);

  // Master Workqueue lock.  This controls access to the following
  // member variables.
  Lock lock_;
  // List of tasks to execute soon.
  Task_list first_tasks_;
  // List of tasks to execute after the ones in first_tasks_.
  Task_list tasks_;
  // Number of tasks currently running.
  int running_;
  // Number of tasks waiting for a lock to release.
  int waiting_;
  // Condition variable associated with lock_.  This is signalled when
  // there may be a new Task to execute.
  Condvar condvar_;

  // The threading implementation.  This is set at construction time
  // and not changed thereafter.
  Workqueue_threader* threader_;
};

} // End namespace gold.

#endif // !defined(GOLD_WORKQUEUE_H)
