Kaydet (Commit) f9d20c37 authored tarafından Vladimir Marangozov's avatar Vladimir Marangozov

Neil Schemenauer: GC enable(), disable(), isenabled() interface.

Small stylistic changes by VM:
- is_enabled() -> isenabled()
- static ... Py_<func> -> static ... gc_<func>
üst 5bcb215e
...@@ -5,18 +5,30 @@ ...@@ -5,18 +5,30 @@
\moduleauthor{Neil Schemenauer}{nascheme@enme.ucalgary.ca} \moduleauthor{Neil Schemenauer}{nascheme@enme.ucalgary.ca}
\sectionauthor{Neil Schemenauer}{nascheme@enme.ucalgary.ca} \sectionauthor{Neil Schemenauer}{nascheme@enme.ucalgary.ca}
This module provides an interface to the optional garbage collector. This module provides an interface to the optional garbage collector. It
It provides the ability to disable the collector, tune the collection provides the ability to disable the collector, tune the collection
frequency, and set debugging options. It also provides access to frequency, and set debugging options. It also provides access to
unreachable objects that the collector found but cannot free. Since unreachable objects that the collector found but cannot free. Since the
the collector supplements the reference counting already used in collector supplements the reference counting already used in Python, you
Python, you can disable the collector if you are sure your program can disable the collector if you are sure your program does not create
does not create reference cycles. The collector can be disabled by reference cycles. Automatic collection can be disabled by calling
calling \code{gc.set_threshold(0)}. To debug a leaking program call \code{gc.disable()}. To debug a leaking program call
\code{gc.set_debug(gc.DEBUG_LEAK)}. \code{gc.set_debug(gc.DEBUG_LEAK)}.
The \module{gc} module provides the following functions: The \module{gc} module provides the following functions:
\begin{funcdesc}{enable}{}
Enable automatic garbage collection.
\end{funcdesc}
\begin{funcdesc}{disable}{}
Disable automatic garbage collection.
\end{funcdesc}
\begin{funcdesc}{isenabled}{}
Returns true if automatic collection is enabled.
\end{funcdesc}
\begin{funcdesc}{collect}{} \begin{funcdesc}{collect}{}
Run a full collection. All generations are examined and the Run a full collection. All generations are examined and the
number of unreachable objects found is returned. number of unreachable objects found is returned.
......
...@@ -75,6 +75,11 @@ def test_function(): ...@@ -75,6 +75,11 @@ def test_function():
def test_all(): def test_all():
enabled = gc.isenabled()
gc.disable()
assert not gc.isenabled()
test_list() test_list()
test_dict() test_dict()
test_tuple() test_tuple()
...@@ -84,4 +89,11 @@ def test_all(): ...@@ -84,4 +89,11 @@ def test_all():
test_finalizer() test_finalizer()
test_function() test_function()
# test gc.enable() even if GC is disabled by default
gc.enable()
assert gc.isenabled()
if not enabled:
gc.disable()
test_all() test_all()
...@@ -39,6 +39,7 @@ static PyGC_Head generation2 = {&generation2, &generation2, 0}; ...@@ -39,6 +39,7 @@ static PyGC_Head generation2 = {&generation2, &generation2, 0};
static int generation = 0; /* current generation being collected */ static int generation = 0; /* current generation being collected */
/* collection frequencies, XXX tune these */ /* collection frequencies, XXX tune these */
static int enabled = 1; /* automatic collection enabled? */
static int threshold0 = 100; /* net new containers before collection */ static int threshold0 = 100; /* net new containers before collection */
static int threshold1 = 10; /* generation0 collections before collecting 1 */ static int threshold1 = 10; /* generation0 collections before collecting 1 */
static int threshold2 = 10; /* generation1 collections before collecting 2 */ static int threshold2 = 10; /* generation1 collections before collecting 2 */
...@@ -492,7 +493,7 @@ _PyGC_Insert(PyObject *op) ...@@ -492,7 +493,7 @@ _PyGC_Insert(PyObject *op)
abort(); abort();
} }
#endif #endif
if (threshold0 && allocated > threshold0 && !collecting) { if (allocated > threshold0 && enabled && threshold0 && !collecting) {
collecting++; collecting++;
collect_generations(); collect_generations();
collecting--; collecting--;
...@@ -516,15 +517,68 @@ _PyGC_Remove(PyObject *op) ...@@ -516,15 +517,68 @@ _PyGC_Remove(PyObject *op)
} }
} }
static char gc_enable__doc__[] =
"enable() -> None\n"
"\n"
"Enable automatic garbage collection.\n"
;
static PyObject *
gc_enable(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":enable")) /* check no args */
return NULL;
enabled = 1;
Py_INCREF(Py_None);
return Py_None;
}
static char gc_disable__doc__[] =
"disable() -> None\n"
"\n"
"Disable automatic garbage collection.\n"
;
static PyObject *
gc_disable(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":disable")) /* check no args */
return NULL;
enabled = 0;
Py_INCREF(Py_None);
return Py_None;
}
static char gc_isenabled__doc__[] =
"isenabled() -> status\n"
"\n"
"Returns true if automatic garbage collection is enabled.\n"
;
static PyObject *
gc_isenabled(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":isenabled")) /* check no args */
return NULL;
return Py_BuildValue("i", enabled);
}
static char collect__doc__[] = static char gc_collect__doc__[] =
"collect() -> n\n" "collect() -> n\n"
"\n" "\n"
"Run a full collection. The number of unreachable objects is returned.\n" "Run a full collection. The number of unreachable objects is returned.\n"
; ;
static PyObject * static PyObject *
Py_collect(PyObject *self, PyObject *args) gc_collect(PyObject *self, PyObject *args)
{ {
long n; long n;
...@@ -539,7 +593,7 @@ Py_collect(PyObject *self, PyObject *args) ...@@ -539,7 +593,7 @@ Py_collect(PyObject *self, PyObject *args)
return Py_BuildValue("i", n); return Py_BuildValue("i", n);
} }
static char set_debug__doc__[] = static char gc_set_debug__doc__[] =
"set_debug(flags) -> None\n" "set_debug(flags) -> None\n"
"\n" "\n"
"Set the garbage collection debugging flags. Debugging information is\n" "Set the garbage collection debugging flags. Debugging information is\n"
...@@ -556,7 +610,7 @@ static char set_debug__doc__[] = ...@@ -556,7 +610,7 @@ static char set_debug__doc__[] =
; ;
static PyObject * static PyObject *
Py_set_debug(PyObject *self, PyObject *args) gc_set_debug(PyObject *self, PyObject *args)
{ {
if (!PyArg_ParseTuple(args, "l:get_debug", &debug)) if (!PyArg_ParseTuple(args, "l:get_debug", &debug))
return NULL; return NULL;
...@@ -565,14 +619,14 @@ Py_set_debug(PyObject *self, PyObject *args) ...@@ -565,14 +619,14 @@ Py_set_debug(PyObject *self, PyObject *args)
return Py_None; return Py_None;
} }
static char get_debug__doc__[] = static char gc_get_debug__doc__[] =
"get_debug() -> flags\n" "get_debug() -> flags\n"
"\n" "\n"
"Get the garbage collection debugging flags.\n" "Get the garbage collection debugging flags.\n"
; ;
static PyObject * static PyObject *
Py_get_debug(PyObject *self, PyObject *args) gc_get_debug(PyObject *self, PyObject *args)
{ {
if (!PyArg_ParseTuple(args, ":get_debug")) /* no args */ if (!PyArg_ParseTuple(args, ":get_debug")) /* no args */
return NULL; return NULL;
...@@ -580,7 +634,7 @@ Py_get_debug(PyObject *self, PyObject *args) ...@@ -580,7 +634,7 @@ Py_get_debug(PyObject *self, PyObject *args)
return Py_BuildValue("i", debug); return Py_BuildValue("i", debug);
} }
static char set_thresh__doc__[] = static char gc_set_thresh__doc__[] =
"set_threshold(threshold0, [threhold1, threshold2]) -> None\n" "set_threshold(threshold0, [threhold1, threshold2]) -> None\n"
"\n" "\n"
"Sets the collection thresholds. Setting threshold0 to zero disables\n" "Sets the collection thresholds. Setting threshold0 to zero disables\n"
...@@ -588,7 +642,7 @@ static char set_thresh__doc__[] = ...@@ -588,7 +642,7 @@ static char set_thresh__doc__[] =
; ;
static PyObject * static PyObject *
Py_set_thresh(PyObject *self, PyObject *args) gc_set_thresh(PyObject *self, PyObject *args)
{ {
if (!PyArg_ParseTuple(args, "i|ii:set_threshold", &threshold0, if (!PyArg_ParseTuple(args, "i|ii:set_threshold", &threshold0,
&threshold1, &threshold2)) &threshold1, &threshold2))
...@@ -598,14 +652,14 @@ Py_set_thresh(PyObject *self, PyObject *args) ...@@ -598,14 +652,14 @@ Py_set_thresh(PyObject *self, PyObject *args)
return Py_None; return Py_None;
} }
static char get_thresh__doc__[] = static char gc_get_thresh__doc__[] =
"get_threshold() -> (threshold0, threshold1, threshold2)\n" "get_threshold() -> (threshold0, threshold1, threshold2)\n"
"\n" "\n"
"Return the current collection thresholds\n" "Return the current collection thresholds\n"
; ;
static PyObject * static PyObject *
Py_get_thresh(PyObject *self, PyObject *args) gc_get_thresh(PyObject *self, PyObject *args)
{ {
if (!PyArg_ParseTuple(args, ":get_threshold")) /* no args */ if (!PyArg_ParseTuple(args, ":get_threshold")) /* no args */
return NULL; return NULL;
...@@ -617,6 +671,9 @@ Py_get_thresh(PyObject *self, PyObject *args) ...@@ -617,6 +671,9 @@ Py_get_thresh(PyObject *self, PyObject *args)
static char gc__doc__ [] = static char gc__doc__ [] =
"This module provides access to the garbage collector for reference cycles.\n" "This module provides access to the garbage collector for reference cycles.\n"
"\n" "\n"
"enable() -- Enable automatic garbage collection.\n"
"disable() -- Disable automatic garbage collection.\n"
"isenabled() -- Returns true if automatic collection is enabled.\n"
"collect() -- Do a full collection right now.\n" "collect() -- Do a full collection right now.\n"
"set_debug() -- Set debugging flags.\n" "set_debug() -- Set debugging flags.\n"
"get_debug() -- Get debugging flags.\n" "get_debug() -- Get debugging flags.\n"
...@@ -625,11 +682,14 @@ static char gc__doc__ [] = ...@@ -625,11 +682,14 @@ static char gc__doc__ [] =
; ;
static PyMethodDef GcMethods[] = { static PyMethodDef GcMethods[] = {
{"set_debug", Py_set_debug, METH_VARARGS, set_debug__doc__}, {"enable", gc_enable, METH_VARARGS, gc_enable__doc__},
{"get_debug", Py_get_debug, METH_VARARGS, get_debug__doc__}, {"disable", gc_disable, METH_VARARGS, gc_disable__doc__},
{"set_threshold", Py_set_thresh, METH_VARARGS, set_thresh__doc__}, {"isenabled", gc_isenabled, METH_VARARGS, gc_isenabled__doc__},
{"get_threshold", Py_get_thresh, METH_VARARGS, get_thresh__doc__}, {"set_debug", gc_set_debug, METH_VARARGS, gc_set_debug__doc__},
{"collect", Py_collect, METH_VARARGS, collect__doc__}, {"get_debug", gc_get_debug, METH_VARARGS, gc_get_debug__doc__},
{"set_threshold", gc_set_thresh, METH_VARARGS, gc_set_thresh__doc__},
{"get_threshold", gc_get_thresh, METH_VARARGS, gc_get_thresh__doc__},
{"collect", gc_collect, METH_VARARGS, gc_collect__doc__},
{NULL, NULL} /* Sentinel */ {NULL, NULL} /* Sentinel */
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment