1#ifndef Py_INTERNAL_GIL_H
2#define Py_INTERNAL_GIL_H
3#ifdef __cplusplus
4extern "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
23struct _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