Changeset 391 for python/trunk/Python/thread_pthread.h
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Python/thread_pthread.h
r2 r391 17 17 #ifdef _POSIX_THREAD_ATTR_STACKSIZE 18 18 #ifndef THREAD_STACK_SIZE 19 #define THREAD_STACK_SIZE 0 /* use default stack size */ 19 #define THREAD_STACK_SIZE 0 /* use default stack size */ 20 #endif 21 22 #if (defined(__APPLE__) || defined(__FreeBSD__)) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 23 /* The default stack size for new threads on OSX is small enough that 24 * we'll get hard crashes instead of 'maximum recursion depth exceeded' 25 * exceptions. 26 * 27 * The default stack size below is the minimal stack size where a 28 * simple recursive function doesn't cause a hard crash. 29 */ 30 #undef THREAD_STACK_SIZE 31 #define THREAD_STACK_SIZE 0x400000 20 32 #endif 21 33 /* for safety, ensure a viable minimum stacksize */ 22 #define THREAD_STACK_MIN 0x8000/* 32kB */34 #define THREAD_STACK_MIN 0x8000 /* 32kB */ 23 35 #else /* !_POSIX_THREAD_ATTR_STACKSIZE */ 24 36 #ifdef THREAD_STACK_SIZE … … 29 41 /* The POSIX spec says that implementations supporting the sem_* 30 42 family of functions must indicate this by defining 31 _POSIX_SEMAPHORES. */ 43 _POSIX_SEMAPHORES. */ 32 44 #ifdef _POSIX_SEMAPHORES 33 /* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so 45 /* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so 34 46 we need to add 0 to make it work there as well. */ 35 47 #if (_POSIX_SEMAPHORES+0) == -1 … … 100 112 101 113 typedef struct { 102 103 104 105 114 char locked; /* 0=unlocked, 1=locked */ 115 /* a <cond, mutex> pair to handle an acquire of a locked lock */ 116 pthread_cond_t lock_released; 117 pthread_mutex_t mut; 106 118 } pthread_lock; 107 119 … … 121 133 PyThread__init_thread(void) 122 134 { 123 124 125 126 127 135 /* DO AN INIT BY STARTING THE THREAD */ 136 static int dummy = 0; 137 pthread_t thread1; 138 pthread_create(&thread1, NULL, (void *) _noop, &dummy); 139 pthread_join(thread1, NULL); 128 140 } 129 141 … … 134 146 { 135 147 #if defined(_AIX) && defined(__GNUC__) 136 pthread_init(); 148 extern void pthread_init(void); 149 pthread_init(); 137 150 #endif 138 151 } … … 148 161 PyThread_start_new_thread(void (*func)(void *), void *arg) 149 162 { 150 151 163 pthread_t th; 164 int status; 152 165 #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) 153 166 pthread_attr_t attrs; 154 167 #endif 155 168 #if defined(THREAD_STACK_SIZE) 156 size_ttss;157 #endif 158 159 160 161 169 size_t tss; 170 #endif 171 172 dprintf(("PyThread_start_new_thread called\n")); 173 if (!initialized) 174 PyThread_init_thread(); 162 175 163 176 #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) 164 165 177 if (pthread_attr_init(&attrs) != 0) 178 return -1; 166 179 #endif 167 180 #if defined(THREAD_STACK_SIZE) 168 169 170 171 172 173 174 175 181 tss = (_pythread_stacksize != 0) ? _pythread_stacksize 182 : THREAD_STACK_SIZE; 183 if (tss != 0) { 184 if (pthread_attr_setstacksize(&attrs, tss) != 0) { 185 pthread_attr_destroy(&attrs); 186 return -1; 187 } 188 } 176 189 #endif 177 190 #if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) 178 179 #endif 180 181 status = pthread_create(&th, 191 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM); 192 #endif 193 194 status = pthread_create(&th, 182 195 #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) 183 184 #else 185 186 #endif 187 188 189 196 &attrs, 197 #else 198 (pthread_attr_t*)NULL, 199 #endif 200 (void* (*)(void *))func, 201 (void *)arg 202 ); 190 203 191 204 #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) 192 193 #endif 194 195 196 197 205 pthread_attr_destroy(&attrs); 206 #endif 207 if (status != 0) 208 return -1; 209 210 pthread_detach(th); 198 211 199 212 #if SIZEOF_PTHREAD_T <= SIZEOF_LONG 200 201 #else 202 213 return (long) th; 214 #else 215 return (long) *(long *) &th; 203 216 #endif 204 217 } … … 211 224 latter return statement (for Alpha OSF/1) are any longer necessary. 212 225 */ 213 long 226 long 214 227 PyThread_get_thread_ident(void) 215 228 { 216 217 218 219 220 229 volatile pthread_t threadid; 230 if (!initialized) 231 PyThread_init_thread(); 232 /* Jump through some hoops for Alpha OSF/1 */ 233 threadid = pthread_self(); 221 234 #if SIZEOF_PTHREAD_T <= SIZEOF_LONG 222 return (long) threadid; 223 #else 224 return (long) *(long *) &threadid; 225 #endif 226 } 227 228 static void 229 do_PyThread_exit_thread(int no_cleanup) 230 { 231 dprintf(("PyThread_exit_thread called\n")); 232 if (!initialized) { 233 if (no_cleanup) 234 _exit(0); 235 else 236 exit(0); 237 } 238 } 239 240 void 235 return (long) threadid; 236 #else 237 return (long) *(long *) &threadid; 238 #endif 239 } 240 241 void 241 242 PyThread_exit_thread(void) 242 243 { 243 do_PyThread_exit_thread(0); 244 } 245 246 void 247 PyThread__exit_thread(void) 248 { 249 do_PyThread_exit_thread(1); 250 } 251 252 #ifndef NO_EXIT_PROG 253 static void 254 do_PyThread_exit_prog(int status, int no_cleanup) 255 { 256 dprintf(("PyThread_exit_prog(%d) called\n", status)); 257 if (!initialized) 258 if (no_cleanup) 259 _exit(status); 260 else 261 exit(status); 262 } 263 264 void 265 PyThread_exit_prog(int status) 266 { 267 do_PyThread_exit_prog(status, 0); 268 } 269 270 void 271 PyThread__exit_prog(int status) 272 { 273 do_PyThread_exit_prog(status, 1); 274 } 275 #endif /* NO_EXIT_PROG */ 244 dprintf(("PyThread_exit_thread called\n")); 245 if (!initialized) { 246 exit(0); 247 } 248 } 276 249 277 250 #ifdef USE_SEMAPHORES … … 281 254 */ 282 255 283 PyThread_type_lock 256 PyThread_type_lock 284 257 PyThread_allocate_lock(void) 285 258 { 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 } 308 309 void 259 sem_t *lock; 260 int status, error = 0; 261 262 dprintf(("PyThread_allocate_lock called\n")); 263 if (!initialized) 264 PyThread_init_thread(); 265 266 lock = (sem_t *)malloc(sizeof(sem_t)); 267 268 if (lock) { 269 status = sem_init(lock,0,1); 270 CHECK_STATUS("sem_init"); 271 272 if (error) { 273 free((void *)lock); 274 lock = NULL; 275 } 276 } 277 278 dprintf(("PyThread_allocate_lock() -> %p\n", lock)); 279 return (PyThread_type_lock)lock; 280 } 281 282 void 310 283 PyThread_free_lock(PyThread_type_lock lock) 311 284 { 312 sem_t *thelock = (sem_t *)lock; 313 int status, error = 0; 314 315 dprintf(("PyThread_free_lock(%p) called\n", lock)); 316 317 if (!thelock) 318 return; 319 320 status = sem_destroy(thelock); 321 CHECK_STATUS("sem_destroy"); 322 323 free((void *)thelock); 285 sem_t *thelock = (sem_t *)lock; 286 int status, error = 0; 287 288 (void) error; /* silence unused-but-set-variable warning */ 289 dprintf(("PyThread_free_lock(%p) called\n", lock)); 290 291 if (!thelock) 292 return; 293 294 status = sem_destroy(thelock); 295 CHECK_STATUS("sem_destroy"); 296 297 free((void *)thelock); 324 298 } 325 299 … … 333 307 fix_status(int status) 334 308 { 335 336 } 337 338 int 309 return (status == -1) ? errno : status; 310 } 311 312 int 339 313 PyThread_acquire_lock(PyThread_type_lock lock, int waitflag) 340 314 { 341 int success; 342 sem_t *thelock = (sem_t *)lock; 343 int status, error = 0; 344 345 dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag)); 346 347 do { 348 if (waitflag) 349 status = fix_status(sem_wait(thelock)); 350 else 351 status = fix_status(sem_trywait(thelock)); 352 } while (status == EINTR); /* Retry if interrupted by a signal */ 353 354 if (waitflag) { 355 CHECK_STATUS("sem_wait"); 356 } else if (status != EAGAIN) { 357 CHECK_STATUS("sem_trywait"); 358 } 359 360 success = (status == 0) ? 1 : 0; 361 362 dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success)); 363 return success; 364 } 365 366 void 315 int success; 316 sem_t *thelock = (sem_t *)lock; 317 int status, error = 0; 318 319 (void) error; /* silence unused-but-set-variable warning */ 320 dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag)); 321 322 do { 323 if (waitflag) 324 status = fix_status(sem_wait(thelock)); 325 else 326 status = fix_status(sem_trywait(thelock)); 327 } while (status == EINTR); /* Retry if interrupted by a signal */ 328 329 if (waitflag) { 330 CHECK_STATUS("sem_wait"); 331 } else if (status != EAGAIN) { 332 CHECK_STATUS("sem_trywait"); 333 } 334 335 success = (status == 0) ? 1 : 0; 336 337 dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success)); 338 return success; 339 } 340 341 void 367 342 PyThread_release_lock(PyThread_type_lock lock) 368 343 { 369 sem_t *thelock = (sem_t *)lock; 370 int status, error = 0; 371 372 dprintf(("PyThread_release_lock(%p) called\n", lock)); 373 374 status = sem_post(thelock); 375 CHECK_STATUS("sem_post"); 344 sem_t *thelock = (sem_t *)lock; 345 int status, error = 0; 346 347 (void) error; /* silence unused-but-set-variable warning */ 348 dprintf(("PyThread_release_lock(%p) called\n", lock)); 349 350 status = sem_post(thelock); 351 CHECK_STATUS("sem_post"); 376 352 } 377 353 … … 381 357 * Lock support. 382 358 */ 383 PyThread_type_lock 359 PyThread_type_lock 384 360 PyThread_allocate_lock(void) 385 361 { 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 } 415 416 void 362 pthread_lock *lock; 363 int status, error = 0; 364 365 dprintf(("PyThread_allocate_lock called\n")); 366 if (!initialized) 367 PyThread_init_thread(); 368 369 lock = (pthread_lock *) malloc(sizeof(pthread_lock)); 370 if (lock) { 371 memset((void *)lock, '\0', sizeof(pthread_lock)); 372 lock->locked = 0; 373 374 status = pthread_mutex_init(&lock->mut, 375 pthread_mutexattr_default); 376 CHECK_STATUS("pthread_mutex_init"); 377 378 status = pthread_cond_init(&lock->lock_released, 379 pthread_condattr_default); 380 CHECK_STATUS("pthread_cond_init"); 381 382 if (error) { 383 free((void *)lock); 384 lock = 0; 385 } 386 } 387 388 dprintf(("PyThread_allocate_lock() -> %p\n", lock)); 389 return (PyThread_type_lock) lock; 390 } 391 392 void 417 393 PyThread_free_lock(PyThread_type_lock lock) 418 394 { 419 pthread_lock *thelock = (pthread_lock *)lock; 420 int status, error = 0; 421 422 dprintf(("PyThread_free_lock(%p) called\n", lock)); 423 424 status = pthread_mutex_destroy( &thelock->mut ); 425 CHECK_STATUS("pthread_mutex_destroy"); 426 427 status = pthread_cond_destroy( &thelock->lock_released ); 428 CHECK_STATUS("pthread_cond_destroy"); 429 430 free((void *)thelock); 431 } 432 433 int 395 pthread_lock *thelock = (pthread_lock *)lock; 396 int status, error = 0; 397 398 (void) error; /* silence unused-but-set-variable warning */ 399 dprintf(("PyThread_free_lock(%p) called\n", lock)); 400 401 status = pthread_mutex_destroy( &thelock->mut ); 402 CHECK_STATUS("pthread_mutex_destroy"); 403 404 status = pthread_cond_destroy( &thelock->lock_released ); 405 CHECK_STATUS("pthread_cond_destroy"); 406 407 free((void *)thelock); 408 } 409 410 int 434 411 PyThread_acquire_lock(PyThread_type_lock lock, int waitflag) 435 412 { 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 } 466 467 void 413 int success; 414 pthread_lock *thelock = (pthread_lock *)lock; 415 int status, error = 0; 416 417 dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag)); 418 419 status = pthread_mutex_lock( &thelock->mut ); 420 CHECK_STATUS("pthread_mutex_lock[1]"); 421 success = thelock->locked == 0; 422 423 if ( !success && waitflag ) { 424 /* continue trying until we get the lock */ 425 426 /* mut must be locked by me -- part of the condition 427 * protocol */ 428 while ( thelock->locked ) { 429 status = pthread_cond_wait(&thelock->lock_released, 430 &thelock->mut); 431 CHECK_STATUS("pthread_cond_wait"); 432 } 433 success = 1; 434 } 435 if (success) thelock->locked = 1; 436 status = pthread_mutex_unlock( &thelock->mut ); 437 CHECK_STATUS("pthread_mutex_unlock[1]"); 438 439 if (error) success = 0; 440 dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success)); 441 return success; 442 } 443 444 void 468 445 PyThread_release_lock(PyThread_type_lock lock) 469 446 { 470 pthread_lock *thelock = (pthread_lock *)lock; 471 int status, error = 0; 472 473 dprintf(("PyThread_release_lock(%p) called\n", lock)); 474 475 status = pthread_mutex_lock( &thelock->mut ); 476 CHECK_STATUS("pthread_mutex_lock[3]"); 477 478 thelock->locked = 0; 479 480 status = pthread_mutex_unlock( &thelock->mut ); 481 CHECK_STATUS("pthread_mutex_unlock[3]"); 482 483 /* wake up someone (anyone, if any) waiting on the lock */ 484 status = pthread_cond_signal( &thelock->lock_released ); 485 CHECK_STATUS("pthread_cond_signal"); 447 pthread_lock *thelock = (pthread_lock *)lock; 448 int status, error = 0; 449 450 (void) error; /* silence unused-but-set-variable warning */ 451 dprintf(("PyThread_release_lock(%p) called\n", lock)); 452 453 status = pthread_mutex_lock( &thelock->mut ); 454 CHECK_STATUS("pthread_mutex_lock[3]"); 455 456 thelock->locked = 0; 457 458 status = pthread_mutex_unlock( &thelock->mut ); 459 CHECK_STATUS("pthread_mutex_unlock[3]"); 460 461 /* wake up someone (anyone, if any) waiting on the lock */ 462 status = pthread_cond_signal( &thelock->lock_released ); 463 CHECK_STATUS("pthread_cond_signal"); 486 464 } 487 465 … … 496 474 { 497 475 #if defined(THREAD_STACK_SIZE) 498 499 500 501 #endif 502 503 504 505 506 507 476 pthread_attr_t attrs; 477 size_t tss_min; 478 int rc = 0; 479 #endif 480 481 /* set to default */ 482 if (size == 0) { 483 _pythread_stacksize = 0; 484 return 0; 485 } 508 486 509 487 #if defined(THREAD_STACK_SIZE) 510 488 #if defined(PTHREAD_STACK_MIN) 511 512 513 #else 514 515 #endif 516 517 518 519 520 521 522 523 524 525 526 527 528 #else 529 530 #endif 531 } 532 533 #define THREAD_SET_STACKSIZE(x) 489 tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN 490 : THREAD_STACK_MIN; 491 #else 492 tss_min = THREAD_STACK_MIN; 493 #endif 494 if (size >= tss_min) { 495 /* validate stack size by setting thread attribute */ 496 if (pthread_attr_init(&attrs) == 0) { 497 rc = pthread_attr_setstacksize(&attrs, size); 498 pthread_attr_destroy(&attrs); 499 if (rc == 0) { 500 _pythread_stacksize = size; 501 return 0; 502 } 503 } 504 } 505 return -1; 506 #else 507 return -2; 508 #endif 509 } 510 511 #define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
Note:
See TracChangeset
for help on using the changeset viewer.