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