mirror of
https://github.com/python/cpython.git
synced 2025-11-25 04:34:37 +00:00
GH-93503: Add thread-specific APIs to set profiling and tracing functions in the C-API (#93504)
* gh-93503: Add APIs to set profiling and tracing functions in all threads in the C-API * Use a separate API * Fix NEWS entry * Add locks around the loop * Document ignoring exceptions * Use the new APIs in the sys module * Update docs
This commit is contained in:
parent
657976ad95
commit
e34c82abeb
10 changed files with 271 additions and 4 deletions
|
|
@ -96,6 +96,10 @@
|
|||
#define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) _Py_atomic_load_relaxed(ATOMIC_VAL)
|
||||
#endif
|
||||
|
||||
#define HEAD_LOCK(runtime) \
|
||||
PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK)
|
||||
#define HEAD_UNLOCK(runtime) \
|
||||
PyThread_release_lock((runtime)->interpreters.mutex)
|
||||
|
||||
/* Forward declarations */
|
||||
static PyObject *trace_call_function(
|
||||
|
|
@ -6455,6 +6459,27 @@ PyEval_SetProfile(Py_tracefunc func, PyObject *arg)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
PyEval_SetProfileAllThreads(Py_tracefunc func, PyObject *arg)
|
||||
{
|
||||
PyThreadState *this_tstate = _PyThreadState_GET();
|
||||
PyInterpreterState* interp = this_tstate->interp;
|
||||
|
||||
_PyRuntimeState *runtime = &_PyRuntime;
|
||||
HEAD_LOCK(runtime);
|
||||
PyThreadState* ts = PyInterpreterState_ThreadHead(interp);
|
||||
HEAD_UNLOCK(runtime);
|
||||
|
||||
while (ts) {
|
||||
if (_PyEval_SetProfile(ts, func, arg) < 0) {
|
||||
_PyErr_WriteUnraisableMsg("in PyEval_SetProfileAllThreads", NULL);
|
||||
}
|
||||
HEAD_LOCK(runtime);
|
||||
ts = PyThreadState_Next(ts);
|
||||
HEAD_UNLOCK(runtime);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
|
||||
{
|
||||
|
|
@ -6508,6 +6533,26 @@ PyEval_SetTrace(Py_tracefunc func, PyObject *arg)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
PyEval_SetTraceAllThreads(Py_tracefunc func, PyObject *arg)
|
||||
{
|
||||
PyThreadState *this_tstate = _PyThreadState_GET();
|
||||
PyInterpreterState* interp = this_tstate->interp;
|
||||
|
||||
_PyRuntimeState *runtime = &_PyRuntime;
|
||||
HEAD_LOCK(runtime);
|
||||
PyThreadState* ts = PyInterpreterState_ThreadHead(interp);
|
||||
HEAD_UNLOCK(runtime);
|
||||
|
||||
while (ts) {
|
||||
if (_PyEval_SetTrace(ts, func, arg) < 0) {
|
||||
_PyErr_WriteUnraisableMsg("in PyEval_SetTraceAllThreads", NULL);
|
||||
}
|
||||
HEAD_LOCK(runtime);
|
||||
ts = PyThreadState_Next(ts);
|
||||
HEAD_UNLOCK(runtime);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_PyEval_SetCoroutineOriginTrackingDepth(int depth)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue