Linux vps-61133.fhnet.fr 4.9.0-19-amd64 #1 SMP Debian 4.9.320-2 (2022-06-30) x86_64
Apache/2.4.25 (Debian)
Server IP : 93.113.207.21 & Your IP : 216.73.216.119
Domains :
Cant Read [ /etc/named.conf ]
User : www-data
Terminal
Auto Root
Create File
Create Folder
Localroot Suggester
Backdoor Destroyer
Readme
/
usr /
src /
Python-3.10.14 /
Python /
Delete
Unzip
Name
Size
Permission
Date
Action
clinic
[ DIR ]
drwxr-xr-x
2024-03-19 22:46
Python-ast.c
403.1
KB
-rw-r--r--
2024-03-19 22:46
Python-ast.gcda
73.55
KB
-rw-r--r--
2025-06-04 09:21
Python-ast.o
1.64
MB
-rw-r--r--
2025-06-04 09:22
README
62
B
-rw-r--r--
2024-03-19 22:46
_warnings.c
37.47
KB
-rw-r--r--
2024-03-19 22:46
_warnings.gcda
10.5
KB
-rw-r--r--
2025-06-04 09:21
_warnings.o
274.36
KB
-rw-r--r--
2025-06-04 09:22
asdl.c
188
B
-rw-r--r--
2024-03-19 22:46
asdl.gcda
3.98
KB
-rw-r--r--
2025-06-04 09:21
asdl.o
41.46
KB
-rw-r--r--
2025-06-04 09:22
ast.c
33.83
KB
-rw-r--r--
2024-03-19 22:46
ast.gcda
8.98
KB
-rw-r--r--
2025-06-04 09:21
ast.o
162
KB
-rw-r--r--
2025-06-04 09:22
ast_opt.c
29.15
KB
-rw-r--r--
2024-03-19 22:46
ast_opt.gcda
10.67
KB
-rw-r--r--
2025-06-04 09:21
ast_opt.o
464.67
KB
-rw-r--r--
2025-06-04 09:22
ast_unparse.c
25.85
KB
-rw-r--r--
2024-03-19 22:46
ast_unparse.gcda
9.81
KB
-rw-r--r--
2025-06-04 09:21
ast_unparse.o
204.5
KB
-rw-r--r--
2025-06-04 09:22
bltinmodule.c
88.5
KB
-rw-r--r--
2024-03-19 22:46
bltinmodule.gcda
17.87
KB
-rw-r--r--
2025-06-04 09:21
bltinmodule.o
611.81
KB
-rw-r--r--
2025-06-04 09:22
bootstrap_hash.c
18.18
KB
-rw-r--r--
2024-03-19 22:46
bootstrap_hash.gcda
4.34
KB
-rw-r--r--
2025-06-04 09:21
bootstrap_hash.o
63.27
KB
-rw-r--r--
2025-06-04 09:22
ceval.c
206.97
KB
-rw-r--r--
2024-03-19 22:46
ceval.gcda
29.57
KB
-rw-r--r--
2025-06-04 09:21
ceval.o
1.21
MB
-rw-r--r--
2025-06-04 09:22
ceval_gil.h
12.19
KB
-rw-r--r--
2024-03-19 22:46
codecs.c
45.02
KB
-rw-r--r--
2024-03-19 22:46
codecs.gcda
12.75
KB
-rw-r--r--
2025-06-04 09:21
codecs.o
329.38
KB
-rw-r--r--
2025-06-04 09:22
compile.c
233.08
KB
-rw-r--r--
2024-03-19 22:46
compile.gcda
43.95
KB
-rw-r--r--
2025-06-04 09:21
compile.o
1.79
MB
-rw-r--r--
2025-06-04 09:22
condvar.h
8.44
KB
-rw-r--r--
2024-03-19 22:46
context.c
30.93
KB
-rw-r--r--
2024-03-19 22:46
context.gcda
9.95
KB
-rw-r--r--
2025-06-04 09:21
context.o
200.97
KB
-rw-r--r--
2025-06-04 09:22
dtoa.c
78.28
KB
-rw-r--r--
2024-03-19 22:46
dtoa.gcda
10.32
KB
-rw-r--r--
2025-06-04 09:21
dtoa.o
658.92
KB
-rw-r--r--
2025-06-04 09:22
dup2.c
759
B
-rw-r--r--
2024-03-19 22:46
dynamic_annotations.c
6.59
KB
-rw-r--r--
2024-03-19 22:46
dynamic_annotations.o
2.16
KB
-rw-r--r--
2025-06-04 09:22
dynload_hpux.c
2.12
KB
-rw-r--r--
2024-03-19 22:46
dynload_shlib.c
3.47
KB
-rw-r--r--
2024-03-19 22:46
dynload_shlib.gcda
3.77
KB
-rw-r--r--
2025-06-04 09:21
dynload_shlib.o
78.03
KB
-rw-r--r--
2025-06-04 09:22
dynload_stub.c
186
B
-rw-r--r--
2024-03-19 22:46
dynload_win.c
9.97
KB
-rw-r--r--
2024-03-19 22:46
errors.c
49.3
KB
-rw-r--r--
2024-03-19 22:46
errors.gcda
11.97
KB
-rw-r--r--
2025-06-04 09:21
errors.o
604.46
KB
-rw-r--r--
2025-06-04 09:22
fileutils.c
65.03
KB
-rw-r--r--
2024-03-19 22:46
fileutils.gcda
9.9
KB
-rw-r--r--
2025-06-04 09:21
fileutils.o
235.27
KB
-rw-r--r--
2025-06-04 09:22
formatter_unicode.c
50.35
KB
-rw-r--r--
2024-03-19 22:46
formatter_unicode.gcda
7.99
KB
-rw-r--r--
2025-06-04 09:21
formatter_unicode.o
352.49
KB
-rw-r--r--
2025-06-04 09:22
frozen.c
1.31
KB
-rw-r--r--
2024-03-19 22:46
frozen.o
122.48
KB
-rw-r--r--
2025-06-04 09:22
frozen_hello.h
547
B
-rw-r--r--
2024-03-19 22:46
frozenmain.c
3.12
KB
-rw-r--r--
2024-03-19 22:46
frozenmain.o
55.7
KB
-rw-r--r--
2025-06-04 09:22
future.c
4.35
KB
-rw-r--r--
2024-03-19 22:46
future.gcda
3.91
KB
-rw-r--r--
2025-06-04 09:21
future.o
69.3
KB
-rw-r--r--
2025-06-04 09:22
getargs.c
83.81
KB
-rw-r--r--
2024-03-19 22:46
getargs.gcda
14.68
KB
-rw-r--r--
2025-06-04 09:21
getargs.o
702.23
KB
-rw-r--r--
2025-06-04 09:22
getcompiler.c
534
B
-rw-r--r--
2024-03-19 22:46
getcompiler.gcda
3.48
KB
-rw-r--r--
2025-06-04 09:21
getcompiler.o
31.86
KB
-rw-r--r--
2025-06-04 09:22
getcopyright.c
511
B
-rw-r--r--
2024-03-19 22:46
getcopyright.gcda
3.48
KB
-rw-r--r--
2025-06-04 09:21
getcopyright.o
32.27
KB
-rw-r--r--
2025-06-04 09:22
getopt.c
4.6
KB
-rw-r--r--
2024-03-19 22:46
getopt.gcda
3.82
KB
-rw-r--r--
2025-06-04 09:21
getopt.o
43.34
KB
-rw-r--r--
2025-06-04 09:22
getplatform.c
133
B
-rw-r--r--
2024-03-19 22:46
getplatform.gcda
3.48
KB
-rw-r--r--
2025-06-04 09:21
getplatform.o
31.85
KB
-rw-r--r--
2025-06-04 09:22
getversion.c
308
B
-rw-r--r--
2024-03-19 22:46
getversion.gcda
3.5
KB
-rw-r--r--
2025-06-04 09:21
getversion.o
32.93
KB
-rw-r--r--
2025-06-04 09:22
hamt.c
78.82
KB
-rw-r--r--
2024-03-19 22:46
hamt.gcda
11.18
KB
-rw-r--r--
2025-06-04 09:21
hamt.o
257.84
KB
-rw-r--r--
2025-06-04 09:22
hashtable.c
11.17
KB
-rw-r--r--
2024-03-19 22:46
hashtable.gcda
5.66
KB
-rw-r--r--
2025-06-04 09:21
hashtable.o
84.36
KB
-rw-r--r--
2025-06-04 09:22
import.c
62.01
KB
-rw-r--r--
2024-03-19 22:46
import.gcda
17.11
KB
-rw-r--r--
2025-06-04 09:21
import.o
461.4
KB
-rw-r--r--
2025-06-04 09:22
importdl.c
7.32
KB
-rw-r--r--
2024-03-19 22:46
importdl.gcda
4.35
KB
-rw-r--r--
2025-06-04 09:21
importdl.h
487
B
-rw-r--r--
2024-03-19 22:46
importdl.o
71.44
KB
-rw-r--r--
2025-06-04 09:22
importlib.h
99.12
KB
-rw-r--r--
2024-03-19 22:46
importlib_external.h
147.15
KB
-rw-r--r--
2024-03-19 22:46
importlib_zipimport.h
57.35
KB
-rw-r--r--
2024-03-19 22:46
initconfig.c
89.33
KB
-rw-r--r--
2024-03-19 22:46
initconfig.gcda
20.45
KB
-rw-r--r--
2025-06-04 09:21
initconfig.o
482.04
KB
-rw-r--r--
2025-06-04 09:22
makeopcodetargets.py
1.55
KB
-rwxr-xr-x
2024-03-19 22:46
marshal.c
48.33
KB
-rw-r--r--
2024-03-19 22:46
marshal.gcda
13.91
KB
-rw-r--r--
2025-06-04 09:21
marshal.o
325.08
KB
-rw-r--r--
2025-06-04 09:22
modsupport.c
18.12
KB
-rw-r--r--
2024-03-19 22:46
modsupport.gcda
6.66
KB
-rw-r--r--
2025-06-04 09:21
modsupport.o
243.86
KB
-rw-r--r--
2025-06-04 09:22
mysnprintf.c
2.49
KB
-rw-r--r--
2024-03-19 22:46
mysnprintf.gcda
3.56
KB
-rw-r--r--
2025-06-04 09:21
mysnprintf.o
39.3
KB
-rw-r--r--
2025-06-04 09:22
mystrtoul.c
8.09
KB
-rw-r--r--
2024-03-19 22:46
mystrtoul.gcda
3.93
KB
-rw-r--r--
2025-06-04 09:21
mystrtoul.o
64.22
KB
-rw-r--r--
2025-06-04 09:22
opcode_targets.h
6.31
KB
-rw-r--r--
2024-03-19 22:46
pathconfig.c
19.75
KB
-rw-r--r--
2024-03-19 22:46
pathconfig.gcda
7.42
KB
-rw-r--r--
2025-06-04 09:21
pathconfig.o
110.59
KB
-rw-r--r--
2025-06-04 09:22
preconfig.c
25.21
KB
-rw-r--r--
2024-03-19 22:46
preconfig.gcda
6.76
KB
-rw-r--r--
2025-06-04 09:21
preconfig.o
140.21
KB
-rw-r--r--
2025-06-04 09:22
pyarena.c
5.52
KB
-rw-r--r--
2024-03-19 22:46
pyarena.gcda
3.97
KB
-rw-r--r--
2025-06-04 09:21
pyarena.o
48.03
KB
-rw-r--r--
2025-06-04 09:22
pyctype.c
7.73
KB
-rw-r--r--
2024-03-19 22:46
pyctype.o
32.77
KB
-rw-r--r--
2025-06-04 09:22
pyfpe.c
345
B
-rw-r--r--
2024-03-19 22:46
pyfpe.o
4.01
KB
-rw-r--r--
2025-06-04 09:22
pyhash.c
13.45
KB
-rw-r--r--
2024-03-19 22:46
pyhash.gcda
4.16
KB
-rw-r--r--
2025-06-04 09:21
pyhash.o
70.6
KB
-rw-r--r--
2025-06-04 09:22
pylifecycle.c
80.77
KB
-rw-r--r--
2024-03-19 22:46
pylifecycle.gcda
15.06
KB
-rw-r--r--
2025-06-04 09:21
pylifecycle.o
390.44
KB
-rw-r--r--
2025-06-04 09:22
pymath.c
1.6
KB
-rw-r--r--
2024-03-19 22:46
pymath.gcda
3.54
KB
-rw-r--r--
2025-06-04 09:21
pymath.o
32.34
KB
-rw-r--r--
2025-06-04 09:22
pystate.c
56.36
KB
-rw-r--r--
2024-03-19 22:46
pystate.gcda
12.61
KB
-rw-r--r--
2025-06-04 09:21
pystate.o
238.3
KB
-rw-r--r--
2025-06-04 09:22
pystrcmp.c
753
B
-rw-r--r--
2024-03-19 22:46
pystrcmp.gcda
3.62
KB
-rw-r--r--
2025-06-04 09:21
pystrcmp.o
37.12
KB
-rw-r--r--
2025-06-04 09:22
pystrhex.c
5.24
KB
-rw-r--r--
2024-03-19 22:46
pystrhex.gcda
4.09
KB
-rw-r--r--
2025-06-04 09:21
pystrhex.o
55.29
KB
-rw-r--r--
2025-06-04 09:22
pystrtod.c
40.06
KB
-rw-r--r--
2024-03-19 22:46
pystrtod.gcda
5.14
KB
-rw-r--r--
2025-06-04 09:21
pystrtod.o
96.01
KB
-rw-r--r--
2025-06-04 09:22
pythonrun.c
42.71
KB
-rw-r--r--
2024-03-19 22:46
pythonrun.gcda
11.89
KB
-rw-r--r--
2025-06-04 09:21
pythonrun.o
282.42
KB
-rw-r--r--
2025-06-04 09:22
pytime.c
28.68
KB
-rw-r--r--
2024-03-19 22:46
pytime.gcda
7.47
KB
-rw-r--r--
2025-06-04 09:21
pytime.o
120.86
KB
-rw-r--r--
2025-06-04 09:22
stdlib_module_names.h
3.49
KB
-rw-r--r--
2024-03-19 22:46
structmember.c
8.83
KB
-rw-r--r--
2024-03-19 22:46
structmember.gcda
4.83
KB
-rw-r--r--
2025-06-04 09:21
structmember.o
73.16
KB
-rw-r--r--
2025-06-04 09:22
suggestions.c
8.46
KB
-rw-r--r--
2024-03-19 22:46
suggestions.gcda
4.29
KB
-rw-r--r--
2025-06-04 09:21
suggestions.o
57.27
KB
-rw-r--r--
2025-06-04 09:22
symtable.c
72.25
KB
-rw-r--r--
2024-03-19 22:46
symtable.gcda
15.05
KB
-rw-r--r--
2025-06-04 09:21
symtable.o
638.03
KB
-rw-r--r--
2025-06-04 09:22
sysmodule.c
94.57
KB
-rw-r--r--
2024-03-19 22:46
sysmodule.gcda
19.89
KB
-rw-r--r--
2025-06-04 09:21
sysmodule.o
579.73
KB
-rw-r--r--
2025-06-04 09:22
thread.c
5.8
KB
-rw-r--r--
2024-03-19 22:46
thread.gcda
6.58
KB
-rw-r--r--
2025-06-04 09:21
thread.o
133.44
KB
-rw-r--r--
2025-06-04 09:22
thread_nt.h
12.16
KB
-rw-r--r--
2024-03-19 22:46
thread_pthread.h
25.32
KB
-rw-r--r--
2024-03-19 22:46
traceback.c
25.55
KB
-rw-r--r--
2024-03-19 22:46
traceback.gcda
8.3
KB
-rw-r--r--
2025-06-04 09:21
traceback.o
169.99
KB
-rw-r--r--
2025-06-04 09:22
wordcode_helpers.h
1.25
KB
-rw-r--r--
2024-03-19 22:46
Save
Rename
/* * Implementation of the Global Interpreter Lock (GIL). */ #include <stdlib.h> #include <errno.h> #include "pycore_atomic.h" /* Notes about the implementation: - The GIL is just a boolean variable (locked) whose access is protected by a mutex (gil_mutex), and whose changes are signalled by a condition variable (gil_cond). gil_mutex is taken for short periods of time, and therefore mostly uncontended. - In the GIL-holding thread, the main loop (PyEval_EvalFrameEx) must be able to release the GIL on demand by another thread. A volatile boolean variable (gil_drop_request) is used for that purpose, which is checked at every turn of the eval loop. That variable is set after a wait of `interval` microseconds on `gil_cond` has timed out. [Actually, another volatile boolean variable (eval_breaker) is used which ORs several conditions into one. Volatile booleans are sufficient as inter-thread signalling means since Python is run on cache-coherent architectures only.] - A thread wanting to take the GIL will first let pass a given amount of time (`interval` microseconds) before setting gil_drop_request. This encourages a defined switching period, but doesn't enforce it since opcodes can take an arbitrary time to execute. The `interval` value is available for the user to read and modify using the Python API `sys.{get,set}switchinterval()`. - When a thread releases the GIL and gil_drop_request is set, that thread ensures that another GIL-awaiting thread gets scheduled. It does so by waiting on a condition variable (switch_cond) until the value of last_holder is changed to something else than its own thread state pointer, indicating that another thread was able to take the GIL. This is meant to prohibit the latency-adverse behaviour on multi-core machines where one thread would speculatively release the GIL, but still run and end up being the first to re-acquire it, making the "timeslices" much longer than expected. (Note: this mechanism is enabled with FORCE_SWITCHING above) */ #include "condvar.h" #define MUTEX_INIT(mut) \ if (PyMUTEX_INIT(&(mut))) { \ Py_FatalError("PyMUTEX_INIT(" #mut ") failed"); }; #define MUTEX_FINI(mut) \ if (PyMUTEX_FINI(&(mut))) { \ Py_FatalError("PyMUTEX_FINI(" #mut ") failed"); }; #define MUTEX_LOCK(mut) \ if (PyMUTEX_LOCK(&(mut))) { \ Py_FatalError("PyMUTEX_LOCK(" #mut ") failed"); }; #define MUTEX_UNLOCK(mut) \ if (PyMUTEX_UNLOCK(&(mut))) { \ Py_FatalError("PyMUTEX_UNLOCK(" #mut ") failed"); }; #define COND_INIT(cond) \ if (PyCOND_INIT(&(cond))) { \ Py_FatalError("PyCOND_INIT(" #cond ") failed"); }; #define COND_FINI(cond) \ if (PyCOND_FINI(&(cond))) { \ Py_FatalError("PyCOND_FINI(" #cond ") failed"); }; #define COND_SIGNAL(cond) \ if (PyCOND_SIGNAL(&(cond))) { \ Py_FatalError("PyCOND_SIGNAL(" #cond ") failed"); }; #define COND_WAIT(cond, mut) \ if (PyCOND_WAIT(&(cond), &(mut))) { \ Py_FatalError("PyCOND_WAIT(" #cond ") failed"); }; #define COND_TIMED_WAIT(cond, mut, microseconds, timeout_result) \ { \ int r = PyCOND_TIMEDWAIT(&(cond), &(mut), (microseconds)); \ if (r < 0) \ Py_FatalError("PyCOND_WAIT(" #cond ") failed"); \ if (r) /* 1 == timeout, 2 == impl. can't say, so assume timeout */ \ timeout_result = 1; \ else \ timeout_result = 0; \ } \ #define DEFAULT_INTERVAL 5000 static void _gil_initialize(struct _gil_runtime_state *gil) { _Py_atomic_int uninitialized = {-1}; gil->locked = uninitialized; gil->interval = DEFAULT_INTERVAL; } static int gil_created(struct _gil_runtime_state *gil) { return (_Py_atomic_load_explicit(&gil->locked, _Py_memory_order_acquire) >= 0); } static void create_gil(struct _gil_runtime_state *gil) { MUTEX_INIT(gil->mutex); #ifdef FORCE_SWITCHING MUTEX_INIT(gil->switch_mutex); #endif COND_INIT(gil->cond); #ifdef FORCE_SWITCHING COND_INIT(gil->switch_cond); #endif _Py_atomic_store_relaxed(&gil->last_holder, 0); _Py_ANNOTATE_RWLOCK_CREATE(&gil->locked); _Py_atomic_store_explicit(&gil->locked, 0, _Py_memory_order_release); } static void destroy_gil(struct _gil_runtime_state *gil) { /* some pthread-like implementations tie the mutex to the cond * and must have the cond destroyed first. */ COND_FINI(gil->cond); MUTEX_FINI(gil->mutex); #ifdef FORCE_SWITCHING COND_FINI(gil->switch_cond); MUTEX_FINI(gil->switch_mutex); #endif _Py_atomic_store_explicit(&gil->locked, -1, _Py_memory_order_release); _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); } static void recreate_gil(struct _gil_runtime_state *gil) { _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); /* XXX should we destroy the old OS resources here? */ create_gil(gil); } static void drop_gil(struct _ceval_runtime_state *ceval, struct _ceval_state *ceval2, PyThreadState *tstate) { #ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS struct _gil_runtime_state *gil = &ceval2->gil; #else struct _gil_runtime_state *gil = &ceval->gil; #endif if (!_Py_atomic_load_relaxed(&gil->locked)) { Py_FatalError("drop_gil: GIL is not locked"); } /* tstate is allowed to be NULL (early interpreter init) */ if (tstate != NULL) { /* Sub-interpreter support: threads might have been switched under our feet using PyThreadState_Swap(). Fix the GIL last holder variable so that our heuristics work. */ _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); } MUTEX_LOCK(gil->mutex); _Py_ANNOTATE_RWLOCK_RELEASED(&gil->locked, /*is_write=*/1); _Py_atomic_store_relaxed(&gil->locked, 0); COND_SIGNAL(gil->cond); MUTEX_UNLOCK(gil->mutex); #ifdef FORCE_SWITCHING if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request) && tstate != NULL) { MUTEX_LOCK(gil->switch_mutex); /* Not switched yet => wait */ if (((PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) == tstate) { assert(is_tstate_valid(tstate)); RESET_GIL_DROP_REQUEST(tstate->interp); /* NOTE: if COND_WAIT does not atomically start waiting when releasing the mutex, another thread can run through, take the GIL and drop it again, and reset the condition before we even had a chance to wait for it. */ COND_WAIT(gil->switch_cond, gil->switch_mutex); } MUTEX_UNLOCK(gil->switch_mutex); } #endif } /* Check if a Python thread must exit immediately, rather than taking the GIL if Py_Finalize() has been called. When this function is called by a daemon thread after Py_Finalize() has been called, the GIL does no longer exist. tstate must be non-NULL. */ static inline int tstate_must_exit(PyThreadState *tstate) { /* bpo-39877: Access _PyRuntime directly rather than using tstate->interp->runtime to support calls from Python daemon threads. After Py_Finalize() has been called, tstate can be a dangling pointer: point to PyThreadState freed memory. */ PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(&_PyRuntime); return (finalizing != NULL && finalizing != tstate); } /* Take the GIL. The function saves errno at entry and restores its value at exit. tstate must be non-NULL. */ static void take_gil(PyThreadState *tstate) { int err = errno; assert(tstate != NULL); if (tstate_must_exit(tstate)) { /* bpo-39877: If Py_Finalize() has been called and tstate is not the thread which called Py_Finalize(), exit immediately the thread. This code path can be reached by a daemon thread after Py_Finalize() completes. In this case, tstate is a dangling pointer: points to PyThreadState freed memory. */ PyThread_exit_thread(); } assert(is_tstate_valid(tstate)); PyInterpreterState *interp = tstate->interp; struct _ceval_runtime_state *ceval = &interp->runtime->ceval; struct _ceval_state *ceval2 = &interp->ceval; #ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS struct _gil_runtime_state *gil = &ceval2->gil; #else struct _gil_runtime_state *gil = &ceval->gil; #endif /* Check that _PyEval_InitThreads() was called to create the lock */ assert(gil_created(gil)); MUTEX_LOCK(gil->mutex); if (!_Py_atomic_load_relaxed(&gil->locked)) { goto _ready; } int drop_requested = 0; while (_Py_atomic_load_relaxed(&gil->locked)) { unsigned long saved_switchnum = gil->switch_number; unsigned long interval = (gil->interval >= 1 ? gil->interval : 1); int timed_out = 0; COND_TIMED_WAIT(gil->cond, gil->mutex, interval, timed_out); /* If we timed out and no switch occurred in the meantime, it is time to ask the GIL-holding thread to drop it. */ if (timed_out && _Py_atomic_load_relaxed(&gil->locked) && gil->switch_number == saved_switchnum) { if (tstate_must_exit(tstate)) { MUTEX_UNLOCK(gil->mutex); // gh-96387: If the loop requested a drop request in a previous // iteration, reset the request. Otherwise, drop_gil() can // block forever waiting for the thread which exited. Drop // requests made by other threads are also reset: these threads // may have to request again a drop request (iterate one more // time). if (drop_requested) { RESET_GIL_DROP_REQUEST(interp); } PyThread_exit_thread(); } assert(is_tstate_valid(tstate)); SET_GIL_DROP_REQUEST(interp); drop_requested = 1; } } _ready: #ifdef FORCE_SWITCHING /* This mutex must be taken before modifying gil->last_holder: see drop_gil(). */ MUTEX_LOCK(gil->switch_mutex); #endif /* We now hold the GIL */ _Py_atomic_store_relaxed(&gil->locked, 1); _Py_ANNOTATE_RWLOCK_ACQUIRED(&gil->locked, /*is_write=*/1); if (tstate != (PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) { _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); ++gil->switch_number; } #ifdef FORCE_SWITCHING COND_SIGNAL(gil->switch_cond); MUTEX_UNLOCK(gil->switch_mutex); #endif if (tstate_must_exit(tstate)) { /* bpo-36475: If Py_Finalize() has been called and tstate is not the thread which called Py_Finalize(), exit immediately the thread. This code path can be reached by a daemon thread which was waiting in take_gil() while the main thread called wait_for_thread_shutdown() from Py_Finalize(). */ MUTEX_UNLOCK(gil->mutex); drop_gil(ceval, ceval2, tstate); PyThread_exit_thread(); } assert(is_tstate_valid(tstate)); if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request)) { RESET_GIL_DROP_REQUEST(interp); } else { /* bpo-40010: eval_breaker should be recomputed to be set to 1 if there is a pending signal: signal received by another thread which cannot handle signals. Note: RESET_GIL_DROP_REQUEST() calls COMPUTE_EVAL_BREAKER(). */ COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); } /* Don't access tstate if the thread must exit */ if (tstate->async_exc != NULL) { _PyEval_SignalAsyncExc(tstate->interp); } MUTEX_UNLOCK(gil->mutex); errno = err; } void _PyEval_SetSwitchInterval(unsigned long microseconds) { #ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS PyInterpreterState *interp = PyInterpreterState_Get(); struct _gil_runtime_state *gil = &interp->ceval.gil; #else struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil; #endif gil->interval = microseconds; } unsigned long _PyEval_GetSwitchInterval() { #ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS PyInterpreterState *interp = PyInterpreterState_Get(); struct _gil_runtime_state *gil = &interp->ceval.gil; #else struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil; #endif return gil->interval; }