Imported Upstream version 3.2.2
[debian/gnuradio] / gr-audio-osx / src / 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 #define DO_DEBUG 0
41
42 #if DO_DEBUG
43 #define DEBUG(X) do{X} while(0);
44 #else
45 #define DEBUG(X) do{} while(0);
46 #endif
47
48 class mld_condition_t;
49
50 class mld_mutex_t {
51 #ifdef _USE_OMNI_THREADS_
52   typedef omni_mutex l_mutex, *l_mutex_ptr;
53 #else
54   typedef pthread_mutex_t l_mutex, *l_mutex_ptr;
55 #endif
56
57   friend class mld_condition_t;
58
59 private:
60   l_mutex_ptr d_mutex;
61
62 protected:
63   inline l_mutex_ptr mutex () { return (d_mutex); };
64
65 public:
66   __INLINE__ mld_mutex_t () {
67 #ifdef _USE_OMNI_THREADS_
68     d_mutex = new omni_mutex ();
69 #else
70     d_mutex = (l_mutex_ptr) new l_mutex;
71     int l_ret = pthread_mutex_init (d_mutex, NULL);
72     if (l_ret != 0) {
73       fprintf (stderr, "Error %d creating mutex.\n", l_ret);
74       throw std::runtime_error ("mld_mutex_t::mld_mutex_t()\n");
75     }
76 #endif
77   };
78
79   __INLINE__ ~mld_mutex_t () {
80     unlock ();
81 #ifndef _USE_OMNI_THREADS_
82     int l_ret = pthread_mutex_destroy (d_mutex);
83     if (l_ret != 0) {
84       fprintf (stderr, "mld_mutex_t::~mld_mutex_t(): "
85                "Error %d destroying mutex.\n", l_ret);
86     }
87 #endif
88     delete d_mutex;
89     d_mutex = NULL;
90   };
91
92   __INLINE__ void lock () {
93 #ifdef _USE_OMNI_THREADS_
94     d_mutex->lock ();
95 #else
96     int l_ret = pthread_mutex_lock (d_mutex);
97     if (l_ret != 0) {
98       fprintf (stderr, "mld_mutex_t::lock(): "
99                "Error %d locking mutex.\n", l_ret);
100     }
101 #endif
102   };
103
104   __INLINE__ void unlock () {
105 #ifdef _USE_OMNI_THREADS_
106     d_mutex->unlock ();
107 #else
108     int l_ret = pthread_mutex_unlock (d_mutex);
109     if (l_ret != 0) {
110       fprintf (stderr, "mld_mutex_t::unlock(): "
111                "Error %d locking mutex.\n", l_ret);
112     }
113 #endif
114   };
115
116   __INLINE__ bool trylock () {
117 #ifdef _USE_OMNI_THREADS_
118     int l_ret = d_mutex->trylock ();
119 #else
120     int l_ret = pthread_mutex_unlock (d_mutex);
121 #endif
122     return (l_ret == 0 ? true : false);
123   };
124
125   inline void acquire () { lock(); };
126   inline void release () { unlock(); };
127   inline void wait () { lock(); };
128   inline void post () { unlock(); };
129 };
130
131 typedef mld_mutex_t mld_mutex, *mld_mutex_ptr;
132
133 class mld_condition_t {
134 #ifdef _USE_OMNI_THREADS_
135   typedef omni_condition l_condition, *l_condition_ptr;
136 #else
137   typedef pthread_cond_t l_condition, *l_condition_ptr;
138 #endif
139
140 private:
141   l_condition_ptr d_condition;
142   mld_mutex_ptr d_mutex;
143   bool d_i_own_mutex;
144
145 public:
146   __INLINE__ mld_condition_t (mld_mutex_ptr mutex = NULL) {
147     if (mutex) {
148       d_i_own_mutex = false;
149       d_mutex = mutex;
150     } else {
151       d_i_own_mutex = true;
152       d_mutex = new mld_mutex ();
153     }
154 #ifdef _USE_OMNI_THREADS_
155     d_condition = new omni_condition (d_mutex->mutex ());
156 #else
157     d_condition = (l_condition_ptr) new l_condition;
158     int l_ret = pthread_cond_init (d_condition, NULL);
159     if (l_ret != 0) {
160       fprintf (stderr, "Error %d creating condition.\n", l_ret);
161       throw std::runtime_error ("mld_condition_t::mld_condition_t()\n");
162     }
163 #endif
164   };
165
166   __INLINE__ ~mld_condition_t () {
167     signal ();
168 #ifndef _USE_OMNI_THREADS_
169     int l_ret = pthread_cond_destroy (d_condition);
170     if (l_ret != 0) {
171       fprintf (stderr, "mld_condition_t::mld_condition_t(): "
172                "Error %d destroying condition.\n", l_ret);
173     }
174 #endif
175     delete d_condition;
176     d_condition = NULL;
177     if (d_i_own_mutex)
178       delete d_mutex;
179     d_mutex = NULL;
180   };
181
182   __INLINE__ mld_mutex_ptr mutex () {return (d_mutex);};
183
184   __INLINE__ void signal () {
185     DEBUG (fprintf (stderr, "a "));
186
187 #ifdef _USE_OMNI_THREADS_
188     d_condition->signal ();
189 #else
190     int l_ret = pthread_cond_signal (d_condition);
191     if (l_ret != 0) {
192       fprintf (stderr, "mld_condition_t::signal(): "
193                "Error %d.\n", l_ret);
194     }
195 #endif
196     DEBUG (fprintf (stderr, "b "));
197   };
198
199   __INLINE__ void wait () {
200     DEBUG (fprintf (stderr, "c "));
201 #ifdef _USE_OMNI_THREADS_
202     d_condition->wait ();
203 #else
204     int l_ret = pthread_cond_wait (d_condition, d_mutex->mutex ());
205     if (l_ret != 0) {
206       fprintf (stderr, "mld_condition_t::wait(): "
207                "Error %d.\n", l_ret);
208     }
209 #endif
210     DEBUG (printf (stderr, "d "));
211   };
212 };
213
214 typedef mld_condition_t mld_condition, *mld_condition_ptr;
215
216 class mld_thread_t {
217 #ifdef _USE_OMNI_THREADS_
218   typedef omni_thread l_thread, *l_thread_ptr;
219 #else
220   typedef pthread_t l_thread, *l_thread_ptr;
221 #endif
222
223 private:
224 #ifndef _USE_OMNI_THREADS_
225   l_thread d_thread;
226   void (*d_start_routine)(void*);
227   void *d_arg;
228 #else
229   l_thread_ptr d_thread;
230 #endif
231
232 #ifndef _USE_OMNI_THREADS_
233   static void* local_start_routine (void *arg) {
234     mld_thread_t* This = (mld_thread_t*) arg;
235     (*(This->d_start_routine))(This->d_arg);
236     return (NULL);
237   };
238 #endif
239
240 public:
241   __INLINE__ mld_thread_t (void (*start_routine)(void *), void *arg) {
242 #ifdef _USE_OMNI_THREADS_
243     d_thread = new omni_thread (start_routine, arg);
244     d_thread->start ();
245 #else
246     d_start_routine = start_routine;
247     d_arg = arg;
248     int l_ret = pthread_create (&d_thread, NULL, local_start_routine, this);
249     if (l_ret != 0) {
250       fprintf (stderr, "Error %d creating thread.\n", l_ret);
251       throw std::runtime_error ("mld_thread_t::mld_thread_t()\n");
252     }
253 #endif
254   };
255
256   __INLINE__ ~mld_thread_t () {
257 #ifdef _USE_OMNI_THREADS_
258 //  delete d_thread;
259     d_thread = NULL;
260 #else
261     int l_ret = pthread_detach (d_thread);
262     if (l_ret != 0) {
263       fprintf (stderr, "Error %d detaching thread.\n", l_ret);
264       throw std::runtime_error ("mld_thread_t::~mld_thread_t()\n");
265     }
266 #endif
267   };
268 };
269
270 typedef mld_thread_t mld_thread, *mld_thread_ptr;
271
272 #endif /* _INCLUDED_MLD_THREADS_H_ */