Skip to content

Commit 86bfabe

Browse files
pi-anldpgeorge
authored andcommitted
py/modmicropython: Add heap_locked function to test state of heap.
This commit adds micropython.heap_locked() which returns the current lock-depth of the heap, and can be used by Python code to check if the heap is locked or not. This new function is configured via MICROPY_PY_MICROPYTHON_HEAP_LOCKED and is disabled by default. This commit also changes the return value of micropython.heap_unlock() so it returns the current lock-depth as well.
1 parent 7eea0d8 commit 86bfabe

File tree

8 files changed

+51
-1
lines changed

8 files changed

+51
-1
lines changed

docs/library/micropython.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,17 +82,26 @@ Functions
8282

8383
.. function:: heap_lock()
8484
.. function:: heap_unlock()
85+
.. function:: heap_locked()
8586

8687
Lock or unlock the heap. When locked no memory allocation can occur and a
8788
`MemoryError` will be raised if any heap allocation is attempted.
89+
`heap_locked()` returns a true value if the heap is currently locked.
8890

8991
These functions can be nested, ie `heap_lock()` can be called multiple times
9092
in a row and the lock-depth will increase, and then `heap_unlock()` must be
9193
called the same number of times to make the heap available again.
9294

95+
Both `heap_unlock()` and `heap_locked()` return the current lock depth
96+
(after unlocking for the former) as a non-negative integer, with 0 meaning
97+
the heap is not locked.
98+
9399
If the REPL becomes active with the heap locked then it will be forcefully
94100
unlocked.
95101

102+
Note: `heap_locked()` is not enabled on most ports by default,
103+
requires `MICROPY_PY_MICROPYTHON_HEAP_LOCKED`.
104+
96105
.. function:: kbd_intr(chr)
97106

98107
Set the character that will raise a `KeyboardInterrupt` exception. By

ports/unix/variants/coverage/mpconfigvariant.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
#define MICROPY_PY_COLLECTIONS_NAMEDTUPLE__ASDICT (1)
6060
#define MICROPY_PY_UCRYPTOLIB (1)
6161
#define MICROPY_PY_UCRYPTOLIB_CTR (1)
62+
#define MICROPY_PY_MICROPYTHON_HEAP_LOCKED (1)
6263

6364
// TODO these should be generic, not bound to fatfs
6465
#define mp_type_fileio mp_type_vfs_posix_fileio

py/modmicropython.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,16 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_heap_lock_obj, mp_micropython_he
130130

131131
STATIC mp_obj_t mp_micropython_heap_unlock(void) {
132132
gc_unlock();
133-
return mp_const_none;
133+
return MP_OBJ_NEW_SMALL_INT(MP_STATE_MEM(gc_lock_depth));
134134
}
135135
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_heap_unlock_obj, mp_micropython_heap_unlock);
136+
137+
#if MICROPY_PY_MICROPYTHON_HEAP_LOCKED
138+
STATIC mp_obj_t mp_micropython_heap_locked(void) {
139+
return MP_OBJ_NEW_SMALL_INT(MP_STATE_MEM(gc_lock_depth));
140+
}
141+
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_heap_locked_obj, mp_micropython_heap_locked);
142+
#endif
136143
#endif
137144

138145
#if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF && (MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE == 0)
@@ -184,6 +191,9 @@ STATIC const mp_rom_map_elem_t mp_module_micropython_globals_table[] = {
184191
#if MICROPY_ENABLE_GC
185192
{ MP_ROM_QSTR(MP_QSTR_heap_lock), MP_ROM_PTR(&mp_micropython_heap_lock_obj) },
186193
{ MP_ROM_QSTR(MP_QSTR_heap_unlock), MP_ROM_PTR(&mp_micropython_heap_unlock_obj) },
194+
#if MICROPY_PY_MICROPYTHON_HEAP_LOCKED
195+
{ MP_ROM_QSTR(MP_QSTR_heap_locked), MP_ROM_PTR(&mp_micropython_heap_locked_obj) },
196+
#endif
187197
#endif
188198
#if MICROPY_KBD_EXCEPTION
189199
{ MP_ROM_QSTR(MP_QSTR_kbd_intr), MP_ROM_PTR(&mp_micropython_kbd_intr_obj) },

py/mpconfig.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,11 @@ typedef double mp_float_t;
10691069
#define MICROPY_PY_MICROPYTHON_STACK_USE (MICROPY_PY_MICROPYTHON_MEM_INFO)
10701070
#endif
10711071

1072+
// Whether to provide the "micropython.heap_locked" function
1073+
#ifndef MICROPY_PY_MICROPYTHON_HEAP_LOCKED
1074+
#define MICROPY_PY_MICROPYTHON_HEAP_LOCKED (0)
1075+
#endif
1076+
10721077
// Whether to provide "array" module. Note that large chunk of the
10731078
// underlying code is shared with "bytearray" builtin type, so to
10741079
// get real savings, it should be disabled too.

tests/micropython/heap_lock.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
l = []
66
l2 = list(range(100))
77

8+
micropython.heap_lock()
89
micropython.heap_lock()
910

1011
# general allocation on the heap
@@ -19,6 +20,14 @@
1920
except MemoryError:
2021
print('MemoryError')
2122

23+
print(micropython.heap_unlock())
24+
25+
# Should still fail
26+
try:
27+
print([])
28+
except MemoryError:
29+
print('MemoryError')
30+
2231
micropython.heap_unlock()
2332

2433
# check that allocation works after an unlock

tests/micropython/heap_lock.py.exp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
MemoryError
22
MemoryError
3+
1
4+
MemoryError
35
[]

tests/micropython/heap_locked.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# test micropython.heap_locked()
2+
3+
import micropython
4+
5+
if not hasattr(micropython, "heap_locked"):
6+
print("SKIP")
7+
raise SystemExit
8+
9+
micropython.heap_lock()
10+
print(micropython.heap_locked())
11+
micropython.heap_unlock()
12+
print(micropython.heap_locked())
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
1
2+
0

0 commit comments

Comments
 (0)