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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [gold/] [workqueue-threads.cc] - Diff between revs 816 and 818

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 816 Rev 818
// workqueue-threads.cc -- the threaded workqueue for gold
// workqueue-threads.cc -- the threaded workqueue for gold
 
 
// Copyright 2007, 2008 Free Software Foundation, Inc.
// Copyright 2007, 2008 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// Written by Ian Lance Taylor <iant@google.com>.
 
 
// This file is part of gold.
// This file is part of gold.
 
 
// This program is free software; you can redistribute it and/or modify
// 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
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
// (at your option) any later version.
 
 
// This program is distributed in the hope that it will be useful,
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// GNU General Public License for more details.
 
 
// You should have received a copy of the GNU General Public License
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// MA 02110-1301, USA.
// MA 02110-1301, USA.
 
 
// This file holds the workqueue implementation which may be used when
// This file holds the workqueue implementation which may be used when
// using threads.
// using threads.
 
 
#include "gold.h"
#include "gold.h"
 
 
#ifdef ENABLE_THREADS
#ifdef ENABLE_THREADS
 
 
#include <cstring>
#include <cstring>
#include <pthread.h>
#include <pthread.h>
 
 
#include "debug.h"
#include "debug.h"
#include "gold-threads.h"
#include "gold-threads.h"
#include "workqueue.h"
#include "workqueue.h"
#include "workqueue-internal.h"
#include "workqueue-internal.h"
 
 
namespace gold
namespace gold
{
{
 
 
// Class Workqueue_thread represents a single thread.  Creating an
// Class Workqueue_thread represents a single thread.  Creating an
// instance of this spawns a new thread.
// instance of this spawns a new thread.
 
 
class Workqueue_thread
class Workqueue_thread
{
{
 public:
 public:
  Workqueue_thread(Workqueue_threader_threadpool*, int thread_number);
  Workqueue_thread(Workqueue_threader_threadpool*, int thread_number);
 
 
  ~Workqueue_thread();
  ~Workqueue_thread();
 
 
 private:
 private:
  // This class can not be copied.
  // This class can not be copied.
  Workqueue_thread(const Workqueue_thread&);
  Workqueue_thread(const Workqueue_thread&);
  Workqueue_thread& operator=(const Workqueue_thread&);
  Workqueue_thread& operator=(const Workqueue_thread&);
 
 
  // Check for error from a pthread function.
  // Check for error from a pthread function.
  void
  void
  check(const char* function, int err) const;
  check(const char* function, int err) const;
 
 
  // A function to pass to pthread_create.  This is called with a
  // A function to pass to pthread_create.  This is called with a
  // pointer to an instance of this object.
  // pointer to an instance of this object.
  static void*
  static void*
  thread_body(void*);
  thread_body(void*);
 
 
  // A pointer to the threadpool that this thread is part of.
  // A pointer to the threadpool that this thread is part of.
  Workqueue_threader_threadpool* threadpool_;
  Workqueue_threader_threadpool* threadpool_;
  // The thread number.
  // The thread number.
  int thread_number_;
  int thread_number_;
  // The thread ID.
  // The thread ID.
  pthread_t tid_;
  pthread_t tid_;
};
};
 
 
// Create the thread in the constructor.
// Create the thread in the constructor.
 
 
Workqueue_thread::Workqueue_thread(Workqueue_threader_threadpool* threadpool,
Workqueue_thread::Workqueue_thread(Workqueue_threader_threadpool* threadpool,
                                   int thread_number)
                                   int thread_number)
  : threadpool_(threadpool), thread_number_(thread_number)
  : threadpool_(threadpool), thread_number_(thread_number)
{
{
  pthread_attr_t attr;
  pthread_attr_t attr;
  int err = pthread_attr_init(&attr);
  int err = pthread_attr_init(&attr);
  this->check("pthread_attr_init", err);
  this->check("pthread_attr_init", err);
 
 
  err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  this->check("pthread_attr_setdetachstate", err);
  this->check("pthread_attr_setdetachstate", err);
 
 
  err = pthread_create(&this->tid_, &attr, &Workqueue_thread::thread_body,
  err = pthread_create(&this->tid_, &attr, &Workqueue_thread::thread_body,
                       reinterpret_cast<void*>(this));
                       reinterpret_cast<void*>(this));
  this->check("pthread_create", err);
  this->check("pthread_create", err);
 
 
  err = pthread_attr_destroy(&attr);
  err = pthread_attr_destroy(&attr);
  this->check("pthread_attr_destroy", err);
  this->check("pthread_attr_destroy", err);
}
}
 
 
// The destructor will be called when the thread is exiting.
// The destructor will be called when the thread is exiting.
 
 
Workqueue_thread::~Workqueue_thread()
Workqueue_thread::~Workqueue_thread()
{
{
}
}
 
 
// Check for an error.
// Check for an error.
 
 
void
void
Workqueue_thread::check(const char* function, int err) const
Workqueue_thread::check(const char* function, int err) const
{
{
  if (err != 0)
  if (err != 0)
    gold_fatal(_("%s failed: %s"), function, strerror(err));
    gold_fatal(_("%s failed: %s"), function, strerror(err));
}
}
 
 
// Passed to pthread_create.
// Passed to pthread_create.
 
 
extern "C"
extern "C"
void*
void*
Workqueue_thread::thread_body(void* arg)
Workqueue_thread::thread_body(void* arg)
{
{
  Workqueue_thread* pwt = reinterpret_cast<Workqueue_thread*>(arg);
  Workqueue_thread* pwt = reinterpret_cast<Workqueue_thread*>(arg);
 
 
  pwt->threadpool_->process(pwt->thread_number_);
  pwt->threadpool_->process(pwt->thread_number_);
 
 
  // Delete the thread object as we exit.
  // Delete the thread object as we exit.
  delete pwt;
  delete pwt;
 
 
  return NULL;
  return NULL;
}
}
 
 
// Class Workqueue_threader_threadpool.
// Class Workqueue_threader_threadpool.
 
 
// Constructor.
// Constructor.
 
 
Workqueue_threader_threadpool::Workqueue_threader_threadpool(
Workqueue_threader_threadpool::Workqueue_threader_threadpool(
    Workqueue* workqueue)
    Workqueue* workqueue)
  : Workqueue_threader(workqueue),
  : Workqueue_threader(workqueue),
    check_thread_count_(0),
    check_thread_count_(0),
    lock_(),
    lock_(),
    desired_thread_count_(1),
    desired_thread_count_(1),
    threads_(1)
    threads_(1)
{
{
}
}
 
 
// Destructor.
// Destructor.
 
 
Workqueue_threader_threadpool::~Workqueue_threader_threadpool()
Workqueue_threader_threadpool::~Workqueue_threader_threadpool()
{
{
  // Tell the threads to exit.
  // Tell the threads to exit.
  this->get_workqueue()->set_thread_count(0);
  this->get_workqueue()->set_thread_count(0);
}
}
 
 
// Set the thread count.
// Set the thread count.
 
 
void
void
Workqueue_threader_threadpool::set_thread_count(int thread_count)
Workqueue_threader_threadpool::set_thread_count(int thread_count)
{
{
  int create;
  int create;
  {
  {
    Hold_lock hl(this->lock_);
    Hold_lock hl(this->lock_);
 
 
    this->desired_thread_count_ = thread_count;
    this->desired_thread_count_ = thread_count;
    create = this->desired_thread_count_ - this->threads_;
    create = this->desired_thread_count_ - this->threads_;
    if (create < 0)
    if (create < 0)
      this->check_thread_count_ = 1;
      this->check_thread_count_ = 1;
  }
  }
 
 
  if (create > 0)
  if (create > 0)
    {
    {
      for (int i = 0; i < create; ++i)
      for (int i = 0; i < create; ++i)
        {
        {
          // Note that threads delete themselves when they exit, so we
          // Note that threads delete themselves when they exit, so we
          // don't keep pointers to them.
          // don't keep pointers to them.
          new Workqueue_thread(this, this->threads_);
          new Workqueue_thread(this, this->threads_);
          ++this->threads_;
          ++this->threads_;
        }
        }
    }
    }
}
}
 
 
// Return whether the current thread should be cancelled.
// Return whether the current thread should be cancelled.
 
 
bool
bool
Workqueue_threader_threadpool::should_cancel_thread()
Workqueue_threader_threadpool::should_cancel_thread()
{
{
  // Fast exit without taking a lock.
  // Fast exit without taking a lock.
  if (!this->check_thread_count_)
  if (!this->check_thread_count_)
    return false;
    return false;
 
 
  {
  {
    Hold_lock hl(this->lock_);
    Hold_lock hl(this->lock_);
    if (this->threads_ > this->desired_thread_count_)
    if (this->threads_ > this->desired_thread_count_)
      {
      {
        --this->threads_;
        --this->threads_;
        return true;
        return true;
      }
      }
    this->check_thread_count_ = 0;
    this->check_thread_count_ = 0;
  }
  }
 
 
  return false;
  return false;
}
}
 
 
} // End namespace gold.
} // End namespace gold.
 
 
#endif // defined(ENABLE_THREADS)
#endif // defined(ENABLE_THREADS)
 
 

powered by: WebSVN 2.1.0

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