Mercurial > cpython-lru_cache-weakref
comparison Python/thread.c @ 61463:fd25030223b0 legacy-trunk
Untabify C files. Will watch buildbots.
| author | Antoine Pitrou <solipsis@pitrou.net> |
|---|---|
| date | Sun, 09 May 2010 14:46:46 +0000 |
| parents | 8540268040ff |
| children | b36cb4602e21 |
comparison
equal
deleted
inserted
replaced
| 61460:d698fb056a45 | 61463:fd25030223b0 |
|---|---|
| 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. */ |
| 153 | 153 |
| 154 /* return the current thread stack size */ | 154 /* return the current thread stack size */ |
| 155 size_t | 155 size_t |
| 156 PyThread_get_stacksize(void) | 156 PyThread_get_stacksize(void) |
| 157 { | 157 { |
| 158 return _pythread_stacksize; | 158 return _pythread_stacksize; |
| 159 } | 159 } |
| 160 | 160 |
| 161 /* Only platforms defining a THREAD_SET_STACKSIZE() macro | 161 /* Only platforms defining a THREAD_SET_STACKSIZE() macro |
| 162 in thread_<platform>.h support changing the stack size. | 162 in thread_<platform>.h support changing the stack size. |
| 163 Return 0 if stack size is valid, | 163 Return 0 if stack size is valid, |
| 164 -1 if stack size value is invalid, | 164 -1 if stack size value is invalid, |
| 165 -2 if setting stack size is not supported. */ | 165 -2 if setting stack size is not supported. */ |
| 166 int | 166 int |
| 167 PyThread_set_stacksize(size_t size) | 167 PyThread_set_stacksize(size_t size) |
| 168 { | 168 { |
| 169 #if defined(THREAD_SET_STACKSIZE) | 169 #if defined(THREAD_SET_STACKSIZE) |
| 170 return THREAD_SET_STACKSIZE(size); | 170 return THREAD_SET_STACKSIZE(size); |
| 171 #else | 171 #else |
| 172 return -2; | 172 return -2; |
| 173 #endif | 173 #endif |
| 174 } | 174 } |
| 175 | 175 |
| 176 #ifndef Py_HAVE_NATIVE_TLS | 176 #ifndef Py_HAVE_NATIVE_TLS |
| 177 /* If the platform has not supplied a platform specific | 177 /* If the platform has not supplied a platform specific |
| 219 /* A singly-linked list of struct key objects remembers all the key->value | 219 /* A singly-linked list of struct key objects remembers all the key->value |
| 220 * associations. File static keyhead heads the list. keymutex is used | 220 * associations. File static keyhead heads the list. keymutex is used |
| 221 * to enforce exclusion internally. | 221 * to enforce exclusion internally. |
| 222 */ | 222 */ |
| 223 struct key { | 223 struct key { |
| 224 /* Next record in the list, or NULL if this is the last record. */ | 224 /* Next record in the list, or NULL if this is the last record. */ |
| 225 struct key *next; | 225 struct key *next; |
| 226 | 226 |
| 227 /* The thread id, according to PyThread_get_thread_ident(). */ | 227 /* The thread id, according to PyThread_get_thread_ident(). */ |
| 228 long id; | 228 long id; |
| 229 | 229 |
| 230 /* The key and its associated value. */ | 230 /* The key and its associated value. */ |
| 231 int key; | 231 int key; |
| 232 void *value; | 232 void *value; |
| 233 }; | 233 }; |
| 234 | 234 |
| 235 static struct key *keyhead = NULL; | 235 static struct key *keyhead = NULL; |
| 236 static PyThread_type_lock keymutex = NULL; | 236 static PyThread_type_lock keymutex = NULL; |
| 237 static int nkeys = 0; /* PyThread_create_key() hands out nkeys+1 next */ | 237 static int nkeys = 0; /* PyThread_create_key() hands out nkeys+1 next */ |
| 258 * segfaults. Now we lock the whole routine. | 258 * segfaults. Now we lock the whole routine. |
| 259 */ | 259 */ |
| 260 static struct key * | 260 static struct key * |
| 261 find_key(int key, void *value) | 261 find_key(int key, void *value) |
| 262 { | 262 { |
| 263 struct key *p, *prev_p; | 263 struct key *p, *prev_p; |
| 264 long id = PyThread_get_thread_ident(); | 264 long id = PyThread_get_thread_ident(); |
| 265 | 265 |
| 266 if (!keymutex) | 266 if (!keymutex) |
| 267 return NULL; | 267 return NULL; |
| 268 PyThread_acquire_lock(keymutex, 1); | 268 PyThread_acquire_lock(keymutex, 1); |
| 269 prev_p = NULL; | 269 prev_p = NULL; |
| 270 for (p = keyhead; p != NULL; p = p->next) { | 270 for (p = keyhead; p != NULL; p = p->next) { |
| 271 if (p->id == id && p->key == key) | 271 if (p->id == id && p->key == key) |
| 272 goto Done; | 272 goto Done; |
| 273 /* Sanity check. These states should never happen but if | 273 /* Sanity check. These states should never happen but if |
| 274 * they do we must abort. Otherwise we'll end up spinning in | 274 * they do we must abort. Otherwise we'll end up spinning in |
| 275 * in a tight loop with the lock held. A similar check is done | 275 * in a tight loop with the lock held. A similar check is done |
| 276 * in pystate.c tstate_delete_common(). */ | 276 * in pystate.c tstate_delete_common(). */ |
| 277 if (p == prev_p) | 277 if (p == prev_p) |
| 278 Py_FatalError("tls find_key: small circular list(!)"); | 278 Py_FatalError("tls find_key: small circular list(!)"); |
| 279 prev_p = p; | 279 prev_p = p; |
| 280 if (p->next == keyhead) | 280 if (p->next == keyhead) |
| 281 Py_FatalError("tls find_key: circular list(!)"); | 281 Py_FatalError("tls find_key: circular list(!)"); |
| 282 } | 282 } |
| 283 if (value == NULL) { | 283 if (value == NULL) { |
| 284 assert(p == NULL); | 284 assert(p == NULL); |
| 285 goto Done; | 285 goto Done; |
| 286 } | 286 } |
| 287 p = (struct key *)malloc(sizeof(struct key)); | 287 p = (struct key *)malloc(sizeof(struct key)); |
| 288 if (p != NULL) { | 288 if (p != NULL) { |
| 289 p->id = id; | 289 p->id = id; |
| 290 p->key = key; | 290 p->key = key; |
| 291 p->value = value; | 291 p->value = value; |
| 292 p->next = keyhead; | 292 p->next = keyhead; |
| 293 keyhead = p; | 293 keyhead = p; |
| 294 } | 294 } |
| 295 Done: | 295 Done: |
| 296 PyThread_release_lock(keymutex); | 296 PyThread_release_lock(keymutex); |
| 297 return p; | 297 return p; |
| 298 } | 298 } |
| 299 | 299 |
| 300 /* Return a new key. This must be called before any other functions in | 300 /* Return a new key. This must be called before any other functions in |
| 301 * this family, and callers must arrange to serialize calls to this | 301 * this family, and callers must arrange to serialize calls to this |
| 302 * function. No violations are detected. | 302 * function. No violations are detected. |
| 303 */ | 303 */ |
| 304 int | 304 int |
| 305 PyThread_create_key(void) | 305 PyThread_create_key(void) |
| 306 { | 306 { |
| 307 /* All parts of this function are wrong if it's called by multiple | 307 /* All parts of this function are wrong if it's called by multiple |
| 308 * threads simultaneously. | 308 * threads simultaneously. |
| 309 */ | 309 */ |
| 310 if (keymutex == NULL) | 310 if (keymutex == NULL) |
| 311 keymutex = PyThread_allocate_lock(); | 311 keymutex = PyThread_allocate_lock(); |
| 312 return ++nkeys; | 312 return ++nkeys; |
| 313 } | 313 } |
| 314 | 314 |
| 315 /* Forget the associations for key across *all* threads. */ | 315 /* Forget the associations for key across *all* threads. */ |
| 316 void | 316 void |
| 317 PyThread_delete_key(int key) | 317 PyThread_delete_key(int key) |
| 318 { | 318 { |
| 319 struct key *p, **q; | 319 struct key *p, **q; |
| 320 | 320 |
| 321 PyThread_acquire_lock(keymutex, 1); | 321 PyThread_acquire_lock(keymutex, 1); |
| 322 q = &keyhead; | 322 q = &keyhead; |
| 323 while ((p = *q) != NULL) { | 323 while ((p = *q) != NULL) { |
| 324 if (p->key == key) { | 324 if (p->key == key) { |
| 325 *q = p->next; | 325 *q = p->next; |
| 326 free((void *)p); | 326 free((void *)p); |
| 327 /* NB This does *not* free p->value! */ | 327 /* NB This does *not* free p->value! */ |
| 328 } | 328 } |
| 329 else | 329 else |
| 330 q = &p->next; | 330 q = &p->next; |
| 331 } | 331 } |
| 332 PyThread_release_lock(keymutex); | 332 PyThread_release_lock(keymutex); |
| 333 } | 333 } |
| 334 | 334 |
| 335 /* Confusing: If the current thread has an association for key, | 335 /* Confusing: If the current thread has an association for key, |
| 336 * value is ignored, and 0 is returned. Else an attempt is made to create | 336 * value is ignored, and 0 is returned. Else an attempt is made to create |
| 337 * an association of key to value for the current thread. 0 is returned | 337 * an association of key to value for the current thread. 0 is returned |
| 339 * to create the association. value must not be NULL. | 339 * to create the association. value must not be NULL. |
| 340 */ | 340 */ |
| 341 int | 341 int |
| 342 PyThread_set_key_value(int key, void *value) | 342 PyThread_set_key_value(int key, void *value) |
| 343 { | 343 { |
| 344 struct key *p; | 344 struct key *p; |
| 345 | 345 |
| 346 assert(value != NULL); | 346 assert(value != NULL); |
| 347 p = find_key(key, value); | 347 p = find_key(key, value); |
| 348 if (p == NULL) | 348 if (p == NULL) |
| 349 return -1; | 349 return -1; |
| 350 else | 350 else |
| 351 return 0; | 351 return 0; |
| 352 } | 352 } |
| 353 | 353 |
| 354 /* Retrieve the value associated with key in the current thread, or NULL | 354 /* Retrieve the value associated with key in the current thread, or NULL |
| 355 * if the current thread doesn't have an association for key. | 355 * if the current thread doesn't have an association for key. |
| 356 */ | 356 */ |
| 357 void * | 357 void * |
| 358 PyThread_get_key_value(int key) | 358 PyThread_get_key_value(int key) |
| 359 { | 359 { |
| 360 struct key *p = find_key(key, NULL); | 360 struct key *p = find_key(key, NULL); |
| 361 | 361 |
| 362 if (p == NULL) | 362 if (p == NULL) |
| 363 return NULL; | 363 return NULL; |
| 364 else | 364 else |
| 365 return p->value; | 365 return p->value; |
| 366 } | 366 } |
| 367 | 367 |
| 368 /* Forget the current thread's association for key, if any. */ | 368 /* Forget the current thread's association for key, if any. */ |
| 369 void | 369 void |
| 370 PyThread_delete_key_value(int key) | 370 PyThread_delete_key_value(int key) |
| 371 { | 371 { |
| 372 long id = PyThread_get_thread_ident(); | 372 long id = PyThread_get_thread_ident(); |
| 373 struct key *p, **q; | 373 struct key *p, **q; |
| 374 | 374 |
| 375 PyThread_acquire_lock(keymutex, 1); | 375 PyThread_acquire_lock(keymutex, 1); |
| 376 q = &keyhead; | 376 q = &keyhead; |
| 377 while ((p = *q) != NULL) { | 377 while ((p = *q) != NULL) { |
| 378 if (p->key == key && p->id == id) { | 378 if (p->key == key && p->id == id) { |
| 379 *q = p->next; | 379 *q = p->next; |
| 380 free((void *)p); | 380 free((void *)p); |
| 381 /* NB This does *not* free p->value! */ | 381 /* NB This does *not* free p->value! */ |
| 382 break; | 382 break; |
| 383 } | 383 } |
| 384 else | 384 else |
| 385 q = &p->next; | 385 q = &p->next; |
| 386 } | 386 } |
| 387 PyThread_release_lock(keymutex); | 387 PyThread_release_lock(keymutex); |
| 388 } | 388 } |
| 389 | 389 |
| 390 /* Forget everything not associated with the current thread id. | 390 /* Forget everything not associated with the current thread id. |
| 391 * This function is called from PyOS_AfterFork(). It is necessary | 391 * This function is called from PyOS_AfterFork(). It is necessary |
| 392 * because other thread ids which were in use at the time of the fork | 392 * because other thread ids which were in use at the time of the fork |
| 393 * may be reused for new threads created in the forked process. | 393 * may be reused for new threads created in the forked process. |
| 394 */ | 394 */ |
| 395 void | 395 void |
| 396 PyThread_ReInitTLS(void) | 396 PyThread_ReInitTLS(void) |
| 397 { | 397 { |
| 398 long id = PyThread_get_thread_ident(); | 398 long id = PyThread_get_thread_ident(); |
| 399 struct key *p, **q; | 399 struct key *p, **q; |
| 400 | 400 |
| 401 if (!keymutex) | 401 if (!keymutex) |
| 402 return; | 402 return; |
| 403 | 403 |
| 404 /* As with interpreter_lock in PyEval_ReInitThreads() | 404 /* As with interpreter_lock in PyEval_ReInitThreads() |
| 405 we just create a new lock without freeing the old one */ | 405 we just create a new lock without freeing the old one */ |
| 406 keymutex = PyThread_allocate_lock(); | 406 keymutex = PyThread_allocate_lock(); |
| 407 | 407 |
| 408 /* Delete all keys which do not match the current thread id */ | 408 /* Delete all keys which do not match the current thread id */ |
| 409 q = &keyhead; | 409 q = &keyhead; |
| 410 while ((p = *q) != NULL) { | 410 while ((p = *q) != NULL) { |
| 411 if (p->id != id) { | 411 if (p->id != id) { |
| 412 *q = p->next; | 412 *q = p->next; |
| 413 free((void *)p); | 413 free((void *)p); |
| 414 /* NB This does *not* free p->value! */ | 414 /* NB This does *not* free p->value! */ |
| 415 } | 415 } |
| 416 else | 416 else |
| 417 q = &p->next; | 417 q = &p->next; |
| 418 } | 418 } |
| 419 } | 419 } |
| 420 | 420 |
| 421 #endif /* Py_HAVE_NATIVE_TLS */ | 421 #endif /* Py_HAVE_NATIVE_TLS */ |
