21 #include "JackPosixThread.h"    22 #include "JackError.h"    24 #include "JackGlobals.h"    29 #define JACK_SCHED_POLICY SCHED_FIFO    34 void* JackPosixThread::ThreadHandler(
void* arg)
    36     JackPosixThread* obj = (JackPosixThread*)arg;
    37     JackRunnableInterface* runnable = obj->fRunnable;
    40     if ((err = pthread_setcanceltype(obj->fCancellation, NULL)) != 0) {
    41         jack_error(
"pthread_setcanceltype err = %s", strerror(err));
    45     jack_log(
"JackPosixThread::ThreadHandler : start");
    46     obj->fStatus = kIniting;
    49     if (!runnable->Init()) {
    54     obj->fStatus = kRunning;
    58     while (obj->fStatus == kRunning && res) {
    59         res = runnable->Execute();
    62     jack_log(
"JackPosixThread::ThreadHandler : exit");
    67 int JackPosixThread::Start()
    72     if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, 
this) < 0) {
    80 int JackPosixThread::StartSync()
    84     if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, 
this) < 0) {
    89         while (fStatus == kStarting && ++count < 1000) {
    92         return (count == 1000) ? -1 : 0;
    96 int JackPosixThread::StartImp(jack_native_thread_t* thread, 
int priority, 
int realtime, 
void*(*start_routine)(
void*), 
void* arg)
    98     pthread_attr_t attributes;
    99     struct sched_param rt_param;
   100     pthread_attr_init(&attributes);
   103     if ((res = pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_JOINABLE))) {
   104         jack_error(
"Cannot request joinable thread creation for thread res = %d", res);
   108     if ((res = pthread_attr_setscope(&attributes, PTHREAD_SCOPE_SYSTEM))) {
   109         jack_error(
"Cannot set scheduling scope for thread res = %d", res);
   115         jack_log(
"JackPosixThread::StartImp : create RT thread");
   117         if ((res = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED))) {
   118             jack_error(
"Cannot request explicit scheduling for RT thread res = %d", res);
   122         if ((res = pthread_attr_setschedpolicy(&attributes, JACK_SCHED_POLICY))) {
   123             jack_error(
"Cannot set RR scheduling class for RT thread res = %d", res);
   127         memset(&rt_param, 0, 
sizeof(rt_param));
   128         rt_param.sched_priority = priority;
   130         if ((res = pthread_attr_setschedparam(&attributes, &rt_param))) {
   131             jack_error(
"Cannot set scheduling priority for RT thread res = %d", res);
   136         jack_log(
"JackPosixThread::StartImp : create non RT thread");
   139     if ((res = pthread_attr_setstacksize(&attributes, THREAD_STACK))) {
   140         jack_error(
"Cannot set thread stack size res = %d", res);
   144     if ((res = JackGlobals::fJackThreadCreator(thread, &attributes, start_routine, arg))) {
   145         jack_error(
"Cannot create thread res = %d", res);
   149     pthread_attr_destroy(&attributes);
   153 int JackPosixThread::Kill()
   155     if (fThread != (jack_native_thread_t)NULL) { 
   158         pthread_cancel(fThread);
   159         pthread_join(fThread, &status);
   161         fThread = (jack_native_thread_t)NULL;
   168 int JackPosixThread::Stop()
   170     if (fThread != (jack_native_thread_t)NULL) { 
   174         pthread_join(fThread, &status);
   175         fThread = (jack_native_thread_t)NULL;
   182 int JackPosixThread::KillImp(jack_native_thread_t thread)
   184     if (thread != (jack_native_thread_t)NULL) { 
   187         pthread_cancel(thread);
   188         pthread_join(thread, &status);
   195 int JackPosixThread::StopImp(jack_native_thread_t thread)
   197     if (thread != (jack_native_thread_t)NULL) { 
   200         pthread_join(thread, &status);
   207 int JackPosixThread::AcquireRealTime()
   209     return (fThread != (jack_native_thread_t)NULL) ? AcquireRealTimeImp(fThread, fPriority) : -1;
   212 int JackPosixThread::AcquireSelfRealTime()
   214     return AcquireRealTimeImp(pthread_self(), fPriority);
   217 int JackPosixThread::AcquireRealTime(
int priority)
   219     fPriority = priority;
   220     return AcquireRealTime();
   223 int JackPosixThread::AcquireSelfRealTime(
int priority)
   225     fPriority = priority;
   226     return AcquireSelfRealTime();
   228 int JackPosixThread::AcquireRealTimeImp(jack_native_thread_t thread, 
int priority)
   230     struct sched_param rtparam;
   232     memset(&rtparam, 0, 
sizeof(rtparam));
   233     rtparam.sched_priority = priority;
   235     jack_log(
"JackPosixThread::AcquireRealTimeImp priority = %d", priority);
   237     if ((res = pthread_setschedparam(thread, JACK_SCHED_POLICY, &rtparam)) != 0) {
   238         jack_error(
"Cannot use real-time scheduling (RR/%d)"   239                    "(%d: %s)", rtparam.sched_priority, res,
   246 int JackPosixThread::DropRealTime()
   248     return (fThread != (jack_native_thread_t)NULL) ? DropRealTimeImp(fThread) : -1;
   251 int JackPosixThread::DropSelfRealTime()
   253     return DropRealTimeImp(pthread_self());
   256 int JackPosixThread::DropRealTimeImp(jack_native_thread_t thread)
   258     struct sched_param rtparam;
   260     memset(&rtparam, 0, 
sizeof(rtparam));
   261     rtparam.sched_priority = 0;
   263     if ((res = pthread_setschedparam(thread, SCHED_OTHER, &rtparam)) != 0) {
   264         jack_error(
"Cannot switch to normal scheduling priority(%s)", strerror(errno));
   270 jack_native_thread_t JackPosixThread::GetThreadID()
   275 bool JackPosixThread::IsThread()
   277     return pthread_self() == fThread;
   280 void JackPosixThread::Terminate()
   282     jack_log(
"JackPosixThread::Terminate");
   286 SERVER_EXPORT 
void ThreadExit()
   294 bool jack_get_thread_realtime_priority_range(
int * min_ptr, 
int * max_ptr)
   296 #if defined(_POSIX_PRIORITY_SCHEDULING) && !defined(__APPLE__)   299     min = sched_get_priority_min(JACK_SCHED_POLICY);
   302         jack_error(
"sched_get_priority_min() failed.");
   306     max = sched_get_priority_max(JACK_SCHED_POLICY);
   309         jack_error(
"sched_get_priority_max() failed.");
   322 bool jack_tls_allocate_key(jack_tls_key *key_ptr)
   326     ret = pthread_key_create(key_ptr, NULL);
   329         jack_error(
"pthread_key_create() failed with error %d", ret);
   336 bool jack_tls_free_key(jack_tls_key key)
   340     ret = pthread_key_delete(key);
   343         jack_error(
"pthread_key_delete() failed with error %d", ret);
   350 bool jack_tls_set(jack_tls_key key, 
void *data_ptr)
   354     ret = pthread_setspecific(key, (
const void *)data_ptr);
   357         jack_error(
"pthread_setspecific() failed with error %d", ret);
   364 void *jack_tls_get(jack_tls_key key)
   366     return pthread_getspecific(key);
 SERVER_EXPORT void jack_error(const char *fmt,...)
SERVER_EXPORT void jack_log(const char *fmt,...)