Imported Upstream version 3.2.2
[debian/gnuradio] / usrp / host / lib / legacy / mld_threads.h
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2006 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio.
6  *
7  * Primary Author: Michael Dickens, NCIP Lab, University of Notre Dame
8  * 
9  * GNU Radio is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 3, or (at your option)
12  * any later version.
13  * 
14  * GNU Radio is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  * 
19  * You should have received a copy of the GNU General Public License
20  * along with GNU Radio; see the file COPYING.  If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street,
22  * Boston, MA 02110-1301, USA.
23  */
24
25 #ifndef _INCLUDED_MLD_THREADS_H_
26 #define _INCLUDED_MLD_THREADS_H_
27
28 /* classes which allow for either pthreads or omni_threads */
29
30 #define __macos__
31 #ifdef _USE_OMNI_THREADS_
32 #include <gnuradio/omnithread.h>
33 #else
34 #include <pthread.h>
35 #endif
36
37 #include <stdexcept>
38
39 #define __INLINE__ inline
40
41 #ifndef DO_DEBUG
42 #define DO_DEBUG 0
43 #endif
44
45 #if DO_DEBUG
46 #define DEBUG(X) do{X} while(0);
47 #else
48 #define DEBUG(X) do{} while(0);
49 #endif
50
51 class mld_condition_t;
52
53 class mld_mutex_t {
54 #ifdef _USE_OMNI_THREADS_
55   typedef omni_mutex l_mutex, *l_mutex_ptr;
56 #else
57   typedef pthread_mutex_t l_mutex, *l_mutex_ptr;
58 #endif
59
60   friend class mld_condition_t;
61
62 private:
63   l_mutex_ptr d_mutex;
64
65 protected:
66   inline l_mutex_ptr mutex () { return (d_mutex); };
67
68 public:
69   __INLINE__ mld_mutex_t () {
70 #ifdef _USE_OMNI_THREADS_
71     d_mutex = new omni_mutex ();
72 #else
73     d_mutex = (l_mutex_ptr) new l_mutex;
74     int l_ret = pthread_mutex_init (d_mutex, NULL);
75     if (l_ret != 0) {
76       fprintf (stderr, "Error %d creating mutex.\n", l_ret);
77       throw std::runtime_error ("mld_mutex_t::mld_mutex_t()\n");
78     }
79 #endif
80   };
81
82   __INLINE__ ~mld_mutex_t () {
83     unlock ();
84 #ifndef _USE_OMNI_THREADS_
85     int l_ret = pthread_mutex_destroy (d_mutex);
86     if (l_ret != 0) {
87       fprintf (stderr, "mld_mutex_t::~mld_mutex_t(): "
88                "Error %d destroying mutex.\n", l_ret);
89     }
90 #endif
91     delete d_mutex;
92     d_mutex = NULL;
93   };
94
95   __INLINE__ void lock () {
96 #ifdef _USE_OMNI_THREADS_
97     d_mutex->lock ();
98 #else
99     int l_ret = pthread_mutex_lock (d_mutex);
100     if (l_ret != 0) {
101       fprintf (stderr, "mld_mutex_t::lock(): "
102                "Error %d locking mutex.\n", l_ret);
103     }
104 #endif
105   };
106
107   __INLINE__ void unlock () {
108 #ifdef _USE_OMNI_THREADS_
109     d_mutex->unlock ();
110 #else
111     int l_ret = pthread_mutex_unlock (d_mutex);
112     if (l_ret != 0) {
113       fprintf (stderr, "mld_mutex_t::unlock(): "
114                "Error %d locking mutex.\n", l_ret);
115     }
116 #endif
117   };
118
119   __INLINE__ bool trylock () {
120 #ifdef _USE_OMNI_THREADS_
121     int l_ret = d_mutex->trylock ();
122 #else
123     int l_ret = pthread_mutex_unlock (d_mutex);
124 #endif
125     return (l_ret == 0 ? true : false);
126   };
127
128   inline void acquire () { lock(); };
129   inline void release () { unlock(); };
130   inline void wait () { lock(); };
131   inline void post () { unlock(); };
132 };
133
134 typedef mld_mutex_t mld_mutex, *mld_mutex_ptr;
135
136 class mld_condition_t {
137 #ifdef _USE_OMNI_THREADS_
138   typedef omni_condition l_condition, *l_condition_ptr;
139 #else
140   typedef pthread_cond_t l_condition, *l_condition_ptr;
141 #endif
142
143 private:
144   l_condition_ptr d_condition;
145   mld_mutex_ptr d_mutex;
146   bool d_i_own_mutex;
147
148 public:
149   __INLINE__ mld_condition_t (mld_mutex_ptr mutex = NULL) {
150     if (mutex) {
151       d_i_own_mutex = false;
152       d_mutex = mutex;
153     } else {
154       d_i_own_mutex = true;
155       d_mutex = new mld_mutex ();
156     }
157 #ifdef _USE_OMNI_THREADS_
158     d_condition = new omni_condition (d_mutex->mutex ());
159 #else
160     d_condition = (l_condition_ptr) new l_condition;
161     int l_ret = pthread_cond_init (d_condition, NULL);
162     if (l_ret != 0) {
163       fprintf (stderr, "Error %d creating condition.\n", l_ret);
164       throw std::runtime_error ("mld_condition_t::mld_condition_t()\n");
165     }
166 #endif
167   };
168
169   __INLINE__ ~mld_condition_t () {
170     signal ();
171 #ifndef _USE_OMNI_THREADS_
172     int l_ret = pthread_cond_destroy (d_condition);
173     if (l_ret != 0) {
174       fprintf (stderr, "mld_condition_t::mld_condition_t(): "
175                "Error %d destroying condition.\n", l_ret);
176     }
177 #endif
178     delete d_condition;
179     d_condition = NULL;
180     if (d_i_own_mutex)
181       delete d_mutex;
182     d_mutex = NULL;
183   };
184
185   __INLINE__ mld_mutex_ptr mutex () {return (d_mutex);};
186
187   __INLINE__ void signal () {
188     DEBUG (fprintf (stderr, "a "););
189
190 #ifdef _USE_OMNI_THREADS_
191     d_condition->signal ();
192 #else
193     int l_ret = pthread_cond_signal (d_condition);
194     if (l_ret != 0) {
195       fprintf (stderr, "mld_condition_t::signal(): "
196                "Error %d.\n", l_ret);
197     }
198 #endif
199     DEBUG (fprintf (stderr, "b "););
200   };
201
202   __INLINE__ void wait () {
203     DEBUG (fprintf (stderr, "c "););
204 #ifdef _USE_OMNI_THREADS_
205     d_condition->wait ();
206 #else
207     int l_ret = pthread_cond_wait (d_condition, d_mutex->mutex ());
208     if (l_ret != 0) {
209       fprintf (stderr, "mld_condition_t::wait(): "
210                "Error %d.\n", l_ret);
211     }
212 #endif
213     DEBUG (fprintf (stderr, "d "););
214   };
215 };
216
217 typedef mld_condition_t mld_condition, *mld_condition_ptr;
218
219 class mld_thread_t {
220 #ifdef _USE_OMNI_THREADS_
221   typedef omni_thread l_thread, *l_thread_ptr;
222 #else
223   typedef pthread_t l_thread, *l_thread_ptr;
224 #endif
225
226 private:
227 #ifndef _USE_OMNI_THREADS_
228   l_thread d_thread;
229   void (*d_start_routine)(void*);
230   void *d_arg;
231 #else
232   l_thread_ptr d_thread;
233 #endif
234
235 #ifndef _USE_OMNI_THREADS_
236   static void* local_start_routine (void *arg) {
237     mld_thread_t* This = (mld_thread_t*) arg;
238     (*(This->d_start_routine))(This->d_arg);
239     return (NULL);
240   };
241 #endif
242
243 public:
244   __INLINE__ mld_thread_t (void (*start_routine)(void *), void *arg) {
245 #ifdef _USE_OMNI_THREADS_
246     d_thread = new omni_thread (start_routine, arg);
247     d_thread->start ();
248 #else
249     d_start_routine = start_routine;
250     d_arg = arg;
251     int l_ret = pthread_create (&d_thread, NULL, local_start_routine, this);
252     if (l_ret != 0) {
253       fprintf (stderr, "Error %d creating thread.\n", l_ret);
254       throw std::runtime_error ("mld_thread_t::mld_thread_t()\n");
255     }
256 #endif
257   };
258
259   __INLINE__ ~mld_thread_t () {
260 #ifdef _USE_OMNI_THREADS_
261 //  delete d_thread;
262     d_thread = NULL;
263 #else
264     int l_ret = pthread_detach (d_thread);
265     if (l_ret != 0) {
266       fprintf (stderr, "Error %d detaching thread.\n", l_ret);
267       throw std::runtime_error ("mld_thread_t::~mld_thread_t()\n");
268     }
269 #endif
270   };
271 };
272
273 typedef mld_thread_t mld_thread, *mld_thread_ptr;
274
275 #endif /* _INCLUDED_MLD_THREADS_H_ */