this repo has no description
at fixPythonPipStalling 335 lines 12 kB view raw
1/* Copyright: � Copyright 2005 Apple Computer, Inc. All rights reserved. 2 3 Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. 4 ("Apple") in consideration of your agreement to the following terms, and your 5 use, installation, modification or redistribution of this Apple software 6 constitutes acceptance of these terms. If you do not agree with these terms, 7 please do not use, install, modify or redistribute this Apple software. 8 9 In consideration of your agreement to abide by the following terms, and subject 10 to these terms, Apple grants you a personal, non-exclusive license, under Apple�s 11 copyrights in this original Apple software (the "Apple Software"), to use, 12 reproduce, modify and redistribute the Apple Software, with or without 13 modifications, in source and/or binary forms; provided that if you redistribute 14 the Apple Software in its entirety and without modifications, you must retain 15 this notice and the following text and disclaimers in all such redistributions of 16 the Apple Software. Neither the name, trademarks, service marks or logos of 17 Apple Computer, Inc. may be used to endorse or promote products derived from the 18 Apple Software without specific prior written permission from Apple. Except as 19 expressly stated in this notice, no other rights or licenses, express or implied, 20 are granted by Apple herein, including but not limited to any patent rights that 21 may be infringed by your derivative works or by other works in which the Apple 22 Software may be incorporated. 23 24 The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO 25 WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED 26 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR 27 PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN 28 COMBINATION WITH YOUR PRODUCTS. 29 30 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR 31 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 32 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION 34 OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT 35 (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN 36 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37*/ 38/*============================================================================= 39 CAPThread.cp 40 41=============================================================================*/ 42 43//============================================================================= 44// Includes 45//============================================================================= 46 47// Self Include 48#include "CAPThread.h" 49 50// PublicUtility Includes 51#include "CADebugMacros.h" 52#include "CAException.h" 53 54// System Includes 55#if TARGET_OS_MAC 56 #include <mach/mach.h> 57#endif 58 59// Standard Library Includes 60#include <stdio.h> 61 62//================================================================================================== 63// CAPThread 64//================================================================================================== 65 66// returns the thread's priority as it was last set by the API 67#define CAPTHREAD_SET_PRIORITY 0 68// returns the thread's priority as it was last scheduled by the Kernel 69#define CAPTHREAD_SCHEDULED_PRIORITY 1 70 71CAPThread::CAPThread(ThreadRoutine inThreadRoutine, void* inParameter, UInt32 inPriority, bool inFixedPriority) 72: 73#if TARGET_OS_MAC 74 mPThread(0), 75 mSpawningThreadPriority(getScheduledPriority(pthread_self(), CAPTHREAD_SET_PRIORITY)), 76#elif TARGET_OS_WIN32 77 mThreadHandle(NULL), 78 mThreadID(0), 79#endif 80 mThreadRoutine(inThreadRoutine), 81 mThreadParameter(inParameter), 82 mPriority(inPriority), 83 mPeriod(0), 84 mComputation(0), 85 mConstraint(0), 86 mIsPreemptible(true), 87 mTimeConstraintSet(false), 88 mFixedPriority(inFixedPriority) 89{ 90} 91 92CAPThread::CAPThread(ThreadRoutine inThreadRoutine, void* inParameter, UInt32 inPeriod, UInt32 inComputation, UInt32 inConstraint, bool inIsPreemptible) 93: 94#if TARGET_OS_MAC 95 mPThread(0), 96 mSpawningThreadPriority(getScheduledPriority(pthread_self(), CAPTHREAD_SET_PRIORITY)), 97#elif TARGET_OS_WIN32 98 mThreadHandle(NULL), 99 mThreadID(0), 100#endif 101 mThreadRoutine(inThreadRoutine), 102 mThreadParameter(inParameter), 103 mPriority(kDefaultThreadPriority), 104 mPeriod(inPeriod), 105 mComputation(inComputation), 106 mConstraint(inConstraint), 107 mIsPreemptible(inIsPreemptible), 108 mTimeConstraintSet(true), 109 mFixedPriority(false) 110{ 111} 112 113CAPThread::~CAPThread() 114{ 115} 116 117UInt32 CAPThread::GetScheduledPriority() 118{ 119#if TARGET_OS_MAC 120 return CAPThread::getScheduledPriority( mPThread, CAPTHREAD_SCHEDULED_PRIORITY ); 121#elif TARGET_OS_WIN32 122 UInt32 theAnswer = 0; 123 if(mThreadHandle != NULL) 124 { 125 theAnswer = GetThreadPriority(mThreadHandle); 126 } 127 return theAnswer; 128#endif 129} 130 131void CAPThread::SetPriority(UInt32 inPriority, bool inFixedPriority) 132{ 133 mPriority = inPriority; 134 mTimeConstraintSet = false; 135 mFixedPriority = inFixedPriority; 136#if TARGET_OS_MAC 137 if(mPThread != 0) 138 { 139 140 if (mFixedPriority) 141 { 142 thread_extended_policy_data_t theFixedPolicy; 143 theFixedPolicy.timeshare = false; // set to true for a non-fixed thread 144 AssertNoError(thread_policy_set(pthread_mach_thread_np(mPThread), THREAD_EXTENDED_POLICY, (thread_policy_t)&theFixedPolicy, THREAD_EXTENDED_POLICY_COUNT), "CAPThread::SetPriority: failed to set the fixed-priority policy"); 145 } 146 // We keep a reference to the spawning thread's priority around (initialized in the constructor), 147 // and set the importance of the child thread relative to the spawning thread's priority. 148 thread_precedence_policy_data_t thePrecedencePolicy; 149 150 thePrecedencePolicy.importance = mPriority - mSpawningThreadPriority; 151 AssertNoError(thread_policy_set(pthread_mach_thread_np(mPThread), THREAD_PRECEDENCE_POLICY, (thread_policy_t)&thePrecedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT), "CAPThread::SetPriority: failed to set the precedence policy"); 152 } 153#elif TARGET_OS_WIN32 154 if(mThreadHandle != NULL) 155 { 156 SetThreadPriority(mThreadHandle, mPriority); 157 } 158#endif 159} 160 161void CAPThread::SetTimeConstraints(UInt32 inPeriod, UInt32 inComputation, UInt32 inConstraint, bool inIsPreemptible) 162{ 163 mPeriod = inPeriod; 164 mComputation = inComputation; 165 mConstraint = inConstraint; 166 mIsPreemptible = inIsPreemptible; 167 mTimeConstraintSet = true; 168#if TARGET_OS_MAC 169 if(mPThread != 0) 170 { 171 thread_time_constraint_policy_data_t thePolicy; 172 thePolicy.period = mPeriod; 173 thePolicy.computation = mComputation; 174 thePolicy.constraint = mConstraint; 175 thePolicy.preemptible = mIsPreemptible; 176 AssertNoError(thread_policy_set(pthread_mach_thread_np(mPThread), THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t)&thePolicy, THREAD_TIME_CONSTRAINT_POLICY_COUNT), "CAPThread::SetTimeConstraints: thread_policy_set failed"); 177 } 178#elif TARGET_OS_WIN32 179 if(mThreadHandle != NULL) 180 { 181 SetThreadPriority(mThreadHandle, THREAD_PRIORITY_TIME_CRITICAL); 182 } 183#endif 184} 185 186void CAPThread::Start() 187{ 188#if TARGET_OS_MAC 189 if(mPThread == 0) 190 { 191 OSStatus theResult; 192 pthread_attr_t theThreadAttributes; 193 194 theResult = pthread_attr_init(&theThreadAttributes); 195 ThrowIf(theResult != 0, CAException(theResult), "CAPThread::Start: Thread attributes could not be created."); 196 197 theResult = pthread_attr_setdetachstate(&theThreadAttributes, PTHREAD_CREATE_DETACHED); 198 ThrowIf(theResult != 0, CAException(theResult), "CAPThread::Start: A thread could not be created in the detached state."); 199 200 theResult = pthread_create(&mPThread, &theThreadAttributes, (ThreadRoutine)CAPThread::Entry, this); 201 ThrowIf(theResult != 0 || !mPThread, CAException(theResult), "CAPThread::Start: Could not create a thread."); 202 203 pthread_attr_destroy(&theThreadAttributes); 204 205 } 206#elif TARGET_OS_WIN32 207 if(mThreadID == 0) 208 { 209 // clean up the existing thread handle 210 if(mThreadHandle != NULL) 211 { 212 CloseHandle(mThreadHandle); 213 mThreadHandle = NULL; 214 } 215 216 // create a new thread 217 mThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Entry, this, 0, &mThreadID); 218 ThrowIf(mThreadHandle == NULL, CAException(GetLastError()), "CAPThread::Start: Could not create a thread."); 219 } 220#endif 221} 222 223#if TARGET_OS_MAC 224 225void* CAPThread::Entry(CAPThread* inCAPThread) 226{ 227 void* theAnswer = NULL; 228 229 try 230 { 231 if(inCAPThread->mTimeConstraintSet) 232 { 233 inCAPThread->SetTimeConstraints(inCAPThread->mPeriod, inCAPThread->mComputation, inCAPThread->mConstraint, inCAPThread->mIsPreemptible); 234 } 235 else 236 { 237 inCAPThread->SetPriority(inCAPThread->mPriority, inCAPThread->mFixedPriority); 238 } 239 240 if(inCAPThread->mThreadRoutine != NULL) 241 { 242 theAnswer = inCAPThread->mThreadRoutine(inCAPThread->mThreadParameter); 243 } 244 } 245 catch (...) 246 { 247 // what should be done here? 248 } 249 inCAPThread->mPThread = 0; 250 return theAnswer; 251} 252 253UInt32 CAPThread::getScheduledPriority(pthread_t inThread, int inPriorityKind) 254{ 255 thread_basic_info_data_t threadInfo; 256 policy_info_data_t thePolicyInfo; 257 unsigned int count; 258 259 if (inThread == NULL) 260 return 0; 261 262 // get basic info 263 count = THREAD_BASIC_INFO_COUNT; 264 thread_info (pthread_mach_thread_np (inThread), THREAD_BASIC_INFO, (thread_info_t)&threadInfo, &count); 265 266 switch (threadInfo.policy) { 267 case POLICY_TIMESHARE: 268 count = POLICY_TIMESHARE_INFO_COUNT; 269 thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_TIMESHARE_INFO, (thread_info_t)&(thePolicyInfo.ts), &count); 270 if (inPriorityKind == CAPTHREAD_SCHEDULED_PRIORITY) { 271 return thePolicyInfo.ts.cur_priority; 272 } 273 return thePolicyInfo.ts.base_priority; 274 break; 275 276 case POLICY_FIFO: 277 count = POLICY_FIFO_INFO_COUNT; 278 thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_FIFO_INFO, (thread_info_t)&(thePolicyInfo.fifo), &count); 279 if ( (thePolicyInfo.fifo.depressed) && (inPriorityKind == CAPTHREAD_SCHEDULED_PRIORITY) ) { 280 return thePolicyInfo.fifo.depress_priority; 281 } 282 return thePolicyInfo.fifo.base_priority; 283 break; 284 285 case POLICY_RR: 286 count = POLICY_RR_INFO_COUNT; 287 thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_RR_INFO, (thread_info_t)&(thePolicyInfo.rr), &count); 288 if ( (thePolicyInfo.rr.depressed) && (inPriorityKind == CAPTHREAD_SCHEDULED_PRIORITY) ) { 289 return thePolicyInfo.rr.depress_priority; 290 } 291 return thePolicyInfo.rr.base_priority; 292 break; 293 } 294 295 return 0; 296} 297 298#elif TARGET_OS_WIN32 299 300UInt32 WINAPI CAPThread::Entry(CAPThread* inCAPThread) 301{ 302 UInt32 theAnswer = 0; 303 304 try 305 { 306 if(inCAPThread->mTimeConstraintSet) 307 { 308 inCAPThread->SetTimeConstraints(inCAPThread->mPeriod, inCAPThread->mComputation, inCAPThread->mConstraint, inCAPThread->mIsPreemptible); 309 } 310 else 311 { 312 inCAPThread->SetPriority(inCAPThread->mPriority, inCAPThread->mFixedPriority); 313 } 314 315 if(inCAPThread->mThreadRoutine != NULL) 316 { 317 theAnswer = reinterpret_cast<UInt32>(inCAPThread->mThreadRoutine(inCAPThread->mThreadParameter)); 318 } 319 inCAPThread->mThreadID = 0; 320 } 321 catch (...) 322 { 323 // what should be done here? 324 } 325 return theAnswer; 326} 327 328// a definition of this function here for now 329extern "C" 330Boolean CompareAndSwap(UInt32 inOldValue, UInt32 inNewValue, UInt32* inOldValuePtr) 331{ 332 return InterlockedCompareExchange((volatile LONG*)inOldValuePtr, inNewValue, inOldValue) == inOldValue; 333} 334 335#endif