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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gold/] [workqueue-threads.cc] - Blame information for rev 183

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

Line No. Rev Author Line
1 27 khays
// workqueue-threads.cc -- the threaded workqueue for gold
2
 
3
// Copyright 2007, 2008 Free Software Foundation, Inc.
4
// Written by Ian Lance Taylor <iant@google.com>.
5
 
6
// This file is part of gold.
7
 
8
// This program is free software; you can redistribute it and/or modify
9
// it under the terms of the GNU General Public License as published by
10
// the Free Software Foundation; either version 3 of the License, or
11
// (at your option) any later version.
12
 
13
// This program is distributed in the hope that it will be useful,
14
// but WITHOUT ANY WARRANTY; without even the implied warranty of
15
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
// GNU General Public License for more details.
17
 
18
// You should have received a copy of the GNU General Public License
19
// along with this program; if not, write to the Free Software
20
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21
// MA 02110-1301, USA.
22
 
23
// This file holds the workqueue implementation which may be used when
24
// using threads.
25
 
26
#include "gold.h"
27
 
28
#ifdef ENABLE_THREADS
29
 
30
#include <cstring>
31
#include <pthread.h>
32
 
33
#include "debug.h"
34
#include "gold-threads.h"
35
#include "workqueue.h"
36
#include "workqueue-internal.h"
37
 
38
namespace gold
39
{
40
 
41
// Class Workqueue_thread represents a single thread.  Creating an
42
// instance of this spawns a new thread.
43
 
44
class Workqueue_thread
45
{
46
 public:
47
  Workqueue_thread(Workqueue_threader_threadpool*, int thread_number);
48
 
49
  ~Workqueue_thread();
50
 
51
 private:
52
  // This class can not be copied.
53
  Workqueue_thread(const Workqueue_thread&);
54
  Workqueue_thread& operator=(const Workqueue_thread&);
55
 
56
  // Check for error from a pthread function.
57
  void
58
  check(const char* function, int err) const;
59
 
60
  // A function to pass to pthread_create.  This is called with a
61
  // pointer to an instance of this object.
62
  static void*
63
  thread_body(void*);
64
 
65
  // A pointer to the threadpool that this thread is part of.
66
  Workqueue_threader_threadpool* threadpool_;
67
  // The thread number.
68
  int thread_number_;
69
  // The thread ID.
70
  pthread_t tid_;
71
};
72
 
73
// Create the thread in the constructor.
74
 
75
Workqueue_thread::Workqueue_thread(Workqueue_threader_threadpool* threadpool,
76
                                   int thread_number)
77
  : threadpool_(threadpool), thread_number_(thread_number)
78
{
79
  pthread_attr_t attr;
80
  int err = pthread_attr_init(&attr);
81
  this->check("pthread_attr_init", err);
82
 
83
  err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
84
  this->check("pthread_attr_setdetachstate", err);
85
 
86
  err = pthread_create(&this->tid_, &attr, &Workqueue_thread::thread_body,
87
                       reinterpret_cast<void*>(this));
88
  this->check("pthread_create", err);
89
 
90
  err = pthread_attr_destroy(&attr);
91
  this->check("pthread_attr_destroy", err);
92
}
93
 
94
// The destructor will be called when the thread is exiting.
95
 
96
Workqueue_thread::~Workqueue_thread()
97
{
98
}
99
 
100
// Check for an error.
101
 
102
void
103
Workqueue_thread::check(const char* function, int err) const
104
{
105
  if (err != 0)
106
    gold_fatal(_("%s failed: %s"), function, strerror(err));
107
}
108
 
109
// Passed to pthread_create.
110
 
111
extern "C"
112
void*
113
Workqueue_thread::thread_body(void* arg)
114
{
115
  Workqueue_thread* pwt = reinterpret_cast<Workqueue_thread*>(arg);
116
 
117
  pwt->threadpool_->process(pwt->thread_number_);
118
 
119
  // Delete the thread object as we exit.
120
  delete pwt;
121
 
122
  return NULL;
123
}
124
 
125
// Class Workqueue_threader_threadpool.
126
 
127
// Constructor.
128
 
129
Workqueue_threader_threadpool::Workqueue_threader_threadpool(
130
    Workqueue* workqueue)
131
  : Workqueue_threader(workqueue),
132
    check_thread_count_(0),
133
    lock_(),
134
    desired_thread_count_(1),
135
    threads_(1)
136
{
137
}
138
 
139
// Destructor.
140
 
141
Workqueue_threader_threadpool::~Workqueue_threader_threadpool()
142
{
143
  // Tell the threads to exit.
144
  this->get_workqueue()->set_thread_count(0);
145
}
146
 
147
// Set the thread count.
148
 
149
void
150
Workqueue_threader_threadpool::set_thread_count(int thread_count)
151
{
152
  int create;
153
  {
154
    Hold_lock hl(this->lock_);
155
 
156
    this->desired_thread_count_ = thread_count;
157
    create = this->desired_thread_count_ - this->threads_;
158
    if (create < 0)
159
      this->check_thread_count_ = 1;
160
  }
161
 
162
  if (create > 0)
163
    {
164
      for (int i = 0; i < create; ++i)
165
        {
166
          // Note that threads delete themselves when they exit, so we
167
          // don't keep pointers to them.
168
          new Workqueue_thread(this, this->threads_);
169
          ++this->threads_;
170
        }
171
    }
172
}
173
 
174
// Return whether the current thread should be cancelled.
175
 
176
bool
177 159 khays
Workqueue_threader_threadpool::should_cancel_thread(int thread_number)
178 27 khays
{
179
  // Fast exit without taking a lock.
180
  if (!this->check_thread_count_)
181
    return false;
182
 
183
  {
184
    Hold_lock hl(this->lock_);
185 159 khays
    if (thread_number > this->desired_thread_count_)
186 27 khays
      {
187
        --this->threads_;
188 159 khays
        if (this->threads_ <= this->desired_thread_count_)
189
          this->check_thread_count_ = 0;
190 27 khays
        return true;
191
      }
192
  }
193
 
194
  return false;
195
}
196
 
197
} // End namespace gold.
198
 
199
#endif // defined(ENABLE_THREADS)

powered by: WebSVN 2.1.0

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