py: Make gc.enable/disable just control auto-GC; alloc is still allowed.
gc.enable/disable are now the same as CPython: they just control whether automatic garbage collection is enabled or not. If disabled, you can still allocate heap memory, and initiate a manual collection.
This commit is contained in:
parent
4029f51842
commit
109c1de015
|
@ -4,23 +4,22 @@
|
|||
.. module:: gc
|
||||
:synopsis: control the garbage collector
|
||||
|
||||
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. function:: enable()
|
||||
|
||||
Enable automatic garbage collection.
|
||||
|
||||
.. function:: disable()
|
||||
|
||||
Disable automatic garbage collection. Heap memory can still be allocated,
|
||||
and garbage collection can still be initiated manually using :meth:`gc.collect`.
|
||||
|
||||
.. function:: collect()
|
||||
|
||||
Run a garbage collection.
|
||||
|
||||
.. function:: disable()
|
||||
|
||||
Disable the garbage collector.
|
||||
|
||||
.. function:: enable()
|
||||
|
||||
Enable the garbage collector.
|
||||
|
||||
.. function:: mem_alloc()
|
||||
|
||||
Return the number of bytes of heap RAM that are allocated.
|
||||
|
|
9
py/gc.c
9
py/gc.c
|
@ -28,6 +28,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
|
@ -68,7 +69,8 @@ STATIC mp_uint_t *gc_pool_end;
|
|||
STATIC int gc_stack_overflow;
|
||||
STATIC mp_uint_t gc_stack[STACK_SIZE];
|
||||
STATIC mp_uint_t *gc_sp;
|
||||
STATIC mp_uint_t gc_lock_depth;
|
||||
STATIC uint16_t gc_lock_depth;
|
||||
uint16_t gc_auto_collect_enabled;
|
||||
STATIC mp_uint_t gc_last_free_atb_index;
|
||||
|
||||
// ATB = allocation table byte
|
||||
|
@ -163,6 +165,9 @@ void gc_init(void *start, void *end) {
|
|||
// unlock the GC
|
||||
gc_lock_depth = 0;
|
||||
|
||||
// allow auto collection
|
||||
gc_auto_collect_enabled = 1;
|
||||
|
||||
DEBUG_printf("GC layout:\n");
|
||||
DEBUG_printf(" alloc table at %p, length " UINT_FMT " bytes, " UINT_FMT " blocks\n", gc_alloc_table_start, gc_alloc_table_byte_len, gc_alloc_table_byte_len * BLOCKS_PER_ATB);
|
||||
#if MICROPY_ENABLE_FINALISER
|
||||
|
@ -375,7 +380,7 @@ void *gc_alloc(mp_uint_t n_bytes, bool has_finaliser) {
|
|||
mp_uint_t end_block;
|
||||
mp_uint_t start_block;
|
||||
mp_uint_t n_free = 0;
|
||||
int collected = 0;
|
||||
int collected = !gc_auto_collect_enabled;
|
||||
for (;;) {
|
||||
|
||||
// look for a run of n_blocks available blocks
|
||||
|
|
5
py/gc.h
5
py/gc.h
|
@ -32,6 +32,11 @@ void gc_lock(void);
|
|||
void gc_unlock(void);
|
||||
bool gc_is_locked(void);
|
||||
|
||||
// This variable controls auto garbage collection. If set to 0 then the
|
||||
// GC won't automatically run when gc_alloc can't find enough blocks. But
|
||||
// you can still allocate/free memory and also explicitly call gc_collect.
|
||||
extern uint16_t gc_auto_collect_enabled;
|
||||
|
||||
// A given port must implement gc_collect by using the other collect functions.
|
||||
void gc_collect(void);
|
||||
void gc_collect_start(void);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
|
|
16
py/modgc.c
16
py/modgc.c
|
@ -24,15 +24,13 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "builtin.h"
|
||||
#include "runtime.h"
|
||||
#include "objlist.h"
|
||||
#include "objtuple.h"
|
||||
#include "objstr.h"
|
||||
#include "gc.h"
|
||||
|
||||
#if MICROPY_PY_GC && MICROPY_ENABLE_GC
|
||||
|
@ -56,7 +54,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(gc_collect_obj, py_gc_collect);
|
|||
/// \function disable()
|
||||
/// Disable the garbage collector.
|
||||
STATIC mp_obj_t gc_disable(void) {
|
||||
gc_lock();
|
||||
gc_auto_collect_enabled = 0;
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(gc_disable_obj, gc_disable);
|
||||
|
@ -64,11 +62,16 @@ MP_DEFINE_CONST_FUN_OBJ_0(gc_disable_obj, gc_disable);
|
|||
/// \function enable()
|
||||
/// Enable the garbage collector.
|
||||
STATIC mp_obj_t gc_enable(void) {
|
||||
gc_unlock();
|
||||
gc_auto_collect_enabled = 1;
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(gc_enable_obj, gc_enable);
|
||||
|
||||
STATIC mp_obj_t gc_isenabled(void) {
|
||||
return MP_BOOL(gc_auto_collect_enabled);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(gc_isenabled_obj, gc_isenabled);
|
||||
|
||||
/// \function mem_free()
|
||||
/// Return the number of bytes of available heap RAM.
|
||||
STATIC mp_obj_t gc_mem_free(void) {
|
||||
|
@ -92,6 +95,7 @@ STATIC const mp_map_elem_t mp_module_gc_globals_table[] = {
|
|||
{ MP_OBJ_NEW_QSTR(MP_QSTR_collect), (mp_obj_t)&gc_collect_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable), (mp_obj_t)&gc_disable_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&gc_enable_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_isenabled), (mp_obj_t)&gc_isenabled_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mem_free), (mp_obj_t)&gc_mem_free_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mem_alloc), (mp_obj_t)&gc_mem_alloc_obj },
|
||||
};
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
|
|
|
@ -470,6 +470,7 @@ Q(gc)
|
|||
Q(collect)
|
||||
Q(disable)
|
||||
Q(enable)
|
||||
Q(isenabled)
|
||||
Q(mem_free)
|
||||
Q(mem_alloc)
|
||||
#endif
|
||||
|
|
|
@ -20,7 +20,12 @@ def h():
|
|||
g(i) # default arg (second one)
|
||||
g(i, i) # 2 args
|
||||
|
||||
# call h with heap allocation disabled
|
||||
# call h with heap allocation disabled and all memory used up
|
||||
gc.disable()
|
||||
try:
|
||||
while True:
|
||||
'a'.lower # allocates 1 cell for boundmeth
|
||||
except MemoryError:
|
||||
pass
|
||||
h()
|
||||
gc.enable()
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
|
|
Loading…
Reference in New Issue