00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "JackPosixThread.h"
00022 #include "JackError.h"
00023 #include <string.h>
00024
00025 namespace Jack
00026 {
00027
00028 void* JackPosixThread::ThreadHandler(void* arg)
00029 {
00030 JackPosixThread* obj = (JackPosixThread*)arg;
00031 JackRunnableInterface* runnable = obj->fRunnable;
00032 int err;
00033
00034 if ((err = pthread_setcanceltype(obj->fCancellation, NULL)) != 0) {
00035 jack_error("pthread_setcanceltype err = %s", strerror(err));
00036 }
00037
00038
00039 if (!runnable->Init()) {
00040 jack_error("Thread init fails: thread quits");
00041 return 0;
00042 }
00043
00044 JackLog("ThreadHandler: start\n");
00045
00046
00047 bool res = true;
00048 while (obj->fRunning && res) {
00049 res = runnable->Execute();
00050
00051 }
00052
00053 JackLog("ThreadHandler: exit\n");
00054 return 0;
00055 }
00056
00057 int JackPosixThread::Start()
00058 {
00059 int res;
00060 fRunning = true;
00061
00062 if (fRealTime) {
00063
00064 JackLog("Create RT thread\n");
00065
00066
00067
00068
00069 pthread_attr_t attributes;
00070 struct sched_param rt_param;
00071 pthread_attr_init(&attributes);
00072
00073 if ((res = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED))) {
00074 jack_error("Cannot request explicit scheduling for RT thread %d %s", res, strerror(errno));
00075 return -1;
00076 }
00077
00078 if ((res = pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_JOINABLE))) {
00079 jack_error("Cannot request joinable thread creation for RT thread %d %s", res, strerror(errno));
00080 return -1;
00081 }
00082
00083 if ((res = pthread_attr_setscope(&attributes, PTHREAD_SCOPE_SYSTEM))) {
00084 jack_error("Cannot set scheduling scope for RT thread %d %s", res, strerror(errno));
00085 return -1;
00086 }
00087
00088
00089
00090 if ((res = pthread_attr_setschedpolicy(&attributes, SCHED_RR))) {
00091 jack_error("Cannot set FIFO scheduling class for RT thread %d %s", res, strerror(errno));
00092 return -1;
00093 }
00094
00095 if ((res = pthread_attr_setscope(&attributes, PTHREAD_SCOPE_SYSTEM))) {
00096 jack_error("Cannot set scheduling scope for RT thread %d %s", res, strerror(errno));
00097 return -1;
00098 }
00099
00100 memset(&rt_param, 0, sizeof(rt_param));
00101 rt_param.sched_priority = fPriority;
00102
00103 if ((res = pthread_attr_setschedparam(&attributes, &rt_param))) {
00104 jack_error("Cannot set scheduling priority for RT thread %d %s", res, strerror(errno));
00105 return -1;
00106 }
00107
00108 if ((res = pthread_create(&fThread, &attributes, ThreadHandler, this))) {
00109 jack_error("Cannot set create thread %d %s", res, strerror(errno));
00110 return -1;
00111 }
00112
00113 return 0;
00114 } else {
00115 JackLog("Create non RT thread\n");
00116
00117 if ((res = pthread_create(&fThread, 0, ThreadHandler, this))) {
00118 jack_error("Cannot set create thread %d %s", res, strerror(errno));
00119 return -1;
00120 }
00121 return 0;
00122 }
00123 }
00124
00125 int JackPosixThread::StartSync()
00126 {
00127 jack_error("Not implemented yet");
00128 return -1;
00129 }
00130
00131 int JackPosixThread::Kill()
00132 {
00133 if (fThread) {
00134 JackLog("JackPosixThread::Kill\n");
00135 void* status;
00136 pthread_cancel(fThread);
00137 pthread_join(fThread, &status);
00138 fRunning = false;
00139 fThread = (pthread_t)NULL;
00140 return 0;
00141 } else {
00142 return -1;
00143 }
00144 }
00145
00146 int JackPosixThread::Stop()
00147 {
00148 if (fThread) {
00149 JackLog("JackPosixThread::Stop\n");
00150 void* status;
00151 fRunning = false;
00152 pthread_join(fThread, &status);
00153 fThread = (pthread_t)NULL;
00154 return 0;
00155 } else {
00156 return -1;
00157 }
00158 }
00159
00160 int JackPosixThread::AcquireRealTime()
00161 {
00162 struct sched_param rtparam;
00163 int res;
00164
00165 if (!fThread)
00166 return -1;
00167
00168 memset(&rtparam, 0, sizeof(rtparam));
00169 rtparam.sched_priority = fPriority;
00170
00171
00172
00173 if ((res = pthread_setschedparam(fThread, SCHED_RR, &rtparam)) != 0) {
00174 jack_error("Cannot use real-time scheduling (FIFO/%d) "
00175 "(%d: %s)", rtparam.sched_priority, res,
00176 strerror(res));
00177 return -1;
00178 }
00179 return 0;
00180 }
00181
00182 int JackPosixThread::AcquireRealTime(int priority)
00183 {
00184 fPriority = priority;
00185 return AcquireRealTime();
00186 }
00187
00188 int JackPosixThread::DropRealTime()
00189 {
00190 struct sched_param rtparam;
00191 int res;
00192
00193 if (!fThread)
00194 return -1;
00195
00196 memset(&rtparam, 0, sizeof(rtparam));
00197 rtparam.sched_priority = 0;
00198
00199 if ((res = pthread_setschedparam(fThread, SCHED_OTHER, &rtparam)) != 0) {
00200 jack_error("Cannot switch to normal scheduling priority(%s)\n", strerror(errno));
00201 return -1;
00202 }
00203 return 0;
00204 }
00205
00206 pthread_t JackPosixThread::GetThreadID()
00207 {
00208 return fThread;
00209 }
00210
00211 }
00212