// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef VM_THREAD_POOL_H_
#define VM_THREAD_POOL_H_

#include "vm/allocation.h"
#include "vm/globals.h"
#include "vm/os_thread.h"

namespace dart {

class ThreadPool {
 public:
  // Subclasses of Task are able to run on a ThreadPool.
  class Task {
   protected:
    Task();

   public:
    virtual ~Task();

    // Override this to provide task-specific behavior.
    virtual void Run() = 0;

   private:
    DISALLOW_COPY_AND_ASSIGN(Task);
  };

  ThreadPool();

  // Shuts down this thread pool. Causes workers to terminate
  // themselves when they are active again.
  ~ThreadPool();

  // Runs a task on the thread pool.
  bool Run(Task* task);

  // Some simple stats.
  uint64_t workers_running() const { return count_running_; }
  uint64_t workers_idle() const { return count_idle_; }
  uint64_t workers_started() const { return count_started_; }
  uint64_t workers_stopped() const { return count_stopped_; }

 private:
  class Worker {
   public:
    explicit Worker(ThreadPool* pool);

    // Sets a task on the worker.
    void SetTask(Task* task);

    // Starts the thread for the worker.  This should only be called
    // after a task has been set by the initial call to SetTask().
    void StartThread();

    // Main loop for a worker. Returns true if worker is removed from thread
    // lists, false otherwise.
    bool Loop();

    // Causes worker to terminate eventually.
    void Shutdown();

    // Get the Worker's thread id.
    ThreadId id();

   private:
    friend class ThreadPool;

    // The main entry point for new worker threads.
    static void Main(uword args);

    bool IsDone() const { return done_; }

    // Fields owned by Worker.
    Monitor monitor_;
    ThreadPool* pool_;
    Task* task_;
    ThreadId id_;
    bool done_;

    // Fields owned by ThreadPool.  Workers should not look at these
    // directly.  It's like looking at the sun.
    bool owned_;         // Protected by ThreadPool::mutex_
    Worker* all_next_;   // Protected by ThreadPool::mutex_
    Worker* idle_next_;  // Protected by ThreadPool::mutex_

    Worker* shutdown_next_;  // Protected by ThreadPool::exit_monitor

    DISALLOW_COPY_AND_ASSIGN(Worker);
  };

  class JoinList {
   public:
    explicit JoinList(ThreadJoinId id, JoinList* next) : id_(id), next_(next) {
    }

    // The thread pool's mutex_ must be held when calling this.
    static void AddLocked(ThreadJoinId id, JoinList** list);

    static void Join(JoinList** list);

    ThreadJoinId id() const { return id_; }
    JoinList* next() const { return next_; }

   private:
    ThreadJoinId id_;
    JoinList* next_;

    DISALLOW_COPY_AND_ASSIGN(JoinList);
  };

  void Shutdown();

  // Expensive.  Use only in assertions.
  bool IsIdle(Worker* worker);

  bool RemoveWorkerFromIdleList(Worker* worker);
  bool RemoveWorkerFromAllList(Worker* worker);

  void AddWorkerToShutdownList(Worker* worker);
  bool RemoveWorkerFromShutdownList(Worker* worker);

  void ReapExitedIdleThreads();

  // Worker operations.
  void SetIdleLocked(Worker* worker);  // Assumes mutex_ is held.
  void SetIdleAndReapExited(Worker* worker);
  bool ReleaseIdleWorker(Worker* worker);

  Mutex mutex_;
  bool shutting_down_;
  Worker* all_workers_;
  Worker* idle_workers_;
  uint64_t count_started_;
  uint64_t count_stopped_;
  uint64_t count_running_;
  uint64_t count_idle_;

  Monitor exit_monitor_;
  Worker* shutting_down_workers_;
  JoinList* join_list_;

  DISALLOW_COPY_AND_ASSIGN(ThreadPool);
};

}  // namespace dart

#endif  // VM_THREAD_POOL_H_
