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