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

Revision 864, 6.7 kB (checked in by ppalmers, 15 years ago)

update license to GPLv2 or GPLv3 instead of GPLv2 or any later version. Update copyrights to reflect the new year

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
55 namespace Util
56 {
57
58 IMPL_DEBUG_MODULE( Thread, Thread, DEBUG_LEVEL_VERBOSE );
59
60 void* PosixThread::ThreadHandler(void* arg)
61 {
62     PosixThread* obj = (PosixThread*)arg;
63     RunnableInterface* runnable = obj->fRunnable;
64     int err;
65
66     if ((err = pthread_setcanceltype(obj->fCancellation, NULL)) != 0) {
67         debugError("pthread_setcanceltype err = %s", strerror(err));
68     }
69
70     // Call Init method
71     if (!runnable->Init()) {
72         debugError("Thread init fails: thread quits");
73         return 0;
74     }
75
76     debugOutput( DEBUG_LEVEL_VERBOSE, "ThreadHandler: start %p\n", obj);
77
78     // If Init succeed start the thread loop
79     bool res = true;
80     while (obj->fRunning && res) {
81         res = runnable->Execute();
82         //pthread_testcancel();
83     }
84
85     debugOutput( DEBUG_LEVEL_VERBOSE, "ThreadHandler: exit %p\n", obj);
86     return 0;
87 }
88
89 int PosixThread::Start()
90 {
91     int res;
92     fRunning = true;
93
94     if (fRealTime) {
95
96         debugOutput( DEBUG_LEVEL_VERBOSE, "Create RT thread %p with priority %d\n", this, fPriority);
97
98         /* Get the client thread to run as an RT-FIFO
99            scheduled thread of appropriate priority.
100         */
101         pthread_attr_t attributes;
102         struct sched_param rt_param;
103         pthread_attr_init(&attributes);
104
105         if ((res = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED))) {
106             debugError("Cannot request explicit scheduling for RT thread  %d %s", res, strerror(errno));
107             return -1;
108         }
109         if ((res = pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_JOINABLE))) {
110             debugError("Cannot request joinable thread creation for RT thread  %d %s", res, strerror(errno));
111             return -1;
112         }
113         if ((res = pthread_attr_setscope(&attributes, PTHREAD_SCOPE_SYSTEM))) {
114             debugError("Cannot set scheduling scope for RT thread %d %s", res, strerror(errno));
115             return -1;
116         }
117
118         if ((res = pthread_attr_setschedpolicy(&attributes, SCHED_FIFO))) {
119
120         //if ((res = pthread_attr_setschedpolicy(&attributes, SCHED_RR))) {
121             debugError("Cannot set FIFO scheduling class for RT thread  %d %s", res, strerror(errno));
122             return -1;
123         }
124
125         memset(&rt_param, 0, sizeof(rt_param));
126         rt_param.sched_priority = fPriority;
127
128         if ((res = pthread_attr_setschedparam(&attributes, &rt_param))) {
129             debugError("Cannot set scheduling priority for RT thread %d %s", res, strerror(errno));
130             return -1;
131         }
132
133         if ((res = pthread_create(&fThread, &attributes, ThreadHandler, this))) {
134             debugError("Cannot set create thread %d %s", res, strerror(errno));
135             return -1;
136         }
137
138         return 0;
139     } else {
140         debugOutput( DEBUG_LEVEL_VERBOSE, "Create non RT thread %p\n", this);
141
142         if ((res = pthread_create(&fThread, 0, ThreadHandler, this))) {
143             debugError("Cannot set create thread %d %s", res, strerror(errno));
144             return -1;
145         }
146
147         return 0;
148     }
149 }
150
151 int PosixThread::Kill()
152 {
153     if (fThread) { // If thread has been started
154         debugOutput( DEBUG_LEVEL_VERBOSE, "PosixThread::Kill %p\n", this);
155         void* status;
156         pthread_cancel(fThread);
157         pthread_join(fThread, &status);
158         debugOutput( DEBUG_LEVEL_VERBOSE, "PosixThread::Killed %p\n", this);
159         return 0;
160     } else {
161         return -1;
162     }
163 }
164
165 int PosixThread::Stop()
166 {
167     if (fThread) { // If thread has been started
168         debugOutput( DEBUG_LEVEL_VERBOSE, "PosixThread::Stop %p\n", this);
169         void* status;
170         fRunning = false; // Request for the thread to stop
171         pthread_join(fThread, &status);
172         debugOutput( DEBUG_LEVEL_VERBOSE, "PosixThread::Stopped %p\n", this);
173         return 0;
174     } else {
175         return -1;
176     }
177 }
178
179 int PosixThread::AcquireRealTime()
180 {
181     struct sched_param rtparam;
182     int res;
183
184     if (!fThread)
185         return -1;
186
187     memset(&rtparam, 0, sizeof(rtparam));
188     rtparam.sched_priority = fPriority;
189
190     //if ((res = pthread_setschedparam(fThread, SCHED_FIFO, &rtparam)) != 0) {
191
192     if ((res = pthread_setschedparam(fThread, SCHED_FIFO, &rtparam)) != 0) {
193         debugError("Cannot use real-time scheduling (FIFO/%d) "
194                    "(%d: %s)", rtparam.sched_priority, res,
195                    strerror(res));
196         return -1;
197     }
198     return 0;
199 }
200
201 int PosixThread::AcquireRealTime(int priority)
202 {
203     fPriority = priority;
204     return AcquireRealTime();
205 }
206
207 int PosixThread::DropRealTime()
208 {
209     struct sched_param rtparam;
210     int res;
211
212     if (!fThread)
213         return -1;
214
215     memset(&rtparam, 0, sizeof(rtparam));
216     rtparam.sched_priority = 0;
217
218     if ((res = pthread_setschedparam(fThread, SCHED_OTHER, &rtparam)) != 0) {
219         debugError("Cannot switch to normal scheduling priority(%s)\n", strerror(errno));
220         return -1;
221     }
222     return 0;
223 }
224
225 pthread_t PosixThread::GetThreadID()
226 {
227     return fThread;
228 }
229
230 } // end of namespace
231
Note: See TracBrowser for help on using the browser.