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

// Copyright (C) 2006-2021 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_;
#if defined(ENABLE_THREADS) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
  // Internal compare-and-swap lock on was_run_;
  uint32_t was_run_lock_;
#endif
  // 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)
