annotate Python/ceval_gil.h @ 73323:dad02a080bbc

Improve byte-compilation in packaging to be independent of -O or -B. The code I fixed to comply with PEP 3147 still had one bug: When run under python -O, some paths for pyc files would be pyo, because I called imp.cache_from_source without explicit debug_override argument in some places, and under -O that would return .pyo (this is well explained in the imp docs). Now all code (util.byte_compile, build_py, install_lib) can create .pyo files according to options given by users, without interference from the calling Python’s own optimize mode. On a related topic, I also removed the code that prevented byte compilation under python -B. The rationale is that packaging gives control over the creation of pyc files to the user with its own explicit option, and the behavior should not be changed if the calling Python happens to run with -B for whatever reason. I will argue that this is a bug fix and ask to be allowed to backport this change to distutils. Finally, I moved one nugget of information about the --compile and --optimize options from the source into the doc. It clears up a misunderstanding that I (and maybe other people) had.
author Éric Araujo <merwok@netwok.org>
date Thu, 03 Nov 2011 05:08:28 +0100
parents 2930393f0bbb
children 6d146e2ae9a9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
1 /*
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
2 * Implementation of the Global Interpreter Lock (GIL).
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
3 */
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
4
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
5 #include <stdlib.h>
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
6 #include <errno.h>
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
7
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
8
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
9 /* First some general settings */
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
10
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
11 /* microseconds (the Python API uses seconds, though) */
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
12 #define DEFAULT_INTERVAL 5000
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
13 static unsigned long gil_interval = DEFAULT_INTERVAL;
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
14 #define INTERVAL (gil_interval >= 1 ? gil_interval : 1)
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
15
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
16 /* Enable if you want to force the switching of threads at least every `gil_interval` */
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
17 #undef FORCE_SWITCHING
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
18 #define FORCE_SWITCHING
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
19
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
20
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
21 /*
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
22 Notes about the implementation:
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
23
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
24 - The GIL is just a boolean variable (gil_locked) whose access is protected
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
25 by a mutex (gil_mutex), and whose changes are signalled by a condition
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
26 variable (gil_cond). gil_mutex is taken for short periods of time,
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
27 and therefore mostly uncontended.
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
28
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
29 - In the GIL-holding thread, the main loop (PyEval_EvalFrameEx) must be
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
30 able to release the GIL on demand by another thread. A volatile boolean
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
31 variable (gil_drop_request) is used for that purpose, which is checked
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
32 at every turn of the eval loop. That variable is set after a wait of
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
33 `interval` microseconds on `gil_cond` has timed out.
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
34
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
35 [Actually, another volatile boolean variable (eval_breaker) is used
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
36 which ORs several conditions into one. Volatile booleans are
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
37 sufficient as inter-thread signalling means since Python is run
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
38 on cache-coherent architectures only.]
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
39
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
40 - A thread wanting to take the GIL will first let pass a given amount of
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
41 time (`interval` microseconds) before setting gil_drop_request. This
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
42 encourages a defined switching period, but doesn't enforce it since
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
43 opcodes can take an arbitrary time to execute.
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
44
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
45 The `interval` value is available for the user to read and modify
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
46 using the Python API `sys.{get,set}switchinterval()`.
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
47
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
48 - When a thread releases the GIL and gil_drop_request is set, that thread
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
49 ensures that another GIL-awaiting thread gets scheduled.
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
50 It does so by waiting on a condition variable (switch_cond) until
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
51 the value of gil_last_holder is changed to something else than its
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
52 own thread state pointer, indicating that another thread was able to
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
53 take the GIL.
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
54
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
55 This is meant to prohibit the latency-adverse behaviour on multi-core
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
56 machines where one thread would speculatively release the GIL, but still
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
57 run and end up being the first to re-acquire it, making the "timeslices"
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
58 much longer than expected.
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
59 (Note: this mechanism is enabled with FORCE_SWITCHING above)
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
60 */
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
61
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
62 #ifndef _POSIX_THREADS
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
63 /* This means pthreads are not implemented in libc headers, hence the macro
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
64 not present in unistd.h. But they still can be implemented as an external
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
65 library (e.g. gnu pth in pthread emulation) */
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
66 # ifdef HAVE_PTHREAD_H
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
67 # include <pthread.h> /* _POSIX_THREADS */
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
68 # endif
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
69 #endif
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
70
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
71
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
72 #ifdef _POSIX_THREADS
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
73
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
74 /*
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
75 * POSIX support
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
76 */
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
77
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
78 #include <pthread.h>
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
79
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
80 #define ADD_MICROSECONDS(tv, interval) \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
81 do { \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
82 tv.tv_usec += (long) interval; \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
83 tv.tv_sec += tv.tv_usec / 1000000; \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
84 tv.tv_usec %= 1000000; \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
85 } while (0)
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
86
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
87 /* We assume all modern POSIX systems have gettimeofday() */
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
88 #ifdef GETTIMEOFDAY_NO_TZ
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
89 #define GETTIMEOFDAY(ptv) gettimeofday(ptv)
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
90 #else
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
91 #define GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL)
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
92 #endif
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
93
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
94 #define MUTEX_T pthread_mutex_t
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
95 #define MUTEX_INIT(mut) \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
96 if (pthread_mutex_init(&mut, NULL)) { \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
97 Py_FatalError("pthread_mutex_init(" #mut ") failed"); };
64709
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
98 #define MUTEX_FINI(mut) \
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
99 if (pthread_mutex_destroy(&mut)) { \
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
100 Py_FatalError("pthread_mutex_destroy(" #mut ") failed"); };
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
101 #define MUTEX_LOCK(mut) \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
102 if (pthread_mutex_lock(&mut)) { \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
103 Py_FatalError("pthread_mutex_lock(" #mut ") failed"); };
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
104 #define MUTEX_UNLOCK(mut) \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
105 if (pthread_mutex_unlock(&mut)) { \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
106 Py_FatalError("pthread_mutex_unlock(" #mut ") failed"); };
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
107
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
108 #define COND_T pthread_cond_t
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
109 #define COND_INIT(cond) \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
110 if (pthread_cond_init(&cond, NULL)) { \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
111 Py_FatalError("pthread_cond_init(" #cond ") failed"); };
64709
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
112 #define COND_FINI(cond) \
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
113 if (pthread_cond_destroy(&cond)) { \
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
114 Py_FatalError("pthread_cond_destroy(" #cond ") failed"); };
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
115 #define COND_SIGNAL(cond) \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
116 if (pthread_cond_signal(&cond)) { \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
117 Py_FatalError("pthread_cond_signal(" #cond ") failed"); };
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
118 #define COND_WAIT(cond, mut) \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
119 if (pthread_cond_wait(&cond, &mut)) { \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
120 Py_FatalError("pthread_cond_wait(" #cond ") failed"); };
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
121 #define COND_TIMED_WAIT(cond, mut, microseconds, timeout_result) \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
122 { \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
123 int r; \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
124 struct timespec ts; \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
125 struct timeval deadline; \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
126 \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
127 GETTIMEOFDAY(&deadline); \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
128 ADD_MICROSECONDS(deadline, microseconds); \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
129 ts.tv_sec = deadline.tv_sec; \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
130 ts.tv_nsec = deadline.tv_usec * 1000; \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
131 \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
132 r = pthread_cond_timedwait(&cond, &mut, &ts); \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
133 if (r == ETIMEDOUT) \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
134 timeout_result = 1; \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
135 else if (r) \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
136 Py_FatalError("pthread_cond_timedwait(" #cond ") failed"); \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
137 else \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
138 timeout_result = 0; \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
139 } \
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
140
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
141 #elif defined(NT_THREADS)
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
142
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
143 /*
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
144 * Windows (2000 and later, as well as (hopefully) CE) support
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
145 */
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
146
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
147 #include <windows.h>
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
148
63911
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
149 #define MUTEX_T CRITICAL_SECTION
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
150 #define MUTEX_INIT(mut) do { \
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
151 if (!(InitializeCriticalSectionAndSpinCount(&(mut), 4000))) \
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
152 Py_FatalError("CreateMutex(" #mut ") failed"); \
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
153 } while (0)
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
154 #define MUTEX_FINI(mut) \
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
155 DeleteCriticalSection(&(mut))
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
156 #define MUTEX_LOCK(mut) \
63911
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
157 EnterCriticalSection(&(mut))
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
158 #define MUTEX_UNLOCK(mut) \
63911
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
159 LeaveCriticalSection(&(mut))
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
160
63911
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
161 /* We emulate condition variables with a semaphore.
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
162 We use a Semaphore rather than an auto-reset event, because although
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
163 an auto-resent event might appear to solve the lost-wakeup bug (race
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
164 condition between releasing the outer lock and waiting) because it
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
165 maintains state even though a wait hasn't happened, there is still
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
166 a lost wakeup problem if more than one thread are interrupted in the
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
167 critical place. A semaphore solves that.
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
168 Because it is ok to signal a condition variable with no one
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
169 waiting, we need to keep track of the number of
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
170 waiting threads. Otherwise, the semaphore's state could rise
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
171 without bound.
57191
c717fe993085 Our condition variable emulation under Windows is imperfect, which
Antoine Pitrou <solipsis@pitrou.net>
parents: 57175
diff changeset
172
63911
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
173 Generic emulations of the pthread_cond_* API using
57191
c717fe993085 Our condition variable emulation under Windows is imperfect, which
Antoine Pitrou <solipsis@pitrou.net>
parents: 57175
diff changeset
174 Win32 functions can be found on the Web.
c717fe993085 Our condition variable emulation under Windows is imperfect, which
Antoine Pitrou <solipsis@pitrou.net>
parents: 57175
diff changeset
175 The following read can be edificating (or not):
c717fe993085 Our condition variable emulation under Windows is imperfect, which
Antoine Pitrou <solipsis@pitrou.net>
parents: 57175
diff changeset
176 http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
c717fe993085 Our condition variable emulation under Windows is imperfect, which
Antoine Pitrou <solipsis@pitrou.net>
parents: 57175
diff changeset
177 */
63911
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
178 typedef struct COND_T
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
179 {
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
180 HANDLE sem; /* the semaphore */
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
181 int n_waiting; /* how many are unreleased */
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
182 } COND_T;
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
183
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
184 __inline static void _cond_init(COND_T *cond)
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
185 {
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
186 /* A semaphore with a large max value, The positive value
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
187 * is only needed to catch those "lost wakeup" events and
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
188 * race conditions when a timed wait elapses.
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
189 */
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
190 if (!(cond->sem = CreateSemaphore(NULL, 0, 1000, NULL)))
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
191 Py_FatalError("CreateSemaphore() failed");
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
192 cond->n_waiting = 0;
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
193 }
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
194
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
195 __inline static void _cond_fini(COND_T *cond)
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
196 {
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
197 BOOL ok = CloseHandle(cond->sem);
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
198 if (!ok)
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
199 Py_FatalError("CloseHandle() failed");
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
200 }
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
201
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
202 __inline static void _cond_wait(COND_T *cond, MUTEX_T *mut)
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
203 {
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
204 ++cond->n_waiting;
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
205 MUTEX_UNLOCK(*mut);
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
206 /* "lost wakeup bug" would occur if the caller were interrupted here,
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
207 * but we are safe because we are using a semaphore wich has an internal
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
208 * count.
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
209 */
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
210 if (WaitForSingleObject(cond->sem, INFINITE) == WAIT_FAILED)
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
211 Py_FatalError("WaitForSingleObject() failed");
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
212 MUTEX_LOCK(*mut);
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
213 }
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
214
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
215 __inline static int _cond_timed_wait(COND_T *cond, MUTEX_T *mut,
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
216 int us)
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
217 {
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
218 DWORD r;
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
219 ++cond->n_waiting;
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
220 MUTEX_UNLOCK(*mut);
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
221 r = WaitForSingleObject(cond->sem, us / 1000);
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
222 if (r == WAIT_FAILED)
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
223 Py_FatalError("WaitForSingleObject() failed");
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
224 MUTEX_LOCK(*mut);
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
225 if (r == WAIT_TIMEOUT)
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
226 --cond->n_waiting;
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
227 /* Here we have a benign race condition with _cond_signal. If the
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
228 * wait operation has timed out, but before we can acquire the
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
229 * mutex again to decrement n_waiting, a thread holding the mutex
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
230 * still sees a positive n_waiting value and may call
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
231 * ReleaseSemaphore and decrement n_waiting.
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
232 * This will cause n_waiting to be decremented twice.
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
233 * This is benign, though, because ReleaseSemaphore will also have
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
234 * been called, leaving the semaphore state positive. We may
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
235 * thus end up with semaphore in state 1, and n_waiting == -1, and
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
236 * the next time someone calls _cond_wait(), that thread will
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
237 * pass right through, decrementing the semaphore state and
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
238 * incrementing n_waiting, thus correcting the extra _cond_signal.
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
239 */
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
240 return r == WAIT_TIMEOUT;
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
241 }
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
242
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
243 __inline static void _cond_signal(COND_T *cond) {
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
244 /* NOTE: This must be called with the mutex held */
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
245 if (cond->n_waiting > 0) {
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
246 if (!ReleaseSemaphore(cond->sem, 1, NULL))
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
247 Py_FatalError("ReleaseSemaphore() failed");
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
248 --cond->n_waiting;
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
249 }
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
250 }
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
251
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
252 #define COND_INIT(cond) \
63911
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
253 _cond_init(&(cond))
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
254 #define COND_FINI(cond) \
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
255 _cond_fini(&(cond))
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
256 #define COND_SIGNAL(cond) \
63911
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
257 _cond_signal(&(cond))
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
258 #define COND_WAIT(cond, mut) \
63911
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
259 _cond_wait(&(cond), &(mut))
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
260 #define COND_TIMED_WAIT(cond, mut, us, timeout_result) do { \
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
261 (timeout_result) = _cond_timed_wait(&(cond), &(mut), us); \
39092f86b0af Issue #8411: new condition variable emulation under Windows for the new GIL,
Antoine Pitrou <solipsis@pitrou.net>
parents: 61184
diff changeset
262 } while (0)
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
263
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
264 #else
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
265
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
266 #error You need either a POSIX-compatible or a Windows system!
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
267
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
268 #endif /* _POSIX_THREADS, NT_THREADS */
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
269
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
270
61184
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
271 /* Whether the GIL is already taken (-1 if uninitialized). This is atomic
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
272 because it can be read without any lock taken in ceval.c. */
61184
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
273 static _Py_atomic_int gil_locked = {-1};
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
274 /* Number of GIL switches since the beginning. */
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
275 static unsigned long gil_switch_number = 0;
61184
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
276 /* Last PyThreadState holding / having held the GIL. This helps us know
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
277 whether anyone else was scheduled after we dropped the GIL. */
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
278 static _Py_atomic_address gil_last_holder = {NULL};
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
279
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
280 /* This condition variable allows one or several threads to wait until
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
281 the GIL is released. In addition, the mutex also protects the above
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
282 variables. */
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
283 static COND_T gil_cond;
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
284 static MUTEX_T gil_mutex;
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
285
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
286 #ifdef FORCE_SWITCHING
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
287 /* This condition variable helps the GIL-releasing thread wait for
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
288 a GIL-awaiting thread to be scheduled and take the GIL. */
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
289 static COND_T switch_cond;
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
290 static MUTEX_T switch_mutex;
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
291 #endif
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
292
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
293
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
294 static int gil_created(void)
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
295 {
61184
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
296 return _Py_atomic_load_explicit(&gil_locked, _Py_memory_order_acquire) >= 0;
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
297 }
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
298
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
299 static void create_gil(void)
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
300 {
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
301 MUTEX_INIT(gil_mutex);
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
302 #ifdef FORCE_SWITCHING
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
303 MUTEX_INIT(switch_mutex);
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
304 #endif
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
305 COND_INIT(gil_cond);
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
306 #ifdef FORCE_SWITCHING
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
307 COND_INIT(switch_cond);
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
308 #endif
61184
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
309 _Py_atomic_store_relaxed(&gil_last_holder, NULL);
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
310 _Py_ANNOTATE_RWLOCK_CREATE(&gil_locked);
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
311 _Py_atomic_store_explicit(&gil_locked, 0, _Py_memory_order_release);
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
312 }
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
313
64709
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
314 static void destroy_gil(void)
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
315 {
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
316 MUTEX_FINI(gil_mutex);
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
317 #ifdef FORCE_SWITCHING
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
318 MUTEX_FINI(switch_mutex);
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
319 #endif
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
320 COND_FINI(gil_cond);
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
321 #ifdef FORCE_SWITCHING
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
322 COND_FINI(switch_cond);
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
323 #endif
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
324 _Py_atomic_store_explicit(&gil_locked, -1, _Py_memory_order_release);
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
325 _Py_ANNOTATE_RWLOCK_DESTROY(&gil_locked);
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
326 }
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
327
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
328 static void recreate_gil(void)
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
329 {
61184
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
330 _Py_ANNOTATE_RWLOCK_DESTROY(&gil_locked);
64709
557e2537c9ae Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
Antoine Pitrou <solipsis@pitrou.net>
parents: 63911
diff changeset
331 /* XXX should we destroy the old OS resources here? */
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
332 create_gil();
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
333 }
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
334
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
335 static void drop_gil(PyThreadState *tstate)
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
336 {
61184
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
337 if (!_Py_atomic_load_relaxed(&gil_locked))
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
338 Py_FatalError("drop_gil: GIL is not locked");
67603
2930393f0bbb Fix the GIL with subinterpreters. Hopefully this will allow mod_wsgi to work with 3.2.
Antoine Pitrou <solipsis@pitrou.net>
parents: 64709
diff changeset
339 /* tstate is allowed to be NULL (early interpreter init) */
2930393f0bbb Fix the GIL with subinterpreters. Hopefully this will allow mod_wsgi to work with 3.2.
Antoine Pitrou <solipsis@pitrou.net>
parents: 64709
diff changeset
340 if (tstate != NULL) {
2930393f0bbb Fix the GIL with subinterpreters. Hopefully this will allow mod_wsgi to work with 3.2.
Antoine Pitrou <solipsis@pitrou.net>
parents: 64709
diff changeset
341 /* Sub-interpreter support: threads might have been switched
2930393f0bbb Fix the GIL with subinterpreters. Hopefully this will allow mod_wsgi to work with 3.2.
Antoine Pitrou <solipsis@pitrou.net>
parents: 64709
diff changeset
342 under our feet using PyThreadState_Swap(). Fix the GIL last
2930393f0bbb Fix the GIL with subinterpreters. Hopefully this will allow mod_wsgi to work with 3.2.
Antoine Pitrou <solipsis@pitrou.net>
parents: 64709
diff changeset
343 holder variable so that our heuristics work. */
2930393f0bbb Fix the GIL with subinterpreters. Hopefully this will allow mod_wsgi to work with 3.2.
Antoine Pitrou <solipsis@pitrou.net>
parents: 64709
diff changeset
344 _Py_atomic_store_relaxed(&gil_last_holder, tstate);
2930393f0bbb Fix the GIL with subinterpreters. Hopefully this will allow mod_wsgi to work with 3.2.
Antoine Pitrou <solipsis@pitrou.net>
parents: 64709
diff changeset
345 }
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
346
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
347 MUTEX_LOCK(gil_mutex);
61184
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
348 _Py_ANNOTATE_RWLOCK_RELEASED(&gil_locked, /*is_write=*/1);
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
349 _Py_atomic_store_relaxed(&gil_locked, 0);
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
350 COND_SIGNAL(gil_cond);
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
351 MUTEX_UNLOCK(gil_mutex);
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
352
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
353 #ifdef FORCE_SWITCHING
61184
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
354 if (_Py_atomic_load_relaxed(&gil_drop_request) && tstate != NULL) {
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
355 MUTEX_LOCK(switch_mutex);
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
356 /* Not switched yet => wait */
61184
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
357 if (_Py_atomic_load_relaxed(&gil_last_holder) == tstate) {
57203
f9a50cede6a9 Try to strengthen condition-waiting under Windows.
Antoine Pitrou <solipsis@pitrou.net>
parents: 57191
diff changeset
358 RESET_GIL_DROP_REQUEST();
57191
c717fe993085 Our condition variable emulation under Windows is imperfect, which
Antoine Pitrou <solipsis@pitrou.net>
parents: 57175
diff changeset
359 /* NOTE: if COND_WAIT does not atomically start waiting when
c717fe993085 Our condition variable emulation under Windows is imperfect, which
Antoine Pitrou <solipsis@pitrou.net>
parents: 57175
diff changeset
360 releasing the mutex, another thread can run through, take
c717fe993085 Our condition variable emulation under Windows is imperfect, which
Antoine Pitrou <solipsis@pitrou.net>
parents: 57175
diff changeset
361 the GIL and drop it again, and reset the condition
57203
f9a50cede6a9 Try to strengthen condition-waiting under Windows.
Antoine Pitrou <solipsis@pitrou.net>
parents: 57191
diff changeset
362 before we even had a chance to wait for it. */
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
363 COND_WAIT(switch_cond, switch_mutex);
57203
f9a50cede6a9 Try to strengthen condition-waiting under Windows.
Antoine Pitrou <solipsis@pitrou.net>
parents: 57191
diff changeset
364 }
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
365 MUTEX_UNLOCK(switch_mutex);
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
366 }
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
367 #endif
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
368 }
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
369
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
370 static void take_gil(PyThreadState *tstate)
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
371 {
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
372 int err;
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
373 if (tstate == NULL)
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
374 Py_FatalError("take_gil: NULL tstate");
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
375
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
376 err = errno;
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
377 MUTEX_LOCK(gil_mutex);
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
378
61184
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
379 if (!_Py_atomic_load_relaxed(&gil_locked))
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
380 goto _ready;
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
381
61184
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
382 while (_Py_atomic_load_relaxed(&gil_locked)) {
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
383 int timed_out = 0;
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
384 unsigned long saved_switchnum;
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
385
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
386 saved_switchnum = gil_switch_number;
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
387 COND_TIMED_WAIT(gil_cond, gil_mutex, INTERVAL, timed_out);
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
388 /* If we timed out and no switch occurred in the meantime, it is time
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
389 to ask the GIL-holding thread to drop it. */
61184
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
390 if (timed_out &&
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
391 _Py_atomic_load_relaxed(&gil_locked) &&
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
392 gil_switch_number == saved_switchnum) {
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
393 SET_GIL_DROP_REQUEST();
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
394 }
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
395 }
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
396 _ready:
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
397 #ifdef FORCE_SWITCHING
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
398 /* This mutex must be taken before modifying gil_last_holder (see drop_gil()). */
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
399 MUTEX_LOCK(switch_mutex);
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
400 #endif
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
401 /* We now hold the GIL */
61184
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
402 _Py_atomic_store_relaxed(&gil_locked, 1);
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
403 _Py_ANNOTATE_RWLOCK_ACQUIRED(&gil_locked, /*is_write=*/1);
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
404
61184
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
405 if (tstate != _Py_atomic_load_relaxed(&gil_last_holder)) {
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
406 _Py_atomic_store_relaxed(&gil_last_holder, tstate);
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
407 ++gil_switch_number;
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
408 }
61184
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
409
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
410 #ifdef FORCE_SWITCHING
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
411 COND_SIGNAL(switch_cond);
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
412 MUTEX_UNLOCK(switch_mutex);
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
413 #endif
61184
4fd3ab5fa71d Make (most of) Python's tests pass under Thread Sanitizer.
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 57203
diff changeset
414 if (_Py_atomic_load_relaxed(&gil_drop_request)) {
57175
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
415 RESET_GIL_DROP_REQUEST();
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
416 }
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
417 if (tstate->async_exc != NULL) {
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
418 _PyEval_SignalAsyncExc();
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
419 }
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
420
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
421 MUTEX_UNLOCK(gil_mutex);
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
422 errno = err;
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
423 }
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
424
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
425 void _PyEval_SetSwitchInterval(unsigned long microseconds)
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
426 {
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
427 gil_interval = microseconds;
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
428 }
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
429
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
430 unsigned long _PyEval_GetSwitchInterval()
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
431 {
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
432 return gil_interval;
fdd6484f1210 Merge in the new GIL.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
433 }