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