Mercurial > cpython-lru_cache-weakref
comparison Python/thread.c @ 61465:e38335d4df91 2.6
Recorded merge of revisions 81029 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r81029 | antoine.pitrou | 2010-05-09 16:46:46 +0200 (dim., 09 mai 2010) | 3 lines
Untabify C files. Will watch buildbots.
........
| author | Antoine Pitrou <solipsis@pitrou.net> |
|---|---|
| date | Sun, 09 May 2010 15:15:40 +0000 |
| parents | a8a8232cb541 |
| children | 787b969d37f0 |
comparison
equal
deleted
inserted
replaced
| 61461:b6e03ca8a206 | 61465:e38335d4df91 |
|---|---|
| 44 #if defined(sun) && !defined(SOLARIS_THREADS) | 44 #if defined(sun) && !defined(SOLARIS_THREADS) |
| 45 #define SUN_LWP | 45 #define SUN_LWP |
| 46 #endif | 46 #endif |
| 47 | 47 |
| 48 /* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then | 48 /* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then |
| 49 enough of the Posix threads package is implimented to support python | 49 enough of the Posix threads package is implimented to support python |
| 50 threads. | 50 threads. |
| 51 | 51 |
| 52 This is valid for HP-UX 11.23 running on an ia64 system. If needed, add | 52 This is valid for HP-UX 11.23 running on an ia64 system. If needed, add |
| 53 a check of __ia64 to verify that we're running on a ia64 system instead | 53 a check of __ia64 to verify that we're running on a ia64 system instead |
| 54 of a pa-risc system. | 54 of a pa-risc system. |
| 62 #endif /* _POSIX_THREADS */ | 62 #endif /* _POSIX_THREADS */ |
| 63 | 63 |
| 64 | 64 |
| 65 #ifdef Py_DEBUG | 65 #ifdef Py_DEBUG |
| 66 static int thread_debug = 0; | 66 static int thread_debug = 0; |
| 67 #define dprintf(args) (void)((thread_debug & 1) && printf args) | 67 #define dprintf(args) (void)((thread_debug & 1) && printf args) |
| 68 #define d2printf(args) ((thread_debug & 8) && printf args) | 68 #define d2printf(args) ((thread_debug & 8) && printf args) |
| 69 #else | 69 #else |
| 70 #define dprintf(args) | 70 #define dprintf(args) |
| 71 #define d2printf(args) | 71 #define d2printf(args) |
| 72 #endif | 72 #endif |
| 73 | 73 |
| 77 | 77 |
| 78 void | 78 void |
| 79 PyThread_init_thread(void) | 79 PyThread_init_thread(void) |
| 80 { | 80 { |
| 81 #ifdef Py_DEBUG | 81 #ifdef Py_DEBUG |
| 82 char *p = Py_GETENV("PYTHONTHREADDEBUG"); | 82 char *p = Py_GETENV("PYTHONTHREADDEBUG"); |
| 83 | 83 |
| 84 if (p) { | 84 if (p) { |
| 85 if (*p) | 85 if (*p) |
| 86 thread_debug = atoi(p); | 86 thread_debug = atoi(p); |
| 87 else | 87 else |
| 88 thread_debug = 1; | 88 thread_debug = 1; |
| 89 } | 89 } |
| 90 #endif /* Py_DEBUG */ | 90 #endif /* Py_DEBUG */ |
| 91 if (initialized) | 91 if (initialized) |
| 92 return; | 92 return; |
| 93 initialized = 1; | 93 initialized = 1; |
| 94 dprintf(("PyThread_init_thread called\n")); | 94 dprintf(("PyThread_init_thread called\n")); |
| 95 PyThread__init_thread(); | 95 PyThread__init_thread(); |
| 96 } | 96 } |
| 97 | 97 |
| 98 /* Support for runtime thread stack size tuning. | 98 /* Support for runtime thread stack size tuning. |
| 99 A value of 0 means using the platform's default stack size | 99 A value of 0 means using the platform's default stack size |
| 100 or the size specified by the THREAD_STACK_SIZE macro. */ | 100 or the size specified by the THREAD_STACK_SIZE macro. */ |
| 157 | 157 |
| 158 /* return the current thread stack size */ | 158 /* return the current thread stack size */ |
| 159 size_t | 159 size_t |
| 160 PyThread_get_stacksize(void) | 160 PyThread_get_stacksize(void) |
| 161 { | 161 { |
| 162 return _pythread_stacksize; | 162 return _pythread_stacksize; |
| 163 } | 163 } |
| 164 | 164 |
| 165 /* Only platforms defining a THREAD_SET_STACKSIZE() macro | 165 /* Only platforms defining a THREAD_SET_STACKSIZE() macro |
| 166 in thread_<platform>.h support changing the stack size. | 166 in thread_<platform>.h support changing the stack size. |
| 167 Return 0 if stack size is valid, | 167 Return 0 if stack size is valid, |
| 168 -1 if stack size value is invalid, | 168 -1 if stack size value is invalid, |
| 169 -2 if setting stack size is not supported. */ | 169 -2 if setting stack size is not supported. */ |
| 170 int | 170 int |
| 171 PyThread_set_stacksize(size_t size) | 171 PyThread_set_stacksize(size_t size) |
| 172 { | 172 { |
| 173 #if defined(THREAD_SET_STACKSIZE) | 173 #if defined(THREAD_SET_STACKSIZE) |
| 174 return THREAD_SET_STACKSIZE(size); | 174 return THREAD_SET_STACKSIZE(size); |
| 175 #else | 175 #else |
| 176 return -2; | 176 return -2; |
| 177 #endif | 177 #endif |
| 178 } | 178 } |
| 179 | 179 |
| 180 #ifndef Py_HAVE_NATIVE_TLS | 180 #ifndef Py_HAVE_NATIVE_TLS |
| 181 /* If the platform has not supplied a platform specific | 181 /* If the platform has not supplied a platform specific |
| 223 /* A singly-linked list of struct key objects remembers all the key->value | 223 /* A singly-linked list of struct key objects remembers all the key->value |
| 224 * associations. File static keyhead heads the list. keymutex is used | 224 * associations. File static keyhead heads the list. keymutex is used |
| 225 * to enforce exclusion internally. | 225 * to enforce exclusion internally. |
| 226 */ | 226 */ |
| 227 struct key { | 227 struct key { |
| 228 /* Next record in the list, or NULL if this is the last record. */ | 228 /* Next record in the list, or NULL if this is the last record. */ |
| 229 struct key *next; | 229 struct key *next; |
| 230 | 230 |
| 231 /* The thread id, according to PyThread_get_thread_ident(). */ | 231 /* The thread id, according to PyThread_get_thread_ident(). */ |
| 232 long id; | 232 long id; |
| 233 | 233 |
| 234 /* The key and its associated value. */ | 234 /* The key and its associated value. */ |
| 235 int key; | 235 int key; |
| 236 void *value; | 236 void *value; |
| 237 }; | 237 }; |
| 238 | 238 |
| 239 static struct key *keyhead = NULL; | 239 static struct key *keyhead = NULL; |
| 240 static PyThread_type_lock keymutex = NULL; | 240 static PyThread_type_lock keymutex = NULL; |
| 241 static int nkeys = 0; /* PyThread_create_key() hands out nkeys+1 next */ | 241 static int nkeys = 0; /* PyThread_create_key() hands out nkeys+1 next */ |
| 262 * segfaults. Now we lock the whole routine. | 262 * segfaults. Now we lock the whole routine. |
| 263 */ | 263 */ |
| 264 static struct key * | 264 static struct key * |
| 265 find_key(int key, void *value) | 265 find_key(int key, void *value) |
| 266 { | 266 { |
| 267 struct key *p, *prev_p; | 267 struct key *p, *prev_p; |
| 268 long id = PyThread_get_thread_ident(); | 268 long id = PyThread_get_thread_ident(); |
| 269 | 269 |
| 270 if (!keymutex) | 270 if (!keymutex) |
| 271 return NULL; | 271 return NULL; |
| 272 PyThread_acquire_lock(keymutex, 1); | 272 PyThread_acquire_lock(keymutex, 1); |
| 273 prev_p = NULL; | 273 prev_p = NULL; |
| 274 for (p = keyhead; p != NULL; p = p->next) { | 274 for (p = keyhead; p != NULL; p = p->next) { |
| 275 if (p->id == id && p->key == key) | 275 if (p->id == id && p->key == key) |
| 276 goto Done; | 276 goto Done; |
| 277 /* Sanity check. These states should never happen but if | 277 /* Sanity check. These states should never happen but if |
| 278 * they do we must abort. Otherwise we'll end up spinning in | 278 * they do we must abort. Otherwise we'll end up spinning in |
| 279 * in a tight loop with the lock held. A similar check is done | 279 * in a tight loop with the lock held. A similar check is done |
| 280 * in pystate.c tstate_delete_common(). */ | 280 * in pystate.c tstate_delete_common(). */ |
| 281 if (p == prev_p) | 281 if (p == prev_p) |
| 282 Py_FatalError("tls find_key: small circular list(!)"); | 282 Py_FatalError("tls find_key: small circular list(!)"); |
| 283 prev_p = p; | 283 prev_p = p; |
| 284 if (p->next == keyhead) | 284 if (p->next == keyhead) |
| 285 Py_FatalError("tls find_key: circular list(!)"); | 285 Py_FatalError("tls find_key: circular list(!)"); |
| 286 } | 286 } |
| 287 if (value == NULL) { | 287 if (value == NULL) { |
| 288 assert(p == NULL); | 288 assert(p == NULL); |
| 289 goto Done; | 289 goto Done; |
| 290 } | 290 } |
| 291 p = (struct key *)malloc(sizeof(struct key)); | 291 p = (struct key *)malloc(sizeof(struct key)); |
| 292 if (p != NULL) { | 292 if (p != NULL) { |
| 293 p->id = id; | 293 p->id = id; |
| 294 p->key = key; | 294 p->key = key; |
| 295 p->value = value; | 295 p->value = value; |
| 296 p->next = keyhead; | 296 p->next = keyhead; |
| 297 keyhead = p; | 297 keyhead = p; |
| 298 } | 298 } |
| 299 Done: | 299 Done: |
| 300 PyThread_release_lock(keymutex); | 300 PyThread_release_lock(keymutex); |
| 301 return p; | 301 return p; |
| 302 } | 302 } |
| 303 | 303 |
| 304 /* Return a new key. This must be called before any other functions in | 304 /* Return a new key. This must be called before any other functions in |
| 305 * this family, and callers must arrange to serialize calls to this | 305 * this family, and callers must arrange to serialize calls to this |
| 306 * function. No violations are detected. | 306 * function. No violations are detected. |
| 307 */ | 307 */ |
| 308 int | 308 int |
| 309 PyThread_create_key(void) | 309 PyThread_create_key(void) |
| 310 { | 310 { |
| 311 /* All parts of this function are wrong if it's called by multiple | 311 /* All parts of this function are wrong if it's called by multiple |
| 312 * threads simultaneously. | 312 * threads simultaneously. |
| 313 */ | 313 */ |
| 314 if (keymutex == NULL) | 314 if (keymutex == NULL) |
| 315 keymutex = PyThread_allocate_lock(); | 315 keymutex = PyThread_allocate_lock(); |
| 316 return ++nkeys; | 316 return ++nkeys; |
| 317 } | 317 } |
| 318 | 318 |
| 319 /* Forget the associations for key across *all* threads. */ | 319 /* Forget the associations for key across *all* threads. */ |
| 320 void | 320 void |
| 321 PyThread_delete_key(int key) | 321 PyThread_delete_key(int key) |
| 322 { | 322 { |
| 323 struct key *p, **q; | 323 struct key *p, **q; |
| 324 | 324 |
| 325 PyThread_acquire_lock(keymutex, 1); | 325 PyThread_acquire_lock(keymutex, 1); |
| 326 q = &keyhead; | 326 q = &keyhead; |
| 327 while ((p = *q) != NULL) { | 327 while ((p = *q) != NULL) { |
| 328 if (p->key == key) { | 328 if (p->key == key) { |
| 329 *q = p->next; | 329 *q = p->next; |
| 330 free((void *)p); | 330 free((void *)p); |
| 331 /* NB This does *not* free p->value! */ | 331 /* NB This does *not* free p->value! */ |
| 332 } | 332 } |
| 333 else | 333 else |
| 334 q = &p->next; | 334 q = &p->next; |
| 335 } | 335 } |
| 336 PyThread_release_lock(keymutex); | 336 PyThread_release_lock(keymutex); |
| 337 } | 337 } |
| 338 | 338 |
| 339 /* Confusing: If the current thread has an association for key, | 339 /* Confusing: If the current thread has an association for key, |
| 340 * value is ignored, and 0 is returned. Else an attempt is made to create | 340 * value is ignored, and 0 is returned. Else an attempt is made to create |
| 341 * an association of key to value for the current thread. 0 is returned | 341 * an association of key to value for the current thread. 0 is returned |
| 343 * to create the association. value must not be NULL. | 343 * to create the association. value must not be NULL. |
| 344 */ | 344 */ |
| 345 int | 345 int |
| 346 PyThread_set_key_value(int key, void *value) | 346 PyThread_set_key_value(int key, void *value) |
| 347 { | 347 { |
| 348 struct key *p; | 348 struct key *p; |
| 349 | 349 |
| 350 assert(value != NULL); | 350 assert(value != NULL); |
| 351 p = find_key(key, value); | 351 p = find_key(key, value); |
| 352 if (p == NULL) | 352 if (p == NULL) |
| 353 return -1; | 353 return -1; |
| 354 else | 354 else |
| 355 return 0; | 355 return 0; |
| 356 } | 356 } |
| 357 | 357 |
| 358 /* Retrieve the value associated with key in the current thread, or NULL | 358 /* Retrieve the value associated with key in the current thread, or NULL |
| 359 * if the current thread doesn't have an association for key. | 359 * if the current thread doesn't have an association for key. |
| 360 */ | 360 */ |
| 361 void * | 361 void * |
| 362 PyThread_get_key_value(int key) | 362 PyThread_get_key_value(int key) |
| 363 { | 363 { |
| 364 struct key *p = find_key(key, NULL); | 364 struct key *p = find_key(key, NULL); |
| 365 | 365 |
| 366 if (p == NULL) | 366 if (p == NULL) |
| 367 return NULL; | 367 return NULL; |
| 368 else | 368 else |
| 369 return p->value; | 369 return p->value; |
| 370 } | 370 } |
| 371 | 371 |
| 372 /* Forget the current thread's association for key, if any. */ | 372 /* Forget the current thread's association for key, if any. */ |
| 373 void | 373 void |
| 374 PyThread_delete_key_value(int key) | 374 PyThread_delete_key_value(int key) |
| 375 { | 375 { |
| 376 long id = PyThread_get_thread_ident(); | 376 long id = PyThread_get_thread_ident(); |
| 377 struct key *p, **q; | 377 struct key *p, **q; |
| 378 | 378 |
| 379 PyThread_acquire_lock(keymutex, 1); | 379 PyThread_acquire_lock(keymutex, 1); |
| 380 q = &keyhead; | 380 q = &keyhead; |
| 381 while ((p = *q) != NULL) { | 381 while ((p = *q) != NULL) { |
| 382 if (p->key == key && p->id == id) { | 382 if (p->key == key && p->id == id) { |
| 383 *q = p->next; | 383 *q = p->next; |
| 384 free((void *)p); | 384 free((void *)p); |
| 385 /* NB This does *not* free p->value! */ | 385 /* NB This does *not* free p->value! */ |
| 386 break; | 386 break; |
| 387 } | 387 } |
| 388 else | 388 else |
| 389 q = &p->next; | 389 q = &p->next; |
| 390 } | 390 } |
| 391 PyThread_release_lock(keymutex); | 391 PyThread_release_lock(keymutex); |
| 392 } | 392 } |
| 393 | 393 |
| 394 /* Forget everything not associated with the current thread id. | 394 /* Forget everything not associated with the current thread id. |
| 395 * This function is called from PyOS_AfterFork(). It is necessary | 395 * This function is called from PyOS_AfterFork(). It is necessary |
| 396 * because other thread ids which were in use at the time of the fork | 396 * because other thread ids which were in use at the time of the fork |
| 397 * may be reused for new threads created in the forked process. | 397 * may be reused for new threads created in the forked process. |
| 398 */ | 398 */ |
| 399 void | 399 void |
| 400 PyThread_ReInitTLS(void) | 400 PyThread_ReInitTLS(void) |
| 401 { | 401 { |
| 402 long id = PyThread_get_thread_ident(); | 402 long id = PyThread_get_thread_ident(); |
| 403 struct key *p, **q; | 403 struct key *p, **q; |
| 404 | 404 |
| 405 if (!keymutex) | 405 if (!keymutex) |
| 406 return; | 406 return; |
| 407 | 407 |
| 408 /* As with interpreter_lock in PyEval_ReInitThreads() | 408 /* As with interpreter_lock in PyEval_ReInitThreads() |
| 409 we just create a new lock without freeing the old one */ | 409 we just create a new lock without freeing the old one */ |
| 410 keymutex = PyThread_allocate_lock(); | 410 keymutex = PyThread_allocate_lock(); |
| 411 | 411 |
| 412 /* Delete all keys which do not match the current thread id */ | 412 /* Delete all keys which do not match the current thread id */ |
| 413 q = &keyhead; | 413 q = &keyhead; |
| 414 while ((p = *q) != NULL) { | 414 while ((p = *q) != NULL) { |
| 415 if (p->id != id) { | 415 if (p->id != id) { |
| 416 *q = p->next; | 416 *q = p->next; |
| 417 free((void *)p); | 417 free((void *)p); |
| 418 /* NB This does *not* free p->value! */ | 418 /* NB This does *not* free p->value! */ |
| 419 } | 419 } |
| 420 else | 420 else |
| 421 q = &p->next; | 421 q = &p->next; |
| 422 } | 422 } |
| 423 } | 423 } |
| 424 | 424 |
| 425 #endif /* Py_HAVE_NATIVE_TLS */ | 425 #endif /* Py_HAVE_NATIVE_TLS */ |
