NeoPZ
pz_pthread.cpp
Go to the documentation of this file.
1 #include "pz_pthread.h"
2 
3 #include<map>
4 
5 using namespace std;
6 
8 {
9  pz_pthread_info_t() : tid(0), last_op(0), last_ct(0)
10  {}
11 
12  int tid;
13  int last_op;
14  int last_ct;
15  // Create time
16  // Join time
17 };
18 
20 {
21 public:
23  {
24  pthread_mutex_init(&mutex, NULL);
25  }
27  {
28  pthread_mutex_destroy(&mutex);
29  }
30 
31  int lock() {
32  int ret = pthread_mutex_lock(&mutex);
33  if (ret) {
34  cerr << "ERROR: (" << __FILE__ << ":" << __LINE__ << ") pthread_mutex_lock(&mutex) returned " << ret << endl;
35  }
36  return ret;
37  }
38 
39  int unlock() {
40  return pthread_mutex_unlock(&mutex);
41  }
42 
43 private:
44 
45  pthread_mutex_t mutex;
46 
47 };
48 
49 #if (defined THREAD_NOTES || defined THREAD_MUTEX_NOTES || defined THREAD_COND_NOTES)
50 
51 map<int,pz_pthread_info_t> threads_info;
52 static bool pz_pthread_logging = false;
53 static unsigned max_sim_threads = 0;
54 static unsigned sim_threads = 0;
55 pz_pthread_mutex_t pz_pmutex;
56 
58 {
59  pz_pthread_logging = true;
60 
61 #ifdef THREAD_NOTES
62  max_sim_threads = 0;
63  sim_threads = 0;
64 #endif //THREAD_NOTES
65 }
66 
68 {
69  pz_pthread_logging = false;
70 }
71 
72 void pz_pthread_log_report(ostream& o)
73 {
74  cout << "pz_pthread_log_report:" << endl;
75 #ifdef THREAD_NOTES
76  cout << "Max number of simultaneous threads = " << max_sim_threads << endl;
77 #endif //THREAD_NOTES
78 }
79 
80 #else // THREAD_NOTES || THREAD_MUTEX_NOTES || THREAD_COND_NOTES
81 
84 void pz_pthread_log_report(std::ostream& o) {}
85 
86 #endif // THREAD_NOTES || THREAD_MUTEX_NOTES || THREAD_COND_NOTES
87 
88 
89 
90 #ifdef THREAD_NOTES
91 
92 int pz_pthread_join(pthread_t thread, void **value_ptr, const char* fn,
93  const char* file, unsigned line)
94 {
95  int ret = pthread_join(thread, value_ptr);
96 
97  if (pz_pthread_logging && (ret == 0)) {
98 
99  pz_pmutex.lock();
100 
101  sim_threads--;
102  std::cout << (int*) thread << " -> "
103  << (int*) pthread_self() << "; Join thread at "
104  << fn << " (" << file << ":" << line << ")."
105  << " sim_threads = " << sim_threads << std::endl;
106 
107  pz_pmutex.unlock();
108 
109  }
110 
111  return ret;
112 }
113 
114 int pz_pthread_create(pthread_t *thread, const pthread_attr_t *attr, void
115  *(*start_routine)(void *), void *arg, const char* fn,
116  const char* file, unsigned line)
117 {
118  int ret = pthread_create(thread, attr, start_routine, arg);
119 
120  if (pz_pthread_logging && (ret == 0)) {
121 
122  pz_pmutex.lock();
123 
124  sim_threads++;
125  if (sim_threads > max_sim_threads) max_sim_threads = sim_threads;
126 
127  std::cout << (int*) pthread_self() << " - "
128  << (int*) *thread << "; Create thread at "
129  << fn << " (" << file << ":" << line << ")."
130  << " sim_threads = " << sim_threads << std::endl;
131 
132  pz_pmutex.unlock();
133 
134  }
135 
136  return ret;
137 }
138 
139 #endif //THREAD_NOTES
140 
141 
142 #ifdef THREAD_MUTEX_NOTES
143 
144 int pz_pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* attr,
145  const char* fn, const char* file, unsigned line)
146 {
147  int ret = pthread_mutex_init(mutex, attr);
148 
149  if (pz_pthread_logging) {
150 
151  pz_pmutex.lock();
152 
153  std::cout << "pthread_mutex_init() ret : " << ret
154  << " : self thread " << (int*) pthread_self() << " : at : "
155  << fn << " : " << file << " : " << line << std::endl;
156 
157  pz_pmutex.unlock();
158 
159  }
160 
161  return ret;
162 }
163 
164 int pz_pthread_mutex_destroy(pthread_mutex_t *mutex,
165  const char* fn, const char* file, unsigned line)
166 {
167  int ret = pthread_mutex_destroy(mutex);
168 
169  if (pz_pthread_logging) {
170 
171  pz_pmutex.lock();
172 
173  std::cout << "pthread_mutex_destroy() ret : " << ret
174  << " : self thread " << (int*) pthread_self() << " : at : "
175  << fn << " : " << file << " : " << line << std::endl;
176 
177  pz_pmutex.unlock();
178 
179  }
180  return ret;
181 }
182 
183 int pz_pthread_mutex_lock(pthread_mutex_t *mutex,
184  const char* fn, const char* file, unsigned line)
185 {
186  int ret = pthread_mutex_lock(mutex);
187 
188  if (pz_pthread_logging) {
189 
190  pz_pmutex.lock();
191 
192  std::cout << "pthread_mutex_lock() ret : " << ret
193  << " : self thread " << (int*) pthread_self() << " : at : "
194  << fn << " : " << file << " : " << line << std::endl;
195 
196  pz_pmutex.unlock();
197 
198  }
199  return ret;
200 }
201 
202 int pz_pthread_mutex_unlock(pthread_mutex_t *mutex,
203  const char* fn, const char* file, unsigned line)
204 {
205  int ret = pthread_mutex_unlock(mutex);
206 
207  if (pz_pthread_logging) {
208 
209  pz_pmutex.lock();
210 
211  std::cout << "pthread_mutex_unlock() ret : " << ret
212  << " : self thread " << (int*) pthread_self() << " : at : "
213  << fn << " : " << file << " : " << line << std::endl;
214 
215  pz_pmutex.unlock();
216 
217  }
218  return ret;
219 }
220 
221 #endif
222 
223 
224 #ifdef THREAD_COND_NOTES
225 
226 int pz_pthread_cond_init(pthread_cond_t* cond, const pthread_condattr_t* attr,
227  const char* fn, const char* file, unsigned line)
228 {
229  int ret = pthread_cond_init(cond,attr);
230 
231  if (pz_pthread_logging) {
232 
233  pz_pmutex.lock();
234 
235  std::cout << "pthread_cond_init() ret : " << ret
236  << " : self thread " << (int*) pthread_self() << " : at : "
237  << fn << " : " << file << " : " << line << std::endl;
238 
239  pz_pmutex.unlock();
240 
241  }
242  return ret;
243 }
244 
245 int pz_pthread_cond_destroy(pthread_cond_t *cond,
246  const char* fn, const char* file, unsigned line)
247 {
248  int ret = pthread_cond_destroy(cond);
249 
250  if (pz_pthread_logging) {
251 
252  pz_pmutex.lock();
253 
254  std::cout << "pthread_cond_destroy() ret : " << ret
255  << " : self thread " << (int*) pthread_self() << " : at : "
256  << fn << " : " << file << " : " << line << std::endl;
257 
258  pz_pmutex.unlock();
259 
260  }
261  return ret;
262 }
263 
264 int pz_pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex,
265  const char* fn, const char* file, unsigned line)
266 {
267  int ret = pthread_cond_wait(cond, mutex);
268 
269  if (pz_pthread_logging) {
270 
271  pz_pmutex.lock();
272 
273  std::cout << "pthread_cond_wait() ret : " << ret
274  << " : self thread " << (int*) pthread_self() << " : at : "
275  << fn << " : " << file << " : " << line << std::endl;
276 
277  pz_pmutex.unlock();
278 
279  }
280  return ret;
281 }
282 
283 int pz_pthread_cond_broadcast(pthread_cond_t *cond,
284  const char* fn, const char* file, unsigned line)
285 {
286  int ret = pthread_cond_broadcast(cond);
287 
288  if (pz_pthread_logging) {
289 
290  pz_pmutex.lock();
291 
292  std::cout << "pthread_cond_broadcast() ret : " << ret
293  << " : self thread " << (int*) pthread_self() << " : at : "
294  << fn << " : " << file << " : " << line << std::endl;
295 
296  pz_pmutex.unlock();
297 
298  }
299  return ret;
300 }
301 
302 int pz_pthread_cond_signal(pthread_cond_t *cond,
303  const char* fn, const char* file, unsigned line)
304 {
305  int ret = pthread_cond_signal(cond);
306 
307  if (pz_pthread_logging) {
308 
309  pz_pmutex.lock();
310 
311  std::cout << "pthread_cond_signal() ret : " << ret
312  << " : self thread " << (int*) pthread_self() << " : at : "
313  << fn << " : " << file << " : " << line << std::endl;
314 
315  pz_pmutex.unlock();
316 
317  }
318  return ret;
319 }
320 
321 #endif //THREAD_COND_NOTES
pthread_mutex_t mutex
Semaphore which controls multiple threads.
void pz_pthread_log_stop()
Definition: pz_pthread.cpp:82
fn
Definition: test.py:253
pthread_mutex_t mutex
Definition: pz_pthread.cpp:45
pthread_cond_t cond
Definition: numatst.cpp:318
void pz_pthread_log_report(std::ostream &o)
Definition: pz_pthread.cpp:84
void pz_pthread_log_start()
Definition: pz_pthread.cpp:83