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

Revision 742, 6.5 kB (checked in by ppalmers, 13 years ago)

- Remove some obsolete support files and dirs

- Clean up the license statements in the source files. Everything is

GPL version 3 now.

- Add license and copyright notices to scons scripts

- Clean up some other text files

Line 
1 /*
2  * Copyright (C) 2005-2007 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 3 of the License, or
12  * (at your option) any later version.
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) any later version.
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\n");
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\n");
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 with priority %d\n", 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\n");
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\n");
155         void* status;
156         pthread_cancel(fThread);
157         pthread_join(fThread, &status);
158         return 0;
159     } else {
160         return -1;
161     }
162 }
163
164 int PosixThread::Stop()
165 {
166     if (fThread) { // If thread has been started
167         debugOutput( DEBUG_LEVEL_VERBOSE, "PosixThread::Stop\n");
168         void* status;
169         fRunning = false; // Request for the thread to stop
170         pthread_join(fThread, &status);
171         return 0;
172     } else {
173         return -1;
174     }
175 }
176
177 int PosixThread::AcquireRealTime()
178 {
179     struct sched_param rtparam;
180     int res;
181
182     if (!fThread)
183         return -1;
184
185     memset(&rtparam, 0, sizeof(rtparam));
186     rtparam.sched_priority = fPriority;
187
188     //if ((res = pthread_setschedparam(fThread, SCHED_FIFO, &rtparam)) != 0) {
189
190     if ((res = pthread_setschedparam(fThread, SCHED_FIFO, &rtparam)) != 0) {
191         debugError("Cannot use real-time scheduling (FIFO/%d) "
192                    "(%d: %s)", rtparam.sched_priority, res,
193                    strerror(res));
194         return -1;
195     }
196     return 0;
197 }
198
199 int PosixThread::AcquireRealTime(int priority)
200 {
201     fPriority = priority;
202     return AcquireRealTime();
203 }
204
205 int PosixThread::DropRealTime()
206 {
207     struct sched_param rtparam;
208     int res;
209
210     if (!fThread)
211         return -1;
212
213     memset(&rtparam, 0, sizeof(rtparam));
214     rtparam.sched_priority = 0;
215
216     if ((res = pthread_setschedparam(fThread, SCHED_OTHER, &rtparam)) != 0) {
217         debugError("Cannot switch to normal scheduling priority(%s)\n", strerror(errno));
218         return -1;
219     }
220     return 0;
221 }
222
223 pthread_t PosixThread::GetThreadID()
224 {
225     return fThread;
226 }
227
228 } // end of namespace
229
Note: See TracBrowser for help on using the browser.