OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gold/] [gold-threads.h] - Rev 148

Go to most recent revision | Compare with Previous | Blame | View Log

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

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.