root/trunk/libffado/src/libutil/PosixThread.cpp

Revision 2732, 9.0 kB (checked in by jwoithe, 3 years ago)

Fix typos throughout the source tree.

Rectify some long-lived typos in strings throughout the source code. in the
FFADO desktop file. This benefits Debian and possibly others. Patch by
Nicolas Boulenguez for Debian and provided to FFADO by Benoit Delcour via
the ffado-user mailing list.

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB
8  *
9  * This program 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 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 /*
25  * Copied from the jackd/jackdmp sources
26  * function names changed in order to avoid naming problems when using this in
27  * a jackd backend.
28  */
29
30 /* Original license:
31  * Copyright (C) 2001 Paul Davis
32  * Copyright (C) 2004-2006 Grame
33  *
34  * this program is free software; you can redistribute it and/or modify
35  * it under the terms of the GNU General Public License as published by
36  * the Free Software Foundation; either version 2 of the License, or
37  * (at your option) version 3 of the License.
38  *
39  * This program is distributed in the hope that it will be useful,
40  * but WITHOUT ANY WARRANTY; without even the implied warranty of
41  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
42  * GNU General Public License for more details.
43  *
44  * You should have received a copy of the GNU General Public License
45  * along with this program; if not, write to the Free Software
46  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
47  *
48  */
49
50 #include "PosixThread.h"
51 #include <string.h> // for memset
52 #include <errno.h>
53 #include <assert.h>
54 #include <sys/prctl.h>
55
56 namespace Util
57 {
58
59 IMPL_DEBUG_MODULE( Thread, Thread, DEBUG_LEVEL_NORMAL );
60
61 void* PosixThread::ThreadHandler(void* arg)
62 {
63     PosixThread* obj = (PosixThread*)arg;
64     RunnableInterface* runnable = obj->fRunnable;
65     int err;
66
67     obj->m_lock.Lock();
68
69     // Signal that ThreadHandler has acquired its initial lock
70     pthread_mutex_lock(&obj->handler_active_lock);
71     obj->handler_active = 1;
72     pthread_cond_signal(&obj->handler_active_cond);
73     pthread_mutex_unlock(&obj->handler_active_lock);
74
75     if ((err = pthread_setcanceltype(obj->fCancellation, NULL)) != 0) {
76         debugError("pthread_setcanceltype err = %s\n", strerror(err));
77     }
78
79     // Call Init method
80     if (!runnable->Init()) {
81         debugError("Thread init fails: thread quits\n");
82         obj->m_lock.Unlock();
83         return 0;
84     }
85
86     std::string threadname = std::string("FW_") + obj->m_id;
87     prctl(PR_SET_NAME, threadname.c_str());
88
89     debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) ThreadHandler: start %p\n", obj->m_id.c_str(), obj);
90
91     // If Init succeed start the thread loop
92     bool res = true;
93
94     obj->m_lock.Unlock();
95     while (obj->fRunning && res) {
96         debugOutputExtreme( DEBUG_LEVEL_VERY_VERBOSE, "(%s) ThreadHandler: run %p\n", obj->m_id.c_str(), obj);
97         res = runnable->Execute();
98         pthread_testcancel();
99     }
100
101     debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) ThreadHandler: exit %p\n", obj->m_id.c_str(), obj);
102     return 0;
103 }
104
105 int PosixThread::Start()
106 {
107     int res;
108     fRunning = true;
109
110     if (fRealTime) {
111
112         debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Create RT thread %p with priority %d\n", m_id.c_str(), this, fPriority);
113
114         /* Get the client thread to run as an RT-FIFO
115            scheduled thread of appropriate priority.
116         */
117         pthread_attr_t attributes;
118         struct sched_param rt_param;
119         pthread_attr_init(&attributes);
120
121         if ((res = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED))) {
122             debugError("Cannot request explicit scheduling for RT thread  %d %s\n", res, strerror(res));
123             return -1;
124         }
125         if ((res = pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_JOINABLE))) {
126             debugError("Cannot request joinable thread creation for RT thread  %d %s\n", res, strerror(res));
127             return -1;
128         }
129         if ((res = pthread_attr_setscope(&attributes, PTHREAD_SCOPE_SYSTEM))) {
130             debugError("Cannot set scheduling scope for RT thread %d %s\n", res, strerror(res));
131             return -1;
132         }
133
134         if ((res = pthread_attr_setschedpolicy(&attributes, SCHED_FIFO))) {
135
136         //if ((res = pthread_attr_setschedpolicy(&attributes, SCHED_RR))) {
137             debugError("Cannot set FIFO scheduling class for RT thread  %d %s\n", res, strerror(res));
138             return -1;
139         }
140
141         memset(&rt_param, 0, sizeof(rt_param));
142         if(fPriority <= 0) {
143             debugWarning("Clipping to minimum priority (%d -> 1)\n", fPriority);
144             rt_param.sched_priority = 1;
145         } else if(fPriority >= 99) {
146             debugWarning("Clipping to maximum priority (%d -> 98)\n", fPriority);
147             rt_param.sched_priority = 98;
148         } else {
149             rt_param.sched_priority = fPriority;
150         }
151
152         if ((res = pthread_attr_setschedparam(&attributes, &rt_param))) {
153             debugError("Cannot set scheduling priority for RT thread %d %s\n", res, strerror(res));
154             return -1;
155         }
156
157         m_lock.Lock();
158         res = pthread_create(&fThread, &attributes, ThreadHandler, this);
159         m_lock.Unlock();
160         if (res) {
161             debugError("Cannot create realtime thread (%d: %s)\n", res, strerror(res));
162             debugError(" priority: %d\n", fPriority);
163             return -1;
164         }
165     } else {
166         debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Create non RT thread %p\n", m_id.c_str(), this);
167
168         m_lock.Lock();
169         res = pthread_create(&fThread, 0, ThreadHandler, this);
170         m_lock.Unlock();
171         if (res) {
172             debugError("Cannot create thread %d %s\n", res, strerror(res));
173             return -1;
174         }
175     }
176
177     // Wait for ThreadHandler() to acquire the thread lock (m_lock) before
178     // continuing, thereby ensuring that ThreadHandler() acquires a lock on
179     // m_lock before anything else tries.
180     pthread_mutex_lock(&handler_active_lock);
181     while (handler_active == 0)
182         pthread_cond_wait(&handler_active_cond, &handler_active_lock);
183     pthread_mutex_unlock(&handler_active_lock);
184
185     return 0;
186 }
187
188 int PosixThread::Kill()
189 {
190     if (fThread) { // If thread has been started
191         debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Kill %p (thread: %p)\n", m_id.c_str(), this, (void *)fThread);
192         void* status;
193         pthread_cancel(fThread);
194         m_lock.Lock();
195         pthread_join(fThread, &status);
196         m_lock.Unlock();
197         debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Killed %p (thread: %p)\n", m_id.c_str(), this, (void *)fThread);
198         return 0;
199     } else {
200         return -1;
201     }
202 }
203
204 int PosixThread::Stop()
205 {
206     if (fThread) { // If thread has been started
207         debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Stop %p (thread: %p)\n", m_id.c_str(), this, (void *)fThread);
208         void* status;
209         fRunning = false; // Request for the thread to stop
210         m_lock.Lock();
211         pthread_join(fThread, &status);
212         fThread = 0;
213         m_lock.Unlock();
214         debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Stopped %p (thread: %p)\n", m_id.c_str(), this, (void *)fThread);
215         return 0;
216     } else {
217         return -1;
218     }
219 }
220
221 int PosixThread::AcquireRealTime()
222 {
223     struct sched_param rtparam;
224     int res;
225     debugOutput( DEBUG_LEVEL_VERBOSE, "(%s, %p) Acquire realtime, prio %d\n", m_id.c_str(), this, fPriority);
226
227     if (!fThread)
228         return -1;
229
230     memset(&rtparam, 0, sizeof(rtparam));
231     if(fPriority <= 0) {
232         debugWarning("Clipping to minimum priority (%d -> 1)\n", fPriority);
233         rtparam.sched_priority = 1;
234     } else if(fPriority >= 99) {
235         debugWarning("Clipping to maximum priority (%d -> 98)\n", fPriority);
236         rtparam.sched_priority = 98;
237     } else {
238         rtparam.sched_priority = fPriority;
239     }
240
241     //if ((res = pthread_setschedparam(fThread, SCHED_FIFO, &rtparam)) != 0) {
242
243     if ((res = pthread_setschedparam(fThread, SCHED_FIFO, &rtparam)) != 0) {
244         debugError("Cannot use real-time scheduling (FIFO/%d) "
245                    "(%d: %s)", rtparam.sched_priority, res,
246                    strerror(res));
247         return -1;
248     }
249     return 0;
250 }
251
252 int PosixThread::AcquireRealTime(int priority)
253 {
254     fPriority = priority;
255     return AcquireRealTime();
256 }
257
258 int PosixThread::DropRealTime()
259 {
260     struct sched_param rtparam;
261     int res;
262     debugOutput( DEBUG_LEVEL_VERBOSE, "(%s, %p) Drop realtime\n", m_id.c_str(), this);
263
264     if (!fThread)
265         return -1;
266
267     memset(&rtparam, 0, sizeof(rtparam));
268     rtparam.sched_priority = 0;
269
270     if ((res = pthread_setschedparam(fThread, SCHED_OTHER, &rtparam)) != 0) {
271         debugError("Cannot switch to normal scheduling priority(%s)\n", strerror(res));
272         return -1;
273     }
274     return 0;
275 }
276
277 pthread_t PosixThread::GetThreadID()
278 {
279     return fThread;
280 }
281
282 } // end of namespace
283
Note: See TracBrowser for help on using the browser.