blob: 0294365067b3c8242349577b9e276295638861e2 [file] [log] [blame]
Guido van Rossum34679b71993-01-26 13:33:44 +00001
Guido van Rossum1d5735e1994-08-30 08:27:36 +00002/* Thread package.
3 This is intended to be usable independently from Python.
4 The implementation for system foobar is in a file thread_foobar.h
5 which is included by this file dependent on config settings.
6 Stuff shared by all thread_*.h files is collected here. */
7
Martin v. Löwiscdc44512002-01-12 11:05:12 +00008#include "Python.h"
Guido van Rossum1d5735e1994-08-30 08:27:36 +00009
Matthias Klosea2542be2004-08-16 11:35:51 +000010
11#ifndef _POSIX_THREADS
12/* This means pthreads are not implemented in libc headers, hence the macro
13 not present in unistd.h. But they still can be implemented as an external
14 library (e.g. gnu pth in pthread emulation) */
15# ifdef HAVE_PTHREAD_H
16# include <pthread.h> /* _POSIX_THREADS */
17# endif
18#endif
19
Guido van Rossum2571cc81999-04-07 16:07:23 +000020#ifndef DONT_HAVE_STDIO_H
Guido van Rossum1d5735e1994-08-30 08:27:36 +000021#include <stdio.h>
Guido van Rossum2571cc81999-04-07 16:07:23 +000022#endif
Guido van Rossum1d5735e1994-08-30 08:27:36 +000023
Guido van Rossum1d5735e1994-08-30 08:27:36 +000024#include <stdlib.h>
Guido van Rossum1d5735e1994-08-30 08:27:36 +000025
Guido van Rossumd11bfdd1997-04-29 21:48:34 +000026#ifdef __sgi
27#ifndef HAVE_PTHREAD_H /* XXX Need to check in configure.in */
28#undef _POSIX_THREADS
29#endif
30#endif
31
Guido van Rossum49b56061998-10-01 20:42:43 +000032#include "pythread.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +000033
Guido van Rossum1d5735e1994-08-30 08:27:36 +000034#ifndef _POSIX_THREADS
35
Guido van Rossum1984f1e1992-08-04 12:41:02 +000036#ifdef __sgi
Guido van Rossum1d5735e1994-08-30 08:27:36 +000037#define SGI_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +000038#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +000039
Guido van Rossum1d5735e1994-08-30 08:27:36 +000040#ifdef HAVE_THREAD_H
41#define SOLARIS_THREADS
42#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +000043
Guido van Rossum1d5735e1994-08-30 08:27:36 +000044#if defined(sun) && !defined(SOLARIS_THREADS)
45#define SUN_LWP
46#endif
47
Sjoerd Mullender66bca321993-12-03 16:54:45 +000048#endif /* _POSIX_THREADS */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000049
Guido van Rossum1984f1e1992-08-04 12:41:02 +000050
Guido van Rossum408027e1996-12-30 16:17:54 +000051#ifdef Py_DEBUG
Guido van Rossum1d5735e1994-08-30 08:27:36 +000052static int thread_debug = 0;
Jeremy Hyltonbd232892002-06-25 19:26:34 +000053#define dprintf(args) (void)((thread_debug & 1) && printf args)
Guido van Rossum1d5735e1994-08-30 08:27:36 +000054#define d2printf(args) ((thread_debug & 8) && printf args)
55#else
56#define dprintf(args)
57#define d2printf(args)
58#endif
59
Guido van Rossum1984f1e1992-08-04 12:41:02 +000060static int initialized;
61
Thomas Wouters8ec68fd2000-07-24 14:39:50 +000062static void PyThread__init_thread(void); /* Forward */
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +000063
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000064void PyThread_init_thread(void)
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +000065{
Guido van Rossum408027e1996-12-30 16:17:54 +000066#ifdef Py_DEBUG
Sjoerd Mullender66bca321993-12-03 16:54:45 +000067 char *p = getenv("THREADDEBUG");
68
69 if (p) {
70 if (*p)
71 thread_debug = atoi(p);
72 else
73 thread_debug = 1;
74 }
Guido van Rossum408027e1996-12-30 16:17:54 +000075#endif /* Py_DEBUG */
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +000076 if (initialized)
77 return;
78 initialized = 1;
Guido van Rossum65d5b571998-12-21 19:32:43 +000079 dprintf(("PyThread_init_thread called\n"));
80 PyThread__init_thread();
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +000081}
82
Guido van Rossum1d5735e1994-08-30 08:27:36 +000083#ifdef SGI_THREADS
84#include "thread_sgi.h"
Sjoerd Mullender66bca321993-12-03 16:54:45 +000085#endif
Guido van Rossum1d5735e1994-08-30 08:27:36 +000086
87#ifdef SOLARIS_THREADS
88#include "thread_solaris.h"
89#endif
90
91#ifdef SUN_LWP
92#include "thread_lwp.h"
93#endif
94
Guido van Rossum9e8181b2000-09-19 00:46:46 +000095#ifdef HAVE_PTH
Guido van Rossum07bd90e2000-05-08 13:41:38 +000096#include "thread_pth.h"
Martin v. Löwis70849f82003-09-20 11:13:36 +000097#undef _POSIX_THREADS
Guido van Rossum9e8181b2000-09-19 00:46:46 +000098#endif
99
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000100#ifdef _POSIX_THREADS
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000101#include "thread_pthread.h"
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000102#endif
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000103
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000104#ifdef C_THREADS
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000105#include "thread_cthread.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000106#endif
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000107
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000108#ifdef NT_THREADS
109#include "thread_nt.h"
110#endif
111
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000112#ifdef OS2_THREADS
113#include "thread_os2.h"
114#endif
115
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000116#ifdef BEOS_THREADS
117#include "thread_beos.h"
118#endif
119
Guido van Rossum2571cc81999-04-07 16:07:23 +0000120#ifdef WINCE_THREADS
121#include "thread_wince.h"
122#endif
123
Martin v. Löwis7d1cd692002-03-09 12:10:54 +0000124#ifdef PLAN9_THREADS
125#include "thread_plan9.h"
126#endif
127
Martin v. Löwisf90ae202002-06-11 06:22:31 +0000128#ifdef ATHEOS_THREADS
129#include "thread_atheos.h"
130#endif
131
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000132/*
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000133#ifdef FOOBAR_THREADS
134#include "thread_foobar.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000135#endif
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000136*/
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000137
138#ifndef Py_HAVE_NATIVE_TLS
139/* If the platform has not supplied a platform specific
140 TLS implementation, provide our own.
141
142 This code stolen from "thread_sgi.h", where it was the only
143 implementation of an existing Python TLS API.
144*/
145/*
146 * Per-thread data ("key") support.
147 */
148
149struct key {
150 struct key *next;
151 long id;
152 int key;
153 void *value;
154};
155
156static struct key *keyhead = NULL;
157static int nkeys = 0;
158static PyThread_type_lock keymutex = NULL;
159
160static struct key *find_key(int key, void *value)
161{
162 struct key *p;
163 long id = PyThread_get_thread_ident();
164 for (p = keyhead; p != NULL; p = p->next) {
165 if (p->id == id && p->key == key)
166 return p;
167 }
168 if (value == NULL)
169 return NULL;
170 p = (struct key *)malloc(sizeof(struct key));
171 if (p != NULL) {
172 p->id = id;
173 p->key = key;
174 p->value = value;
175 PyThread_acquire_lock(keymutex, 1);
176 p->next = keyhead;
177 keyhead = p;
178 PyThread_release_lock(keymutex);
179 }
180 return p;
181}
182
183int PyThread_create_key(void)
184{
185 if (keymutex == NULL)
186 keymutex = PyThread_allocate_lock();
187 return ++nkeys;
188}
189
190void PyThread_delete_key(int key)
191{
192 struct key *p, **q;
193 PyThread_acquire_lock(keymutex, 1);
194 q = &keyhead;
195 while ((p = *q) != NULL) {
196 if (p->key == key) {
197 *q = p->next;
198 free((void *)p);
199 /* NB This does *not* free p->value! */
200 }
201 else
202 q = &p->next;
203 }
204 PyThread_release_lock(keymutex);
205}
206
207int PyThread_set_key_value(int key, void *value)
208{
209 struct key *p = find_key(key, value);
210 if (p == NULL)
211 return -1;
212 else
213 return 0;
214}
215
216void *PyThread_get_key_value(int key)
217{
218 struct key *p = find_key(key, NULL);
219 if (p == NULL)
220 return NULL;
221 else
222 return p->value;
223}
224
225void PyThread_delete_key_value(int key)
226{
227 long id = PyThread_get_thread_ident();
228 struct key *p, **q;
229 PyThread_acquire_lock(keymutex, 1);
230 q = &keyhead;
231 while ((p = *q) != NULL) {
232 if (p->key == key && p->id == id) {
233 *q = p->next;
234 free((void *)p);
235 /* NB This does *not* free p->value! */
236 break;
237 }
238 else
239 q = &p->next;
240 }
241 PyThread_release_lock(keymutex);
242}
243
244#endif /* Py_HAVE_NATIVE_TLS */