summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2021-10-15 14:06:30 (GMT)
committerGitHub <noreply@github.com>2021-10-15 14:06:30 (GMT)
commit547d26aa08aa5e4ec6e4f8a5587b30b39064a5ba (patch)
treef89a1327f1847ca97929efec97a12cab09478b2a /Modules
parent354c35220d25a893e502014478f6739dad6897f3 (diff)
downloadcpython-547d26aa08aa5e4ec6e4f8a5587b30b39064a5ba.zip
cpython-547d26aa08aa5e4ec6e4f8a5587b30b39064a5ba.tar.gz
cpython-547d26aa08aa5e4ec6e4f8a5587b30b39064a5ba.tar.bz2
bpo-43760: Add PyThreadState_EnterTracing() (GH-28542)
Add PyThreadState_EnterTracing() and PyThreadState_LeaveTracing() functions to the limited C API to suspend and resume tracing and profiling. Add an unit test on the PyThreadState C API to _testcapi. Add also internal _PyThreadState_DisableTracing() and _PyThreadState_ResetTracing().
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_testcapimodule.c67
1 files changed, 61 insertions, 6 deletions
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 82cfc04..6857241 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -18,29 +18,32 @@
#define PY_SSIZE_T_CLEAN
#include "Python.h"
-#include "datetime.h"
-#include "marshal.h"
+#include "frameobject.h" // PyFrame_Check()
+#include "datetime.h" // PyDateTimeAPI
+#include "marshal.h" // PyMarshal_WriteLongToFile
#include "structmember.h" // PyMemberDef
-#include <float.h>
+#include <float.h> // FLT_MAX
#include <signal.h>
#ifdef MS_WINDOWS
-# include <winsock2.h> /* struct timeval */
+# include <winsock2.h> // struct timeval
#endif
#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h> /* For W_STOPCODE */
+#include <sys/wait.h> // W_STOPCODE
#endif
#ifdef Py_BUILD_CORE
# error "_testcapi must test the public Python C API, not CPython internal C API"
#endif
+
+// Forward declarations
static struct PyModuleDef _testcapimodule;
static PyType_Spec HeapTypeNameType_Spec;
-
static PyObject *TestError; /* set to exception object in init */
+
/* Raise TestError with test_name + ": " + msg, and return NULL. */
static PyObject *
@@ -5674,6 +5677,57 @@ type_get_version(PyObject *self, PyObject *type)
}
+// Test PyThreadState C API
+static PyObject *
+test_tstate_capi(PyObject *self, PyObject *Py_UNUSED(args))
+{
+ // PyThreadState_Get()
+ PyThreadState *tstate = PyThreadState_Get();
+ assert(tstate != NULL);
+
+ // PyThreadState_GET()
+ PyThreadState *tstate2 = PyThreadState_Get();
+ assert(tstate2 == tstate);
+
+ // private _PyThreadState_UncheckedGet()
+ PyThreadState *tstate3 = _PyThreadState_UncheckedGet();
+ assert(tstate3 == tstate);
+
+ // PyThreadState_EnterTracing(), PyThreadState_LeaveTracing()
+ PyThreadState_EnterTracing(tstate);
+ PyThreadState_LeaveTracing(tstate);
+
+ // PyThreadState_GetDict(): no tstate argument
+ PyObject *dict = PyThreadState_GetDict();
+ // PyThreadState_GetDict() API can return NULL if PyDict_New() fails,
+ // but it should not occur in practice.
+ assert(dict != NULL);
+ assert(PyDict_Check(dict));
+ // dict is a borrowed reference
+
+ // private _PyThreadState_GetDict()
+ PyObject *dict2 = _PyThreadState_GetDict(tstate);
+ assert(dict2 == dict);
+ // dict2 is a borrowed reference
+
+ // PyThreadState_GetInterpreter()
+ PyInterpreterState *interp = PyThreadState_GetInterpreter(tstate);
+ assert(interp != NULL);
+
+ // PyThreadState_GetFrame()
+ PyFrameObject*frame = PyThreadState_GetFrame(tstate);
+ assert(frame != NULL);
+ assert(PyFrame_Check(frame));
+ Py_DECREF(frame);
+
+ // PyThreadState_GetID()
+ uint64_t id = PyThreadState_GetID(tstate);
+ assert(id >= 1);
+
+ Py_RETURN_NONE;
+}
+
+
static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *);
static PyObject *getargs_s_hash_int(PyObject *, PyObject *, PyObject*);
@@ -5957,6 +6011,7 @@ static PyMethodDef TestMethods[] = {
{"fatal_error", test_fatal_error, METH_VARARGS,
PyDoc_STR("fatal_error(message, release_gil=False): call Py_FatalError(message)")},
{"type_get_version", type_get_version, METH_O, PyDoc_STR("type->tp_version_tag")},
+ {"test_tstate_capi", test_tstate_capi, METH_NOARGS, NULL},
{NULL, NULL} /* sentinel */
};