// gold-threads.h -- thread support for gold  -*- C++ -*-

// Copyright 2006, 2007, 2008, 2009, 2010 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.

// gold can be configured to support threads.  If threads are
// supported, the user can specify at runtime whether or not to
// support them.  This provides an interface to manage locking
// accordingly.

// Lock
//   A simple lock class.

#ifndef GOLD_THREADS_H
#define GOLD_THREADS_H

namespace gold
{

class Condvar;
class Once_initialize;
class Initialize_lock_once;

// The interface for the implementation of a Lock.

class Lock_impl
{
 public:
  Lock_impl()
  { }

  virtual
  ~Lock_impl()
  { }

  virtual void
  acquire() = 0;

  virtual void
  release() = 0;
};

// A simple lock class.

class Lock
{
 public:
  Lock();

  ~Lock();

  // Acquire the lock.
  void
  acquire()
  { this->lock_->acquire(); }

  // Release the lock.
  void
  release()
  { this->lock_->release(); }

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

  friend class Condvar;
  Lock_impl*
  get_impl() const
  { return this->lock_; }

  Lock_impl* lock_;
};

// RAII for Lock.

class Hold_lock
{
 public:
  Hold_lock(Lock& lock)
    : lock_(lock)
  { this->lock_.acquire(); }

  ~Hold_lock()
  { this->lock_.release(); }

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

  Lock& lock_;
};

class Hold_optional_lock
{
 public:
  Hold_optional_lock(Lock* lock)
    : lock_(lock)
  {
    if (this->lock_ != NULL)
      this->lock_->acquire();
  }

  ~Hold_optional_lock()
  {
    if (this->lock_ != NULL)
      this->lock_->release();
  }

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

  Lock* lock_;
};

// The interface for the implementation of a condition variable.

class Condvar_impl
{
 public:
  Condvar_impl()
  { }

  virtual
  ~Condvar_impl()
  { }

  virtual void
  wait(Lock_impl*) = 0;

  virtual void
  signal() = 0;

  virtual void
  broadcast() = 0;
};

// A simple condition variable class.  It is always associated with a
// specific lock.

class Condvar
{
 public:
  Condvar(Lock& lock);
  ~Condvar();

  // Wait for the condition variable to be signalled.  This should
  // only be called when the lock is held.
  void
  wait()
  { this->condvar_->wait(this->lock_.get_impl()); }

  // Signal the condition variable--wake up at least one thread
  // waiting on the condition variable.  This should only be called
  // when the lock is held.
  void
  signal()
  { this->condvar_->signal(); }

  // Broadcast the condition variable--wake up all threads waiting on
  // the condition variable.  This should only be called when the lock
  // is held.
  void
  broadcast()
  { this->condvar_->broadcast(); }

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

  Lock& lock_;
  Condvar_impl* condvar_;
};

// A class used to do something once.  This is an abstract parent
// class; any actual use will involve a child of this.

class Once
{
 public:
  Once();

  virtual
  ~Once()
  { }

  // Call this function to do whatever it is.  We pass an argument
  // even though you have to use a child class because in some uses
  // setting the argument would itself require a Once class.
  void
  run_once(void* arg);

  // This is an internal function, which must be public because it is
  // run by an extern "C" function called via pthread_once.
  void
  internal_run(void* arg);

 protected:
  // This must be implemented by the child class.
  virtual void
  do_run_once(void* arg) = 0;

 private:
  // True if we have already run the function.
  bool was_run_;
  // Internal compare-and-swap lock on was_run_;
  uint32_t was_run_lock_;
  // The lock to run the function only once.
  Once_initialize* once_;
};

// A class used to initialize a lock exactly once, after the options
// have been read.  This is needed because the implementation of locks
// depends on whether we've seen the --threads option.  Before the
// options have been read, we know we are single-threaded, so we can
// get by without using a lock.  This class should be an instance
// variable of the class which has a lock which needs to be
// initialized.

class Initialize_lock : public Once
{
 public:
  // The class which uses this will have a pointer to a lock.  This
  // must be constructed with a pointer to that pointer.
  Initialize_lock(Lock** pplock)
    : pplock_(pplock)
  { }

  // Initialize the lock.  Return true if the lock is now initialized,
  // false if it is not (because the options have not yet been read).
  bool
  initialize();

 protected:
  void
  do_run_once(void*);

 private:
  // A pointer to the lock pointer which must be initialized.
  Lock** const pplock_;
};

} // End namespace gold.

#endif // !defined(GOLD_THREADS_H)
