4#include "greenlet_internal.hpp"
7#include "TGreenletGlobals.cpp"
8#include "TMainGreenlet.cpp"
9#include "TThreadStateDestroy.cpp"
11using greenlet::LockGuard;
15# pragma clang diagnostic push
16# pragma clang diagnostic ignored "-Wunused-function"
17# pragma clang diagnostic ignored "-Wunused-variable"
20PyDoc_STRVAR(mod_getcurrent_doc,
21 "getcurrent() -> greenlet\n"
23 "Returns the current greenlet (i.e. the one which called this "
27mod_getcurrent(PyObject* UNUSED(module))
29 return GET_THREAD_STATE().state().get_current().relinquish_ownership_o();
32PyDoc_STRVAR(mod_settrace_doc,
33 "settrace(callback) -> object\n"
35 "Sets a new tracing function and returns the previous one.\n");
37mod_settrace(PyObject* UNUSED(module), PyObject* args)
40 if (!PyArg_ParseTuple(args,
"O", &tracefunc)) {
44 OwnedObject previous = state.get_tracefunc();
49 state.set_tracefunc(tracefunc);
51 return previous.relinquish_ownership();
54PyDoc_STRVAR(mod_gettrace_doc,
55 "gettrace() -> object\n"
57 "Returns the currently set tracing function, or None.\n");
60mod_gettrace(PyObject* UNUSED(module))
62 OwnedObject tracefunc = GET_THREAD_STATE().state().get_tracefunc();
66 return tracefunc.relinquish_ownership();
71PyDoc_STRVAR(mod_set_thread_local_doc,
72 "set_thread_local(key, value) -> None\n"
74 "Set a value in the current thread-local dictionary. Debugging only.\n");
77mod_set_thread_local(PyObject* UNUSED(module), PyObject* args)
81 PyObject* result = NULL;
83 if (PyArg_UnpackTuple(args,
"set_thread_local", 2, 2, &key, &value)) {
85 PyThreadState_GetDict(),
96PyDoc_STRVAR(mod_get_pending_cleanup_count_doc,
97 "get_pending_cleanup_count() -> Integer\n"
99 "Get the number of greenlet cleanup operations pending. Testing only.\n");
103mod_get_pending_cleanup_count(PyObject* UNUSED(module))
105 LockGuard cleanup_lock(*mod_globs->thread_states_to_destroy_lock);
106 return PyLong_FromSize_t(mod_globs->thread_states_to_destroy.size());
109PyDoc_STRVAR(mod_get_total_main_greenlets_doc,
110 "get_total_main_greenlets() -> Integer\n"
112 "Quickly return the number of main greenlets that exist. Testing only.\n");
115mod_get_total_main_greenlets(PyObject* UNUSED(module))
117 return PyLong_FromSize_t(G_TOTAL_MAIN_GREENLETS);
122PyDoc_STRVAR(mod_get_clocks_used_doing_optional_cleanup_doc,
123 "get_clocks_used_doing_optional_cleanup() -> Integer\n"
125 "Get the number of clock ticks the program has used doing optional "
126 "greenlet cleanup.\n"
127 "Beginning in greenlet 2.0, greenlet tries to find and dispose of greenlets\n"
128 "that leaked after a thread exited. This requires invoking Python's garbage collector,\n"
129 "which may have a performance cost proportional to the number of live objects.\n"
130 "This function returns the amount of processor time\n"
131 "greenlet has used to do this. In programs that run with very large amounts of live\n"
132 "objects, this metric can be used to decide whether the cost of doing this cleanup\n"
133 "is worth the memory leak being corrected. If not, you can disable the cleanup\n"
134 "using ``enable_optional_cleanup(False)``.\n"
135 "The units are arbitrary and can only be compared to themselves (similarly to ``time.clock()``);\n"
136 "for example, to see how it scales with your heap. You can attempt to convert them into seconds\n"
137 "by dividing by the value of CLOCKS_PER_SEC."
138 "If cleanup has been disabled, returns None."
140 "This is an implementation specific, provisional API. It may be changed or removed\n"
142 ".. versionadded:: 2.0"
145mod_get_clocks_used_doing_optional_cleanup(PyObject* UNUSED(module))
149 if (clocks == std::clock_t(-1)) {
154 return PyLong_FromSsize_t(clocks);
157PyDoc_STRVAR(mod_enable_optional_cleanup_doc,
158 "mod_enable_optional_cleanup(bool) -> None\n"
160 "Enable or disable optional cleanup operations.\n"
161 "See ``get_clocks_used_doing_optional_cleanup()`` for details.\n"
164mod_enable_optional_cleanup(PyObject* UNUSED(module), PyObject* flag)
166 int is_true = PyObject_IsTrue(flag);
174 if (clocks == std::clock_t(-1)) {
175 ThreadState::set_clocks_used_doing_gc(0);
179 ThreadState::set_clocks_used_doing_gc(std::clock_t(-1));
188PyDoc_STRVAR(mod_get_tstate_trash_delete_nesting_doc,
189 "get_tstate_trash_delete_nesting() -> Integer\n"
191 "Return the 'trash can' nesting level. Testing only.\n");
193mod_get_tstate_trash_delete_nesting(PyObject* UNUSED(module))
195 PyThreadState* tstate = PyThreadState_GET();
198 return PyLong_FromLong(tstate->trash.delete_nesting);
200 return PyLong_FromLong(tstate->trash_delete_nesting);
208static PyMethodDef GreenMethods[] = {
210 .ml_name=
"getcurrent",
211 .ml_meth=(PyCFunction)mod_getcurrent,
212 .ml_flags=METH_NOARGS,
213 .ml_doc=mod_getcurrent_doc
217 .ml_meth=(PyCFunction)mod_settrace,
218 .ml_flags=METH_VARARGS,
219 .ml_doc=mod_settrace_doc
223 .ml_meth=(PyCFunction)mod_gettrace,
224 .ml_flags=METH_NOARGS,
225 .ml_doc=mod_gettrace_doc
228 .ml_name=
"set_thread_local",
229 .ml_meth=(PyCFunction)mod_set_thread_local,
230 .ml_flags=METH_VARARGS,
231 .ml_doc=mod_set_thread_local_doc
234 .ml_name=
"get_pending_cleanup_count",
235 .ml_meth=(PyCFunction)mod_get_pending_cleanup_count,
236 .ml_flags=METH_NOARGS,
237 .ml_doc=mod_get_pending_cleanup_count_doc
240 .ml_name=
"get_total_main_greenlets",
241 .ml_meth=(PyCFunction)mod_get_total_main_greenlets,
242 .ml_flags=METH_NOARGS,
243 .ml_doc=mod_get_total_main_greenlets_doc
246 .ml_name=
"get_clocks_used_doing_optional_cleanup",
247 .ml_meth=(PyCFunction)mod_get_clocks_used_doing_optional_cleanup,
248 .ml_flags=METH_NOARGS,
249 .ml_doc=mod_get_clocks_used_doing_optional_cleanup_doc
252 .ml_name=
"enable_optional_cleanup",
253 .ml_meth=(PyCFunction)mod_enable_optional_cleanup,
255 .ml_doc=mod_enable_optional_cleanup_doc
259 .ml_name=
"get_tstate_trash_delete_nesting",
260 .ml_meth=(PyCFunction)mod_get_tstate_trash_delete_nesting,
261 .ml_flags=METH_NOARGS,
262 .ml_doc=mod_get_tstate_trash_delete_nesting_doc
265 {.ml_name=NULL, .ml_meth=NULL}
268static const char*
const copy_on_greentype[] = {
277static struct PyModuleDef greenlet_module_def = {
278 .m_base=PyModuleDef_HEAD_INIT,
279 .m_name=
"greenlet._greenlet",
282 .m_methods=GreenMethods,
289# pragma clang diagnostic pop
290#elif defined(__GNUC__)
291# pragma GCC diagnostic pop
Definition TThreadState.hpp:87
static std::clock_t clocks_used_doing_gc()
Definition TThreadState.hpp:352
Definition greenlet_refs.hpp:1102