1 // workqueue-threads.cc -- the threaded workqueue for gold
3 // Copyright (C) 2007-2019 Free Software Foundation, Inc.
4 // Written by Ian Lance Taylor <iant@google.com>.
6 // This file is part of gold.
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.
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.
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.
23 // This file holds the workqueue implementation which may be used when
34 #include "gold-threads.h"
35 #include "workqueue.h"
36 #include "workqueue-internal.h"
41 // Class Workqueue_thread represents a single thread. Creating an
42 // instance of this spawns a new thread.
44 class Workqueue_thread
47 Workqueue_thread(Workqueue_threader_threadpool
*, int thread_number
);
52 // This class can not be copied.
53 Workqueue_thread(const Workqueue_thread
&);
54 Workqueue_thread
& operator=(const Workqueue_thread
&);
56 // Check for error from a pthread function.
58 check(const char* function
, int err
) const;
60 // A function to pass to pthread_create. This is called with a
61 // pointer to an instance of this object.
65 // A pointer to the threadpool that this thread is part of.
66 Workqueue_threader_threadpool
* threadpool_
;
73 // Create the thread in the constructor.
75 Workqueue_thread::Workqueue_thread(Workqueue_threader_threadpool
* threadpool
,
77 : threadpool_(threadpool
), thread_number_(thread_number
)
80 int err
= pthread_attr_init(&attr
);
81 this->check("pthread_attr_init", err
);
83 err
= pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
84 this->check("pthread_attr_setdetachstate", err
);
86 err
= pthread_create(&this->tid_
, &attr
, &Workqueue_thread::thread_body
,
87 reinterpret_cast<void*>(this));
88 this->check("pthread_create", err
);
90 err
= pthread_attr_destroy(&attr
);
91 this->check("pthread_attr_destroy", err
);
94 // The destructor will be called when the thread is exiting.
96 Workqueue_thread::~Workqueue_thread()
100 // Check for an error.
103 Workqueue_thread::check(const char* function
, int err
) const
106 gold_fatal(_("%s failed: %s"), function
, strerror(err
));
109 // Passed to pthread_create.
113 Workqueue_thread::thread_body(void* arg
)
115 Workqueue_thread
* pwt
= reinterpret_cast<Workqueue_thread
*>(arg
);
117 pwt
->threadpool_
->process(pwt
->thread_number_
);
119 // Delete the thread object as we exit.
125 // Class Workqueue_threader_threadpool.
129 Workqueue_threader_threadpool::Workqueue_threader_threadpool(
130 Workqueue
* workqueue
)
131 : Workqueue_threader(workqueue
),
132 check_thread_count_(0),
134 desired_thread_count_(1),
141 Workqueue_threader_threadpool::~Workqueue_threader_threadpool()
143 // Tell the threads to exit.
144 this->get_workqueue()->set_thread_count(0);
147 // Set the thread count.
150 Workqueue_threader_threadpool::set_thread_count(int thread_count
)
154 Hold_lock
hl(this->lock_
);
156 this->desired_thread_count_
= thread_count
;
157 create
= this->desired_thread_count_
- this->threads_
;
159 this->check_thread_count_
= 1;
164 for (int i
= 0; i
< create
; ++i
)
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_
);
174 // Return whether the current thread should be cancelled.
177 Workqueue_threader_threadpool::should_cancel_thread(int thread_number
)
179 // Fast exit without taking a lock.
180 if (!this->check_thread_count_
)
184 Hold_lock
hl(this->lock_
);
185 if (thread_number
> this->desired_thread_count_
)
188 if (this->threads_
<= this->desired_thread_count_
)
189 this->check_thread_count_
= 0;
197 } // End namespace gold.
199 #endif // defined(ENABLE_THREADS)