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