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 */