blob: 57ee7b914348b4aa79647eb488d16b306bc36010 [file] [log] [blame]
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +00001/*
2
3 Reference Cycle Garbage Collection
4 ==================================
5
6 Neil Schemenauer <nascheme@enme.ucalgary.ca>
7
8 Based on a post on the python-dev list. Ideas from Guido van Rossum,
9 Eric Tiedemann, and various others.
10
11 http://www.enme.calgary.ca/~nascheme/python/gc.html
12 http://www.python.org/pipermail/python-dev/2000-March/003869.html
13 http://www.python.org/pipermail/python-dev/2000-March/004010.html
14 http://www.python.org/pipermail/python-dev/2000-March/004022.html
15
16 For a highlevel view of the collection process, read the collect
17 function.
18
19 TODO:
20 use a different interface for set_debug() (keywords)?
21 tune parameters
22
23*/
24
25
26#include "Python.h"
27
28#ifdef WITH_CYCLE_GC
29
30/* magic gc_refs value */
31#define GC_MOVED -1
32
33/*** Global GC state ***/
34
35/* linked lists of container objects */
36static PyGC_Head generation0 = {&generation0, &generation0, 0};
37static PyGC_Head generation1 = {&generation1, &generation1, 0};
38static PyGC_Head generation2 = {&generation2, &generation2, 0};
39static int generation = 0; /* current generation being collected */
40
41/* collection frequencies, XXX tune these */
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +000042static int enabled = 1; /* automatic collection enabled? */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +000043static int threshold0 = 100; /* net new containers before collection */
44static int threshold1 = 10; /* generation0 collections before collecting 1 */
45static int threshold2 = 10; /* generation1 collections before collecting 2 */
46
47/* net new objects allocated since last collection */
48static int allocated;
49
50/* set for debugging information */
51#define DEBUG_STATS (1<<0) /* print collection statistics */
52#define DEBUG_COLLECTABLE (1<<1) /* print collectable objects */
53#define DEBUG_UNCOLLECTABLE (1<<2) /* print uncollectable objects */
54#define DEBUG_INSTANCES (1<<3) /* print instances */
55#define DEBUG_OBJECTS (1<<4) /* print other objects */
56#define DEBUG_LEAK DEBUG_COLLECTABLE | \
57 DEBUG_UNCOLLECTABLE | \
58 DEBUG_INSTANCES | \
59 DEBUG_OBJECTS
Jeremy Hylton06257772000-08-31 15:10:24 +000060static int debug = 0;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +000061
62/* list of uncollectable objects */
63static PyObject *garbage;
64
65
66/*** list functions ***/
67
68static void
69gc_list_init(PyGC_Head *list)
70{
71 list->gc_prev = list;
72 list->gc_next = list;
73}
74
75static void
76gc_list_append(PyGC_Head *node, PyGC_Head *list)
77{
78 node->gc_next = list;
79 node->gc_prev = list->gc_prev;
80 node->gc_prev->gc_next = node;
81 list->gc_prev = node;
82}
83
84static void
85gc_list_remove(PyGC_Head *node)
86{
87 node->gc_prev->gc_next = node->gc_next;
88 node->gc_next->gc_prev = node->gc_prev;
89#ifdef Py_DEBUG
90 node->gc_prev = NULL;
91 node->gc_next = NULL;
92#endif
93}
94
95static void
96gc_list_move(PyGC_Head *from, PyGC_Head *to)
97{
98 if (from->gc_next == from) {
99 /* empty from list */
100 gc_list_init(to);
101 } else {
102 to->gc_next = from->gc_next;
103 to->gc_next->gc_prev = to;
104 to->gc_prev = from->gc_prev;
105 to->gc_prev->gc_next = to;
106 }
107 gc_list_init(from);
108}
109
110/* append a list onto another list, from becomes an empty list */
111static void
112gc_list_merge(PyGC_Head *from, PyGC_Head *to)
113{
114 PyGC_Head *tail;
115 if (from->gc_next != from) {
116 tail = to->gc_prev;
117 tail->gc_next = from->gc_next;
118 tail->gc_next->gc_prev = tail;
119 to->gc_prev = from->gc_prev;
120 to->gc_prev->gc_next = to;
121 }
122 gc_list_init(from);
123}
124
125static long
126gc_list_size(PyGC_Head *list)
127{
128 PyGC_Head *gc;
129 long n = 0;
130 for (gc = list->gc_next; gc != list; gc = gc->gc_next) {
131 n++;
132 }
133 return n;
134}
135
136/*** end of list stuff ***/
137
138
139/* Set all gc_refs = ob_refcnt */
140static void
141update_refs(PyGC_Head *containers)
142{
143 PyGC_Head *gc = containers->gc_next;
144 for (; gc != containers; gc=gc->gc_next) {
145 gc->gc_refs = PyObject_FROM_GC(gc)->ob_refcnt;
146 }
147}
148
149static int
150visit_decref(PyObject *op, void *data)
151{
152 if (op && PyObject_IS_GC(op)) {
153 PyObject_AS_GC(op)->gc_refs--;
154 }
155 return 0;
156}
157
158/* Subtract internal references from gc_refs */
159static void
160subtract_refs(PyGC_Head *containers)
161{
162 traverseproc traverse;
163 PyGC_Head *gc = containers->gc_next;
164 for (; gc != containers; gc=gc->gc_next) {
165 traverse = PyObject_FROM_GC(gc)->ob_type->tp_traverse;
166 (void) traverse(PyObject_FROM_GC(gc),
167 (visitproc)visit_decref,
168 NULL);
169 }
170}
171
172/* Append objects with gc_refs > 0 to roots list */
173static void
174move_roots(PyGC_Head *containers, PyGC_Head *roots)
175{
176 PyGC_Head *next;
177 PyGC_Head *gc = containers->gc_next;
178 while (gc != containers) {
179 next = gc->gc_next;
180 if (gc->gc_refs > 0) {
181 gc_list_remove(gc);
182 gc_list_append(gc, roots);
183 gc->gc_refs = GC_MOVED;
184 }
185 gc = next;
186 }
187}
188
189static int
190visit_reachable(PyObject *op, PyGC_Head *roots)
191{
192 if (PyObject_IS_GC(op)) {
193 PyGC_Head *gc = PyObject_AS_GC(op);
194 if (gc && gc->gc_refs != GC_MOVED) {
195 gc_list_remove(gc);
196 gc_list_append(gc, roots);
197 gc->gc_refs = GC_MOVED;
198 }
199 }
200 return 0;
201}
202
203/* Move objects referenced from reachable to reachable set. */
204static void
205move_root_reachable(PyGC_Head *reachable)
206{
207 traverseproc traverse;
208 PyGC_Head *gc = reachable->gc_next;
209 for (; gc != reachable; gc=gc->gc_next) {
210 /* careful, reachable list is growing here */
211 PyObject *op = PyObject_FROM_GC(gc);
212 traverse = op->ob_type->tp_traverse;
213 (void) traverse(op,
214 (visitproc)visit_reachable,
215 (void *)reachable);
216 }
217}
218
219/* move all objects with finalizers (instances with __del__) */
220static void
221move_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers)
222{
223 PyGC_Head *next;
224 PyGC_Head *gc = unreachable->gc_next;
Jeremy Hylton06257772000-08-31 15:10:24 +0000225 static PyObject *delstr = NULL;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000226 if (delstr == NULL) {
227 delstr = PyString_InternFromString("__del__");
Jeremy Hylton06257772000-08-31 15:10:24 +0000228 if (delstr == NULL)
229 Py_FatalError("PyGC: can't initialize __del__ string");
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000230 }
231 for (; gc != unreachable; gc=next) {
232 PyObject *op = PyObject_FROM_GC(gc);
233 next = gc->gc_next;
234 if (PyInstance_Check(op) && PyObject_HasAttr(op, delstr)) {
235 gc_list_remove(gc);
236 gc_list_append(gc, finalizers);
237 }
238 }
239}
240
241
242/* called by tp_traverse */
243static int
244visit_finalizer_reachable(PyObject *op, PyGC_Head *finalizers)
245{
246 if (PyObject_IS_GC(op)) {
247 PyGC_Head *gc = PyObject_AS_GC(op);
248 if (gc && gc->gc_refs != GC_MOVED) {
249 gc_list_remove(gc);
250 gc_list_append(gc, finalizers);
251 gc->gc_refs = GC_MOVED;
252 }
253 }
254 return 0;
255}
256
257/* Move objects referenced from roots to roots */
258static void
259move_finalizer_reachable(PyGC_Head *finalizers)
260{
261 traverseproc traverse;
262 PyGC_Head *gc = finalizers->gc_next;
263 for (; gc != finalizers; gc=gc->gc_next) {
264 /* careful, finalizers list is growing here */
265 traverse = PyObject_FROM_GC(gc)->ob_type->tp_traverse;
266 (void) traverse(PyObject_FROM_GC(gc),
267 (visitproc)visit_finalizer_reachable,
268 (void *)finalizers);
269 }
270}
271
272static void
Jeremy Hylton06257772000-08-31 15:10:24 +0000273debug_instance(char *msg, PyInstanceObject *inst)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000274{
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000275 char *cname;
276 /* be careful not to create new dictionaries */
277 PyObject *classname = inst->in_class->cl_name;
278 if (classname != NULL && PyString_Check(classname))
279 cname = PyString_AsString(classname);
280 else
281 cname = "?";
Jeremy Hylton06257772000-08-31 15:10:24 +0000282 PySys_WriteStderr("gc: %.100s <%.100s instance at %p>\n",
283 msg, cname, inst);
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000284}
285
286static void
Jeremy Hylton06257772000-08-31 15:10:24 +0000287debug_cycle(char *msg, PyObject *op)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000288{
289 if ((debug & DEBUG_INSTANCES) && PyInstance_Check(op)) {
Jeremy Hylton06257772000-08-31 15:10:24 +0000290 debug_instance(msg, (PyInstanceObject *)op);
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000291 } else if (debug & DEBUG_OBJECTS) {
Jeremy Hylton06257772000-08-31 15:10:24 +0000292 PySys_WriteStderr("gc: %.100s <%.100s %p>\n",
293 msg, op->ob_type->tp_name, op);
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000294 }
295}
296
297/* Handle uncollectable garbage (cycles with finalizers). */
298static void
299handle_finalizers(PyGC_Head *finalizers, PyGC_Head *old)
300{
301 PyGC_Head *gc;
302 if (garbage == NULL) {
303 garbage = PyList_New(0);
304 }
305 for (gc = finalizers->gc_next; gc != finalizers;
306 gc = finalizers->gc_next) {
307 PyObject *op = PyObject_FROM_GC(gc);
308 /* Add all instances to a Python accessible list of garbage */
309 if (PyInstance_Check(op)) {
310 PyList_Append(garbage, op);
311 }
312 /* We assume that all objects in finalizers are reachable from
313 * instances. Once we add the instances to the garbage list
314 * everything is reachable from Python again. */
315 gc_list_remove(gc);
316 gc_list_append(gc, old);
317 }
318}
319
320/* Break reference cycles by clearing the containers involved. This is
321 * tricky business as the lists can be changing and we don't know which
322 * objects may be freed. It is possible I screwed something up here. */
323static void
324delete_garbage(PyGC_Head *unreachable, PyGC_Head *old)
325{
326 inquiry clear;
327
328 while (unreachable->gc_next != unreachable) {
329 PyGC_Head *gc = unreachable->gc_next;
330 PyObject *op = PyObject_FROM_GC(gc);
331 /*
332 PyList_Append(garbage, op);
333 */
334 if ((clear = op->ob_type->tp_clear) != NULL) {
335 Py_INCREF(op);
336 clear((PyObject *)op);
337 Py_DECREF(op);
338 }
339 /* only try to call tp_clear once for each object */
340 if (unreachable->gc_next == gc) {
341 /* still alive, move it, it may die later */
342 gc_list_remove(gc);
343 gc_list_append(gc, old);
344 }
345 }
346}
347
348/* This is the main function. Read this to understand how the
349 * collection process works. */
350static long
351collect(PyGC_Head *young, PyGC_Head *old)
352{
353 long n = 0;
354 long m = 0;
355 PyGC_Head reachable;
356 PyGC_Head unreachable;
357 PyGC_Head finalizers;
358 PyGC_Head *gc;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000359
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000360 if (debug & DEBUG_STATS) {
Jeremy Hylton06257772000-08-31 15:10:24 +0000361 PySys_WriteStderr(
362 "gc: collecting generation %d...\n"
363 "gc: objects in each generation: %ld %ld %ld\n",
364 generation,
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000365 gc_list_size(&generation0),
366 gc_list_size(&generation1),
367 gc_list_size(&generation2));
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000368 }
369
370 /* Using ob_refcnt and gc_refs, calculate which objects in the
371 * container set are reachable from outside the set (ie. have a
372 * refcount greater than 0 when all the references within the
373 * set are taken into account */
374 update_refs(young);
375 subtract_refs(young);
376
377 /* Move everything reachable from outside the set into the
378 * reachable set (ie. gc_refs > 0). Next, move everything
379 * reachable from objects in the reachable set. */
380 gc_list_init(&reachable);
381 move_roots(young, &reachable);
382 move_root_reachable(&reachable);
383
384 /* move unreachable objects to a temporary list, new objects can be
385 * allocated after this point */
386 gc_list_init(&unreachable);
387 gc_list_move(young, &unreachable);
388
389 /* move reachable objects to next generation */
390 gc_list_merge(&reachable, old);
391
392 /* Move objects reachable from finalizers, we can't safely delete
393 * them. Python programmers should take care not to create such
394 * things. For Python finalizers means instance objects with
395 * __del__ methods. */
396 gc_list_init(&finalizers);
397 move_finalizers(&unreachable, &finalizers);
398 move_finalizer_reachable(&finalizers);
399
400 /* Collect statistics on collectable objects found and print
401 * debugging information. */
402 for (gc = unreachable.gc_next; gc != &unreachable;
403 gc = gc->gc_next) {
404 m++;
Jeremy Hylton06257772000-08-31 15:10:24 +0000405 if (debug & DEBUG_COLLECTABLE) {
406 debug_cycle("collectable", PyObject_FROM_GC(gc));
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000407 }
408 }
409 /* call tp_clear on objects in the collectable set. This will cause
410 * the reference cycles to be broken. It may also cause some objects in
411 * finalizers to be freed */
412 delete_garbage(&unreachable, old);
413
414 /* Collect statistics on uncollectable objects found and print
415 * debugging information. */
416 for (gc = finalizers.gc_next; gc != &finalizers;
417 gc = gc->gc_next) {
418 n++;
Jeremy Hylton06257772000-08-31 15:10:24 +0000419 if (debug & DEBUG_UNCOLLECTABLE) {
420 debug_cycle("uncollectable", PyObject_FROM_GC(gc));
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000421 }
422 }
Jeremy Hylton06257772000-08-31 15:10:24 +0000423 if (debug & DEBUG_STATS) {
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000424 if (m == 0 && n == 0) {
Jeremy Hylton06257772000-08-31 15:10:24 +0000425 PySys_WriteStderr("gc: done.\n");
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000426 } else {
Jeremy Hylton06257772000-08-31 15:10:24 +0000427 PySys_WriteStderr(
428 "gc: done, %ld unreachable, %ld uncollectable.\n",
429 n+m, n);
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000430 }
431 }
432
433 /* Append instances in the uncollectable set to a Python
434 * reachable list of garbage. The programmer has to deal with
435 * this if they insist on creating this type of structure. */
436 handle_finalizers(&finalizers, old);
437
438 allocated = 0;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000439 return n+m;
440}
441
442static long
443collect_generations(void)
444{
445 static long collections0 = 0;
446 static long collections1 = 0;
Vladimir Marangozovb16714b2000-07-10 05:37:39 +0000447 long n = 0;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000448
449
450 if (collections1 > threshold2) {
451 generation = 2;
452 gc_list_merge(&generation0, &generation2);
453 gc_list_merge(&generation1, &generation2);
454 if (generation2.gc_next != &generation2) {
455 n = collect(&generation2, &generation2);
456 }
457 collections1 = 0;
458 } else if (collections0 > threshold1) {
459 generation = 1;
460 collections1++;
461 gc_list_merge(&generation0, &generation1);
462 if (generation1.gc_next != &generation1) {
463 n = collect(&generation1, &generation2);
464 }
465 collections0 = 0;
466 } else {
467 generation = 0;
468 collections0++;
469 if (generation0.gc_next != &generation0) {
470 n = collect(&generation0, &generation1);
471 }
472 }
473 return n;
474}
475
476void
477_PyGC_Insert(PyObject *op)
478{
479 /* collection lock since collecting may cause allocations */
480 static int collecting = 0;
481
482#ifdef Py_DEBUG
483 if (!PyObject_IS_GC(op)) {
484 abort();
485 }
486#endif
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000487 if (allocated > threshold0 && enabled && threshold0 && !collecting) {
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000488 collecting++;
489 collect_generations();
490 collecting--;
491 }
492 allocated++;
493 gc_list_append(PyObject_AS_GC(op), &generation0);
494}
495
496void
497_PyGC_Remove(PyObject *op)
498{
499 PyGC_Head *g = PyObject_AS_GC(op);
500#ifdef Py_DEBUG
501 if (!PyObject_IS_GC(op)) {
502 abort();
503 }
504#endif
505 gc_list_remove(g);
506 if (allocated > 0) {
507 allocated--;
508 }
509}
510
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000511static char gc_enable__doc__[] =
512"enable() -> None\n"
513"\n"
514"Enable automatic garbage collection.\n"
515;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000516
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000517static PyObject *
518gc_enable(PyObject *self, PyObject *args)
519{
520
521 if (!PyArg_ParseTuple(args, ":enable")) /* check no args */
522 return NULL;
523
524 enabled = 1;
525
526 Py_INCREF(Py_None);
527 return Py_None;
528}
529
530static char gc_disable__doc__[] =
531"disable() -> None\n"
532"\n"
533"Disable automatic garbage collection.\n"
534;
535
536static PyObject *
537gc_disable(PyObject *self, PyObject *args)
538{
539
540 if (!PyArg_ParseTuple(args, ":disable")) /* check no args */
541 return NULL;
542
543 enabled = 0;
544
545 Py_INCREF(Py_None);
546 return Py_None;
547}
548
549static char gc_isenabled__doc__[] =
550"isenabled() -> status\n"
551"\n"
552"Returns true if automatic garbage collection is enabled.\n"
553;
554
555static PyObject *
556gc_isenabled(PyObject *self, PyObject *args)
557{
558
559 if (!PyArg_ParseTuple(args, ":isenabled")) /* check no args */
560 return NULL;
561
562 return Py_BuildValue("i", enabled);
563}
564
565static char gc_collect__doc__[] =
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000566"collect() -> n\n"
567"\n"
568"Run a full collection. The number of unreachable objects is returned.\n"
569;
570
571static PyObject *
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000572gc_collect(PyObject *self, PyObject *args)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000573{
574 long n;
575
Fred Drakecc1be242000-07-12 04:42:23 +0000576 if (!PyArg_ParseTuple(args, ":collect")) /* check no args */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000577 return NULL;
578
579 generation = 2;
580 gc_list_merge(&generation0, &generation2);
581 gc_list_merge(&generation1, &generation2);
582 n = collect(&generation2, &generation2);
583
584 return Py_BuildValue("i", n);
585}
586
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000587static char gc_set_debug__doc__[] =
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000588"set_debug(flags) -> None\n"
589"\n"
590"Set the garbage collection debugging flags. Debugging information is\n"
591"written to sys.stderr.\n"
592"\n"
593"flags is an integer and can have the following bits turned on:\n"
594"\n"
595" DEBUG_STATS - Print statistics during collection.\n"
596" DEBUG_COLLECTABLE - Print collectable objects found.\n"
597" DEBUG_UNCOLLECTABLE - Print unreachable but uncollectable objects found.\n"
598" DEBUG_INSTANCES - Print instance objects.\n"
599" DEBUG_OBJECTS - Print objects other than instances.\n"
600" DEBUG_LEAK - Debug leaking programs (everything but STATS).\n"
601;
602
603static PyObject *
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000604gc_set_debug(PyObject *self, PyObject *args)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000605{
Fred Drakecc1be242000-07-12 04:42:23 +0000606 if (!PyArg_ParseTuple(args, "l:get_debug", &debug))
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000607 return NULL;
608
609 Py_INCREF(Py_None);
610 return Py_None;
611}
612
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000613static char gc_get_debug__doc__[] =
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000614"get_debug() -> flags\n"
615"\n"
616"Get the garbage collection debugging flags.\n"
617;
618
619static PyObject *
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000620gc_get_debug(PyObject *self, PyObject *args)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000621{
Fred Drakecc1be242000-07-12 04:42:23 +0000622 if (!PyArg_ParseTuple(args, ":get_debug")) /* no args */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000623 return NULL;
624
625 return Py_BuildValue("i", debug);
626}
627
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000628static char gc_set_thresh__doc__[] =
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000629"set_threshold(threshold0, [threhold1, threshold2]) -> None\n"
630"\n"
631"Sets the collection thresholds. Setting threshold0 to zero disables\n"
632"collection.\n"
633;
634
635static PyObject *
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000636gc_set_thresh(PyObject *self, PyObject *args)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000637{
Fred Drakecc1be242000-07-12 04:42:23 +0000638 if (!PyArg_ParseTuple(args, "i|ii:set_threshold", &threshold0,
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000639 &threshold1, &threshold2))
640 return NULL;
641
642 Py_INCREF(Py_None);
643 return Py_None;
644}
645
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000646static char gc_get_thresh__doc__[] =
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000647"get_threshold() -> (threshold0, threshold1, threshold2)\n"
648"\n"
649"Return the current collection thresholds\n"
650;
651
652static PyObject *
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000653gc_get_thresh(PyObject *self, PyObject *args)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000654{
Fred Drakecc1be242000-07-12 04:42:23 +0000655 if (!PyArg_ParseTuple(args, ":get_threshold")) /* no args */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000656 return NULL;
657
658 return Py_BuildValue("(iii)", threshold0, threshold1, threshold2);
659}
660
661
662static char gc__doc__ [] =
663"This module provides access to the garbage collector for reference cycles.\n"
664"\n"
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000665"enable() -- Enable automatic garbage collection.\n"
666"disable() -- Disable automatic garbage collection.\n"
667"isenabled() -- Returns true if automatic collection is enabled.\n"
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000668"collect() -- Do a full collection right now.\n"
669"set_debug() -- Set debugging flags.\n"
670"get_debug() -- Get debugging flags.\n"
671"set_threshold() -- Set the collection thresholds.\n"
672"get_threshold() -- Return the current the collection thresholds.\n"
673;
674
675static PyMethodDef GcMethods[] = {
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000676 {"enable", gc_enable, METH_VARARGS, gc_enable__doc__},
677 {"disable", gc_disable, METH_VARARGS, gc_disable__doc__},
678 {"isenabled", gc_isenabled, METH_VARARGS, gc_isenabled__doc__},
679 {"set_debug", gc_set_debug, METH_VARARGS, gc_set_debug__doc__},
680 {"get_debug", gc_get_debug, METH_VARARGS, gc_get_debug__doc__},
681 {"set_threshold", gc_set_thresh, METH_VARARGS, gc_set_thresh__doc__},
682 {"get_threshold", gc_get_thresh, METH_VARARGS, gc_get_thresh__doc__},
683 {"collect", gc_collect, METH_VARARGS, gc_collect__doc__},
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000684 {NULL, NULL} /* Sentinel */
685};
686
687void
688initgc(void)
689{
690 PyObject *m;
691 PyObject *d;
692
693 m = Py_InitModule4("gc",
694 GcMethods,
695 gc__doc__,
696 NULL,
697 PYTHON_API_VERSION);
698 d = PyModule_GetDict(m);
699 if (garbage == NULL) {
700 garbage = PyList_New(0);
701 }
702 PyDict_SetItemString(d, "garbage", garbage);
703 PyDict_SetItemString(d, "DEBUG_STATS",
704 PyInt_FromLong(DEBUG_STATS));
705 PyDict_SetItemString(d, "DEBUG_COLLECTABLE",
706 PyInt_FromLong(DEBUG_COLLECTABLE));
707 PyDict_SetItemString(d, "DEBUG_UNCOLLECTABLE",
708 PyInt_FromLong(DEBUG_UNCOLLECTABLE));
709 PyDict_SetItemString(d, "DEBUG_INSTANCES",
710 PyInt_FromLong(DEBUG_INSTANCES));
711 PyDict_SetItemString(d, "DEBUG_OBJECTS",
712 PyInt_FromLong(DEBUG_OBJECTS));
713 PyDict_SetItemString(d, "DEBUG_LEAK",
714 PyInt_FromLong(DEBUG_LEAK));
715}
716
717#endif /* WITH_CYCLE_GC */