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
00164 jack_log("JackMachThread::Kill");
00165
00166 if (fThread != (jack_native_thread_t)NULL) {
00167 mach_port_t machThread = pthread_mach_thread_np(fThread);
00168 int res = (thread_terminate(machThread) == KERN_SUCCESS) ? 0 : -1;
00169 fThread = (jack_native_thread_t)NULL;
00170 return res;
00171 } else {
00172 return -1;
00173 }
00174 }
00175
00176 int JackMachThread::AcquireRealTime()
00177 {
00178 jack_log("JackMachThread::AcquireRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld",
00179 long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000));
00180 return (fThread != (jack_native_thread_t)NULL) ? AcquireRealTimeImp(fThread, fPeriod, fComputation, fConstraint) : -1;
00181 }
00182
00183 int JackMachThread::AcquireSelfRealTime()
00184 {
00185 jack_log("JackMachThread::AcquireSelfRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld",
00186 long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000));
00187 return AcquireRealTimeImp(pthread_self(), fPeriod, fComputation, fConstraint);
00188 }
00189
00190 int JackMachThread::AcquireRealTime(int priority)
00191 {
00192 fPriority = priority;
00193 return AcquireRealTime();
00194 }
00195
00196 int JackMachThread::AcquireSelfRealTime(int priority)
00197 {
00198 fPriority = priority;
00199 return AcquireSelfRealTime();
00200 }
00201
00202 int JackMachThread::AcquireRealTimeImp(jack_native_thread_t thread, UInt64 period, UInt64 computation, UInt64 constraint)
00203 {
00204 SetThreadToPriority(thread, 96, true, period, computation, constraint);
00205 return 0;
00206 }
00207
00208 int JackMachThread::DropRealTime()
00209 {
00210 return (fThread != (jack_native_thread_t)NULL) ? DropRealTimeImp(fThread) : -1;
00211 }
00212
00213 int JackMachThread::DropSelfRealTime()
00214 {
00215 return DropRealTimeImp(pthread_self());
00216 }
00217
00218 int JackMachThread::DropRealTimeImp(jack_native_thread_t thread)
00219 {
00220 SetThreadToPriority(thread, 63, false, 0, 0, 0);
00221 return 0;
00222 }
00223
00224 void JackMachThread::SetParams(UInt64 period, UInt64 computation, UInt64 constraint)
00225 {
00226 fPeriod = period;
00227 fComputation = computation;
00228 fConstraint = constraint;
00229 }
00230
00231 }
00232