00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "JackMachThread.h"
00023 #include "JackError.h"
00024
00025 #ifdef MY_TARGET_OS_IPHONE
00026 #include "/Developer/Extras/CoreAudio/PublicUtility/CAHostTimeBase.h"
00027 #endif
00028
00029 namespace Jack
00030 {
00031
00032 int JackMachThread::SetThreadToPriority(jack_native_thread_t thread, UInt32 inPriority, Boolean inIsFixed, UInt64 period, UInt64 computation, UInt64 constraint)
00033 {
00034 if (inPriority == 96) {
00035
00036 thread_time_constraint_policy_data_t theTCPolicy;
00037
00038 #ifdef MY_TARGET_OS_IPHONE
00039 theTCPolicy.period = CAHostTimeBase::ConvertFromNanos(period);
00040 theTCPolicy.computation = CAHostTimeBase::ConvertFromNanos(computation);
00041 theTCPolicy.constraint = CAHostTimeBase::ConvertFromNanos(constraint);
00042 #else
00043 theTCPolicy.period = AudioConvertNanosToHostTime(period);
00044 theTCPolicy.computation = AudioConvertNanosToHostTime(computation);
00045 theTCPolicy.constraint = AudioConvertNanosToHostTime(constraint);
00046 #endif
00047 theTCPolicy.preemptible = true;
00048 kern_return_t res = thread_policy_set(pthread_mach_thread_np(thread), THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t) &theTCPolicy, THREAD_TIME_CONSTRAINT_POLICY_COUNT);
00049 jack_log("JackMachThread::thread_policy_set res = %ld", res);
00050 return (res == KERN_SUCCESS) ? 0 : -1;
00051 } else {
00052
00053 thread_extended_policy_data_t theFixedPolicy;
00054 thread_precedence_policy_data_t thePrecedencePolicy;
00055 SInt32 relativePriority;
00056
00057
00058 theFixedPolicy.timeshare = !inIsFixed;
00059 thread_policy_set(pthread_mach_thread_np(thread), THREAD_EXTENDED_POLICY, (thread_policy_t)&theFixedPolicy, THREAD_EXTENDED_POLICY_COUNT);
00060
00061
00062
00063
00064
00065
00066
00067
00068 relativePriority = inPriority - GetThreadSetPriority(pthread_self());
00069
00070 thePrecedencePolicy.importance = relativePriority;
00071 kern_return_t res = thread_policy_set(pthread_mach_thread_np(thread), THREAD_PRECEDENCE_POLICY, (thread_policy_t) &thePrecedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT);
00072 jack_log("JackMachThread::thread_policy_set res = %ld", res);
00073 return (res == KERN_SUCCESS) ? 0 : -1;
00074 }
00075 }
00076
00077
00078 UInt32 JackMachThread::GetThreadSetPriority(jack_native_thread_t thread)
00079 {
00080 return GetThreadPriority(thread, THREAD_SET_PRIORITY);
00081 }
00082
00083
00084 UInt32 JackMachThread::GetThreadScheduledPriority(jack_native_thread_t thread)
00085 {
00086 return GetThreadPriority(thread, THREAD_SCHEDULED_PRIORITY);
00087 }
00088
00089 UInt32 JackMachThread::GetThreadPriority(jack_native_thread_t thread, int inWhichPriority)
00090 {
00091 thread_basic_info_data_t threadInfo;
00092 policy_info_data_t thePolicyInfo;
00093 unsigned int count;
00094
00095
00096 count = THREAD_BASIC_INFO_COUNT;
00097 thread_info(pthread_mach_thread_np(thread), THREAD_BASIC_INFO, (thread_info_t)&threadInfo, &count);
00098
00099 switch (threadInfo.policy) {
00100 case POLICY_TIMESHARE:
00101 count = POLICY_TIMESHARE_INFO_COUNT;
00102 thread_info(pthread_mach_thread_np(thread), THREAD_SCHED_TIMESHARE_INFO, (thread_info_t)&(thePolicyInfo.ts), &count);
00103 if (inWhichPriority == THREAD_SCHEDULED_PRIORITY) {
00104 return thePolicyInfo.ts.cur_priority;
00105 } else {
00106 return thePolicyInfo.ts.base_priority;
00107 }
00108 break;
00109
00110 case POLICY_FIFO:
00111 count = POLICY_FIFO_INFO_COUNT;
00112 thread_info(pthread_mach_thread_np(thread), THREAD_SCHED_FIFO_INFO, (thread_info_t)&(thePolicyInfo.fifo), &count);
00113 if ( (thePolicyInfo.fifo.depressed) && (inWhichPriority == THREAD_SCHEDULED_PRIORITY) ) {
00114 return thePolicyInfo.fifo.depress_priority;
00115 }
00116 return thePolicyInfo.fifo.base_priority;
00117 break;
00118
00119 case POLICY_RR:
00120 count = POLICY_RR_INFO_COUNT;
00121 thread_info(pthread_mach_thread_np(thread), THREAD_SCHED_RR_INFO, (thread_info_t)&(thePolicyInfo.rr), &count);
00122 if ( (thePolicyInfo.rr.depressed) && (inWhichPriority == THREAD_SCHEDULED_PRIORITY) ) {
00123 return thePolicyInfo.rr.depress_priority;
00124 }
00125 return thePolicyInfo.rr.base_priority;
00126 break;
00127 }
00128
00129 return 0;
00130 }
00131
00132 int JackMachThread::GetParams(jack_native_thread_t thread, UInt64* period, UInt64* computation, UInt64* constraint)
00133 {
00134 thread_time_constraint_policy_data_t theTCPolicy;
00135 mach_msg_type_number_t count = THREAD_TIME_CONSTRAINT_POLICY_COUNT;
00136 boolean_t get_default = false;
00137
00138 kern_return_t res = thread_policy_get(pthread_mach_thread_np(thread),
00139 THREAD_TIME_CONSTRAINT_POLICY,
00140 (thread_policy_t) & theTCPolicy,
00141 &count,
00142 &get_default);
00143 if (res == KERN_SUCCESS) {
00144 #ifdef MY_TARGET_OS_IPHONE
00145 *period = CAHostTimeBase::ConvertToNanos(theTCPolicy.period);
00146 *computation = CAHostTimeBase::ConvertToNanos(theTCPolicy.computation);
00147 *constraint = CAHostTimeBase::ConvertToNanos(theTCPolicy.constraint);
00148 #else
00149 *period = AudioConvertHostTimeToNanos(theTCPolicy.period);
00150 *computation = AudioConvertHostTimeToNanos(theTCPolicy.computation);
00151 *constraint = AudioConvertHostTimeToNanos(theTCPolicy.constraint);
00152 #endif
00153
00154 jack_log("JackMachThread::GetParams period = %ld computation = %ld constraint = %ld", long(*period / 1000.0f), long(*computation / 1000.0f), long(*constraint / 1000.0f));
00155 return 0;
00156 } else {
00157 return -1;
00158 }
00159 }
00160
00161 int JackMachThread::Kill()
00162 {
00163 if (fThread != (jack_native_thread_t)NULL) {
00164 jack_log("JackMachThread::Kill");
00165 mach_port_t machThread = pthread_mach_thread_np(fThread);
00166 int res = (thread_terminate(machThread) == KERN_SUCCESS) ? 0 : -1;
00167 fStatus = kIdle;
00168 fThread = (jack_native_thread_t)NULL;
00169 return res;
00170 } else {
00171 return -1;
00172 }
00173 }
00174
00175 int JackMachThread::AcquireRealTime()
00176 {
00177 jack_log("JackMachThread::AcquireRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld",
00178 long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000));
00179 return (fThread != (jack_native_thread_t)NULL) ? AcquireRealTimeImp(fThread, fPeriod, fComputation, fConstraint) : -1;
00180 }
00181
00182 int JackMachThread::AcquireSelfRealTime()
00183 {
00184 jack_log("JackMachThread::AcquireSelfRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld",
00185 long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000));
00186 return AcquireRealTimeImp(pthread_self(), fPeriod, fComputation, fConstraint);
00187 }
00188
00189 int JackMachThread::AcquireRealTime(int priority)
00190 {
00191 fPriority = priority;
00192 return AcquireRealTime();
00193 }
00194
00195 int JackMachThread::AcquireSelfRealTime(int priority)
00196 {
00197 fPriority = priority;
00198 return AcquireSelfRealTime();
00199 }
00200
00201 int JackMachThread::AcquireRealTimeImp(jack_native_thread_t thread, UInt64 period, UInt64 computation, UInt64 constraint)
00202 {
00203 SetThreadToPriority(thread, 96, true, period, computation, constraint);
00204 return 0;
00205 }
00206
00207 int JackMachThread::DropRealTime()
00208 {
00209 return (fThread != (jack_native_thread_t)NULL) ? DropRealTimeImp(fThread) : -1;
00210 }
00211
00212 int JackMachThread::DropSelfRealTime()
00213 {
00214 return DropRealTimeImp(pthread_self());
00215 }
00216
00217 int JackMachThread::DropRealTimeImp(jack_native_thread_t thread)
00218 {
00219 SetThreadToPriority(thread, 63, false, 0, 0, 0);
00220 return 0;
00221 }
00222
00223 void JackMachThread::SetParams(UInt64 period, UInt64 computation, UInt64 constraint)
00224 {
00225 fPeriod = period;
00226 fComputation = computation;
00227 fConstraint = constraint;
00228 }
00229
00230 }
00231