Generate a GLOB_DAT reloc for a GOT32 reloc against a symbol defined
[platform/upstream/binutils.git] / gold / gold-threads.cc
1 // gold-threads.cc -- thread support for gold
2
3 #include "gold.h"
4
5 #ifdef ENABLE_THREADS
6 #include <pthread.h>
7 #endif
8
9 #include "gold-threads.h"
10
11 namespace gold
12 {
13
14 // Class Lock_impl. 
15
16 class Lock_impl
17 {
18  public:
19   Lock_impl();
20   ~Lock_impl();
21
22   void acquire();
23
24   void release();
25
26 private:
27   // This class can not be copied.
28   Lock_impl(const Lock_impl&);
29   Lock_impl& operator=(const Lock_impl&);
30
31   friend class Condvar_impl;
32
33 #ifdef ENABLE_THREADS
34   pthread_mutex_t mutex_;
35 #else
36   bool acquired_;
37 #endif
38 };
39
40 #ifdef ENABLE_THREADS
41
42 Lock_impl::Lock_impl()
43 {
44   pthread_mutexattr_t attr;
45   if (pthread_mutexattr_init(&attr) != 0)
46     gold_fatal(_("pthead_mutextattr_init failed"), true);
47 #ifdef PTHREAD_MUTEXT_ADAPTIVE_NP
48   if (pthread_mutextattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP) != 0)
49     gold_fatal(_("pthread_mutextattr_settype failed"), true);
50 #endif
51
52   if (pthread_mutex_init (&this->mutex_, &attr) != 0)
53     gold_fatal(_("pthread_mutex_init failed"), true);
54
55   if (pthread_mutexattr_destroy(&attr) != 0)
56     gold_fatal(_("pthread_mutexattr_destroy failed"), true);
57 }
58
59 Lock_impl::~Lock_impl()
60 {
61   if (pthread_mutex_destroy(&this->mutex_) != 0)
62     gold_fatal(_("pthread_mutex_destroy failed"), true);
63 }
64
65 void
66 Lock_impl::acquire()
67 {
68   if (pthread_mutex_lock(&this->mutex_) != 0)
69     gold_fatal(_("pthread_mutex_lock failed"), true);
70 }
71
72 void
73 Lock_impl::release()
74 {
75   if (pthread_mutex_unlock(&this->mutex_) != 0)
76     gold_fatal(_("pthread_mutex_unlock failed"), true);
77 }
78
79 #else // !defined(ENABLE_THREADS)
80
81 Lock_impl::Lock_impl()
82   : acquired_(false)
83 {
84 }
85
86 Lock_impl::~Lock_impl()
87 {
88   gold_assert(!this->acquired_);
89 }
90
91 void
92 Lock_impl::acquire()
93 {
94   gold_assert(!this->acquired_);
95   this->acquired_ = true;
96 }
97
98 void
99 Lock_impl::release()
100 {
101   gold_assert(this->acquired_);
102   this->acquired_ = false;
103 }
104
105 #endif // !defined(ENABLE_THREADS)
106
107 // Methods for Lock class.
108
109 Lock::Lock()
110 {
111   this->lock_ = new Lock_impl;
112 }
113
114 Lock::~Lock()
115 {
116   delete this->lock_;
117 }
118
119 void
120 Lock::acquire()
121 {
122   this->lock_->acquire();
123 }
124
125 void
126 Lock::release()
127 {
128   this->lock_->release();
129 }
130
131 // Class Condvar_impl.
132
133 class Condvar_impl
134 {
135  public:
136   Condvar_impl();
137   ~Condvar_impl();
138
139   void wait(Lock_impl*);
140   void signal();
141
142  private:
143   // This class can not be copied.
144   Condvar_impl(const Condvar_impl&);
145   Condvar_impl& operator=(const Condvar_impl&);
146
147 #ifdef ENABLE_THREADS
148   pthread_cond_t cond_;
149 #endif
150 };
151
152 #ifdef ENABLE_THREADS
153
154 Condvar_impl::Condvar_impl()
155 {
156   if (pthread_cond_init(&this->cond_, NULL) != 0)
157     gold_fatal(_("pthread_cond_init failed"), true);
158 }
159
160 Condvar_impl::~Condvar_impl()
161 {
162   if (pthread_cond_destroy(&this->cond_) != 0)
163     gold_fatal(_("pthread_cond_destroy failed"), true);
164 }
165
166 void
167 Condvar_impl::wait(Lock_impl* li)
168 {
169   if (pthread_cond_wait(&this->cond_, &li->mutex_) != 0)
170     gold_fatal(_("pthread_cond_wait failed"), true);
171 }
172
173 void
174 Condvar_impl::signal()
175 {
176   if (pthread_cond_signal(&this->cond_) != 0)
177     gold_fatal(_("pthread_cond_signal failed"), true);
178 }
179
180 #else // !defined(ENABLE_THREADS)
181
182 Condvar_impl::Condvar_impl()
183 {
184 }
185
186 Condvar_impl::~Condvar_impl()
187 {
188 }
189
190 void
191 Condvar_impl::wait(Lock_impl* li)
192 {
193   gold_assert(li->acquired_);
194 }
195
196 void
197 Condvar_impl::signal()
198 {
199 }
200
201 #endif // !defined(ENABLE_THREADS)
202
203 // Methods for Condvar class.
204
205 Condvar::Condvar(Lock& lock)
206   : lock_(lock)
207 {
208   this->condvar_ = new Condvar_impl;
209 }
210
211 Condvar::~Condvar()
212 {
213   delete this->condvar_;
214 }
215
216 void
217 Condvar::wait()
218 {
219   this->condvar_->wait(this->lock_.get_impl());
220 }
221
222 void
223 Condvar::signal()
224 {
225   this->condvar_->signal();
226 }
227
228 } // End namespace gold.