1 | #ifndef Py_INTERNAL_GIL_H |
2 | #define Py_INTERNAL_GIL_H |
3 | #ifdef __cplusplus |
4 | extern "C" { |
5 | #endif |
6 | |
7 | #ifndef Py_BUILD_CORE |
8 | # error "this header requires Py_BUILD_CORE define" |
9 | #endif |
10 | |
11 | #include "pycore_atomic.h" /* _Py_atomic_address */ |
12 | #include "pycore_condvar.h" /* PyCOND_T */ |
13 | |
14 | #ifndef Py_HAVE_CONDVAR |
15 | # error You need either a POSIX-compatible or a Windows system! |
16 | #endif |
17 | |
18 | /* Enable if you want to force the switching of threads at least |
19 | every `interval`. */ |
20 | #undef FORCE_SWITCHING |
21 | #define FORCE_SWITCHING |
22 | |
23 | struct _gil_runtime_state { |
24 | /* microseconds (the Python API uses seconds, though) */ |
25 | unsigned long interval; |
26 | /* Last PyThreadState holding / having held the GIL. This helps us |
27 | know whether anyone else was scheduled after we dropped the GIL. */ |
28 | _Py_atomic_address last_holder; |
29 | /* Whether the GIL is already taken (-1 if uninitialized). This is |
30 | atomic because it can be read without any lock taken in ceval.c. */ |
31 | _Py_atomic_int locked; |
32 | /* Number of GIL switches since the beginning. */ |
33 | unsigned long switch_number; |
34 | /* This condition variable allows one or several threads to wait |
35 | until the GIL is released. In addition, the mutex also protects |
36 | the above variables. */ |
37 | PyCOND_T cond; |
38 | PyMUTEX_T mutex; |
39 | #ifdef FORCE_SWITCHING |
40 | /* This condition variable helps the GIL-releasing thread wait for |
41 | a GIL-awaiting thread to be scheduled and take the GIL. */ |
42 | PyCOND_T switch_cond; |
43 | PyMUTEX_T switch_mutex; |
44 | #endif |
45 | }; |
46 | |
47 | #ifdef __cplusplus |
48 | } |
49 | #endif |
50 | #endif /* !Py_INTERNAL_GIL_H */ |
51 | |