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 jack_log("JackMachThread::thread_policy_set res = %ld", 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 jack_log("JackMachThread::thread_policy_set res = %ld", 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(pthread_t thread, 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(thread),
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 jack_log("JackMachThread::GetParams period = %ld computation = %ld constraint = %ld", 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 jack_log("JackMachThread::Kill");
00147
00148 if (fThread != (pthread_t)NULL) {
00149 mach_port_t machThread = pthread_mach_thread_np(fThread);
00150 int res = (thread_terminate(machThread) == KERN_SUCCESS) ? 0 : -1;
00151 fThread = (pthread_t)NULL;
00152 return res;
00153 } else {
00154 return -1;
00155 }
00156 }
00157
00158 int JackMachThread::AcquireRealTime()
00159 {
00160 jack_log("JackMachThread::AcquireRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld",
00161 long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000));
00162 return (fThread != (pthread_t)NULL) ? AcquireRealTimeImp(fThread, fPeriod, fComputation, fConstraint) : -1;
00163 }
00164
00165 int JackMachThread::AcquireSelfRealTime()
00166 {
00167 jack_log("JackMachThread::AcquireRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld",
00168 long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000));
00169 return AcquireRealTimeImp(pthread_self(), fPeriod, fComputation, fConstraint);
00170 }
00171
00172 int JackMachThread::AcquireRealTime(int priority)
00173 {
00174 fPriority = priority;
00175 return AcquireRealTime();
00176 }
00177
00178 int JackMachThread::AcquireSelfRealTime(int priority)
00179 {
00180 fPriority = priority;
00181 return AcquireSelfRealTime();
00182 }
00183
00184 int JackMachThread::AcquireRealTimeImp(pthread_t thread, UInt64 period, UInt64 computation, UInt64 constraint)
00185 {
00186 SetThreadToPriority(thread, 96, true, period, computation, constraint);
00187 return 0;
00188 }
00189
00190 int JackMachThread::DropRealTime()
00191 {
00192 return (fThread != (pthread_t)NULL) ? DropRealTimeImp(fThread) : -1;
00193 }
00194
00195 int JackMachThread::DropSelfRealTime()
00196 {
00197 return DropRealTimeImp(pthread_self());
00198 }
00199
00200 int JackMachThread::DropRealTimeImp(pthread_t thread)
00201 {
00202 SetThreadToPriority(thread, 63, false, 0, 0, 0);
00203 return 0;
00204 }
00205
00206 void JackMachThread::SetParams(UInt64 period, UInt64 computation, UInt64 constraint)
00207 {
00208 fPeriod = period;
00209 fComputation = computation;
00210 fConstraint = constraint;
00211 }
00212
00213 }
00214