Merge pull request #3163 from tannewt/memmonitor
Add `memorymonitor` for memory allocation debugging
This commit is contained in:
commit
d22283c9c4
|
@ -78,10 +78,15 @@ msgstr ""
|
||||||
msgid "%q list must be a list"
|
msgid "%q list must be a list"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: shared-bindings/memorymonitor/AllocationAlarm.c
|
||||||
|
msgid "%q must be >= 0"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/_bleio/CharacteristicBuffer.c
|
#: shared-bindings/_bleio/CharacteristicBuffer.c
|
||||||
#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
|
#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
|
||||||
#: shared-bindings/displayio/Shape.c shared-bindings/vectorio/Circle.c
|
#: shared-bindings/displayio/Shape.c
|
||||||
#: shared-bindings/vectorio/Rectangle.c
|
#: shared-bindings/memorymonitor/AllocationAlarm.c
|
||||||
|
#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c
|
||||||
msgid "%q must be >= 1"
|
msgid "%q must be >= 1"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -319,6 +324,11 @@ msgstr ""
|
||||||
msgid "Already advertising."
|
msgid "Already advertising."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: shared-module/memorymonitor/AllocationAlarm.c
|
||||||
|
#: shared-module/memorymonitor/AllocationSize.c
|
||||||
|
msgid "Already running"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: ports/cxd56/common-hal/analogio/AnalogIn.c
|
#: ports/cxd56/common-hal/analogio/AnalogIn.c
|
||||||
msgid "AnalogIn not supported on given pin"
|
msgid "AnalogIn not supported on given pin"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -354,6 +364,11 @@ msgstr ""
|
||||||
msgid "At most %d %q may be specified (not %d)"
|
msgid "At most %d %q may be specified (not %d)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: shared-module/memorymonitor/AllocationAlarm.c
|
||||||
|
#, c-format
|
||||||
|
msgid "Attempt to allocate %d blocks"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: supervisor/shared/safe_mode.c
|
#: supervisor/shared/safe_mode.c
|
||||||
msgid "Attempted heap allocation when MicroPython VM not running."
|
msgid "Attempted heap allocation when MicroPython VM not running."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -473,7 +488,9 @@ msgstr ""
|
||||||
msgid "Can't set CCCD on local Characteristic"
|
msgid "Can't set CCCD on local Characteristic"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
|
#: shared-bindings/displayio/Bitmap.c
|
||||||
|
#: shared-bindings/memorymonitor/AllocationSize.c
|
||||||
|
#: shared-bindings/pulseio/PulseIn.c
|
||||||
msgid "Cannot delete values"
|
msgid "Cannot delete values"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1353,6 +1370,7 @@ msgstr ""
|
||||||
msgid "Random number generation error"
|
msgid "Random number generation error"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: shared-bindings/memorymonitor/AllocationSize.c
|
||||||
#: shared-bindings/pulseio/PulseIn.c
|
#: shared-bindings/pulseio/PulseIn.c
|
||||||
msgid "Read-only"
|
msgid "Read-only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -1437,7 +1455,9 @@ msgid "Slice and value different lengths."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c
|
#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c
|
||||||
#: shared-bindings/displayio/TileGrid.c shared-bindings/pulseio/PulseIn.c
|
#: shared-bindings/displayio/TileGrid.c
|
||||||
|
#: shared-bindings/memorymonitor/AllocationSize.c
|
||||||
|
#: shared-bindings/pulseio/PulseIn.c
|
||||||
msgid "Slices not supported"
|
msgid "Slices not supported"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
7
main.c
7
main.c
|
@ -64,6 +64,10 @@
|
||||||
#include "shared-module/displayio/__init__.h"
|
#include "shared-module/displayio/__init__.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CIRCUITPY_MEMORYMONITOR
|
||||||
|
#include "shared-module/memorymonitor/__init__.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CIRCUITPY_NETWORK
|
#if CIRCUITPY_NETWORK
|
||||||
#include "shared-module/network/__init__.h"
|
#include "shared-module/network/__init__.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -206,6 +210,9 @@ void cleanup_after_vm(supervisor_allocation* heap) {
|
||||||
#if CIRCUITPY_DISPLAYIO
|
#if CIRCUITPY_DISPLAYIO
|
||||||
reset_displays();
|
reset_displays();
|
||||||
#endif
|
#endif
|
||||||
|
#if CIRCUITPY_MEMORYMONITOR
|
||||||
|
memorymonitor_reset();
|
||||||
|
#endif
|
||||||
filesystem_flush();
|
filesystem_flush();
|
||||||
stop_mp();
|
stop_mp();
|
||||||
free_memory(heap);
|
free_memory(heap);
|
||||||
|
|
|
@ -174,6 +174,9 @@ endif
|
||||||
ifeq ($(CIRCUITPY__EVE),1)
|
ifeq ($(CIRCUITPY__EVE),1)
|
||||||
SRC_PATTERNS += _eve/%
|
SRC_PATTERNS += _eve/%
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(CIRCUITPY_MEMORYMONITOR),1)
|
||||||
|
SRC_PATTERNS += memorymonitor/%
|
||||||
|
endif
|
||||||
ifeq ($(CIRCUITPY_MICROCONTROLLER),1)
|
ifeq ($(CIRCUITPY_MICROCONTROLLER),1)
|
||||||
SRC_PATTERNS += microcontroller/%
|
SRC_PATTERNS += microcontroller/%
|
||||||
endif
|
endif
|
||||||
|
@ -398,6 +401,9 @@ SRC_SHARED_MODULE_ALL = \
|
||||||
gamepad/__init__.c \
|
gamepad/__init__.c \
|
||||||
gamepadshift/GamePadShift.c \
|
gamepadshift/GamePadShift.c \
|
||||||
gamepadshift/__init__.c \
|
gamepadshift/__init__.c \
|
||||||
|
memorymonitor/__init__.c \
|
||||||
|
memorymonitor/AllocationAlarm.c \
|
||||||
|
memorymonitor/AllocationSize.c \
|
||||||
network/__init__.c \
|
network/__init__.c \
|
||||||
os/__init__.c \
|
os/__init__.c \
|
||||||
random/__init__.c \
|
random/__init__.c \
|
||||||
|
|
|
@ -430,6 +430,16 @@ extern const struct _mp_obj_module_t _eve_module;
|
||||||
#define _EVE_MODULE
|
#define _EVE_MODULE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CIRCUITPY_MEMORYMONITOR
|
||||||
|
extern const struct _mp_obj_module_t memorymonitor_module;
|
||||||
|
#define MEMORYMONITOR_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_memorymonitor), (mp_obj_t)&memorymonitor_module },
|
||||||
|
#define MEMORYMONITOR_ROOT_POINTERS mp_obj_t active_allocationsizes; \
|
||||||
|
mp_obj_t active_allocationalarms;
|
||||||
|
#else
|
||||||
|
#define MEMORYMONITOR_MODULE
|
||||||
|
#define MEMORYMONITOR_ROOT_POINTERS
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CIRCUITPY_MICROCONTROLLER
|
#if CIRCUITPY_MICROCONTROLLER
|
||||||
extern const struct _mp_obj_module_t microcontroller_module;
|
extern const struct _mp_obj_module_t microcontroller_module;
|
||||||
#define MICROCONTROLLER_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)µcontroller_module },
|
#define MICROCONTROLLER_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)µcontroller_module },
|
||||||
|
@ -709,6 +719,7 @@ extern const struct _mp_obj_module_t watchdog_module;
|
||||||
JSON_MODULE \
|
JSON_MODULE \
|
||||||
MATH_MODULE \
|
MATH_MODULE \
|
||||||
_EVE_MODULE \
|
_EVE_MODULE \
|
||||||
|
MEMORYMONITOR_MODULE \
|
||||||
MICROCONTROLLER_MODULE \
|
MICROCONTROLLER_MODULE \
|
||||||
NEOPIXEL_WRITE_MODULE \
|
NEOPIXEL_WRITE_MODULE \
|
||||||
NETWORK_MODULE \
|
NETWORK_MODULE \
|
||||||
|
@ -766,6 +777,7 @@ extern const struct _mp_obj_module_t watchdog_module;
|
||||||
mp_obj_t terminal_tilegrid_tiles; \
|
mp_obj_t terminal_tilegrid_tiles; \
|
||||||
BOARD_UART_ROOT_POINTER \
|
BOARD_UART_ROOT_POINTER \
|
||||||
FLASH_ROOT_POINTERS \
|
FLASH_ROOT_POINTERS \
|
||||||
|
MEMORYMONITOR_ROOT_POINTERS \
|
||||||
NETWORK_ROOT_POINTERS \
|
NETWORK_ROOT_POINTERS \
|
||||||
|
|
||||||
void supervisor_run_background_tasks_if_tick(void);
|
void supervisor_run_background_tasks_if_tick(void);
|
||||||
|
|
|
@ -118,6 +118,9 @@ CFLAGS += -DCIRCUITPY_MATH=$(CIRCUITPY_MATH)
|
||||||
CIRCUITPY__EVE ?= 0
|
CIRCUITPY__EVE ?= 0
|
||||||
CFLAGS += -DCIRCUITPY__EVE=$(CIRCUITPY__EVE)
|
CFLAGS += -DCIRCUITPY__EVE=$(CIRCUITPY__EVE)
|
||||||
|
|
||||||
|
CIRCUITPY_MEMORYMONITOR ?= 0
|
||||||
|
CFLAGS += -DCIRCUITPY_MEMORYMONITOR=$(CIRCUITPY_MEMORYMONITOR)
|
||||||
|
|
||||||
CIRCUITPY_MICROCONTROLLER ?= 1
|
CIRCUITPY_MICROCONTROLLER ?= 1
|
||||||
CFLAGS += -DCIRCUITPY_MICROCONTROLLER=$(CIRCUITPY_MICROCONTROLLER)
|
CFLAGS += -DCIRCUITPY_MICROCONTROLLER=$(CIRCUITPY_MICROCONTROLLER)
|
||||||
|
|
||||||
|
|
16
py/gc.c
16
py/gc.c
|
@ -33,6 +33,10 @@
|
||||||
|
|
||||||
#include "supervisor/shared/safe_mode.h"
|
#include "supervisor/shared/safe_mode.h"
|
||||||
|
|
||||||
|
#if CIRCUITPY_MEMORYMONITOR
|
||||||
|
#include "shared-module/memorymonitor/__init__.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if MICROPY_ENABLE_GC
|
#if MICROPY_ENABLE_GC
|
||||||
|
|
||||||
#if MICROPY_DEBUG_VERBOSE // print debugging info
|
#if MICROPY_DEBUG_VERBOSE // print debugging info
|
||||||
|
@ -653,6 +657,10 @@ void *gc_alloc(size_t n_bytes, bool has_finaliser, bool long_lived) {
|
||||||
gc_dump_alloc_table();
|
gc_dump_alloc_table();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CIRCUITPY_MEMORYMONITOR
|
||||||
|
memorymonitor_track_allocation(end_block - start_block + 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
return ret_ptr;
|
return ret_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -906,6 +914,10 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) {
|
||||||
gc_log_change(block, new_blocks);
|
gc_log_change(block, new_blocks);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CIRCUITPY_MEMORYMONITOR
|
||||||
|
memorymonitor_track_allocation(new_blocks);
|
||||||
|
#endif
|
||||||
|
|
||||||
return ptr_in;
|
return ptr_in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -935,6 +947,10 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) {
|
||||||
gc_log_change(block, new_blocks);
|
gc_log_change(block, new_blocks);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CIRCUITPY_MEMORYMONITOR
|
||||||
|
memorymonitor_track_allocation(new_blocks);
|
||||||
|
#endif
|
||||||
|
|
||||||
return ptr_in;
|
return ptr_in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,9 +58,8 @@
|
||||||
//| This object is the sole instance of `_bleio.Adapter`."""
|
//| This object is the sole instance of `_bleio.Adapter`."""
|
||||||
//|
|
//|
|
||||||
|
|
||||||
|
|
||||||
//| class BluetoothError(Exception):
|
//| class BluetoothError(Exception):
|
||||||
//| """Catch all exception for Bluetooth related errors."""
|
//| """Catchall exception for Bluetooth related errors."""
|
||||||
//| ...
|
//| ...
|
||||||
MP_DEFINE_BLEIO_EXCEPTION(BluetoothError, Exception)
|
MP_DEFINE_BLEIO_EXCEPTION(BluetoothError, Exception)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "py/objproperty.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
#include "py/runtime0.h"
|
||||||
|
#include "shared-bindings/memorymonitor/AllocationAlarm.h"
|
||||||
|
#include "shared-bindings/util.h"
|
||||||
|
#include "supervisor/shared/translate.h"
|
||||||
|
|
||||||
|
//| class AllocationAlarm:
|
||||||
|
//|
|
||||||
|
//| def __init__(self, *, minimum_block_count=1):
|
||||||
|
//| """Throw an exception when an allocation of ``minimum_block_count`` or more blocks
|
||||||
|
//| occurs while active.
|
||||||
|
//|
|
||||||
|
//| Track allocations::
|
||||||
|
//|
|
||||||
|
//| import memorymonitor
|
||||||
|
//|
|
||||||
|
//| aa = memorymonitor.AllocationAlarm(minimum_block_count=2)
|
||||||
|
//| x = 2
|
||||||
|
//| # Should not allocate any blocks.
|
||||||
|
//| with aa:
|
||||||
|
//| x = 5
|
||||||
|
//|
|
||||||
|
//| # Should throw an exception when allocating storage for the 20 bytes.
|
||||||
|
//| with aa:
|
||||||
|
//| x = bytearray(20)
|
||||||
|
//|
|
||||||
|
//| """
|
||||||
|
//| ...
|
||||||
|
//|
|
||||||
|
STATIC mp_obj_t memorymonitor_allocationalarm_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||||
|
enum { ARG_minimum_block_count };
|
||||||
|
static const mp_arg_t allowed_args[] = {
|
||||||
|
{ MP_QSTR_minimum_block_count, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
|
||||||
|
};
|
||||||
|
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||||
|
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||||
|
mp_int_t minimum_block_count = args[ARG_minimum_block_count].u_int;
|
||||||
|
if (minimum_block_count < 1) {
|
||||||
|
mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_minimum_block_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
memorymonitor_allocationalarm_obj_t *self = m_new_obj(memorymonitor_allocationalarm_obj_t);
|
||||||
|
self->base.type = &memorymonitor_allocationalarm_type;
|
||||||
|
|
||||||
|
common_hal_memorymonitor_allocationalarm_construct(self, minimum_block_count);
|
||||||
|
|
||||||
|
return MP_OBJ_FROM_PTR(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
//| def ignore(self, count) -> AllocationAlarm:
|
||||||
|
//| """Sets the number of applicable allocations to ignore before raising the exception.
|
||||||
|
//| Automatically set back to zero at context exit.
|
||||||
|
//|
|
||||||
|
//| Use it within a ``with`` block::
|
||||||
|
//|
|
||||||
|
//| # Will not alarm because the bytearray allocation will be ignored.
|
||||||
|
//| with aa.ignore(2):
|
||||||
|
//| x = bytearray(20)
|
||||||
|
//| """
|
||||||
|
//| ...
|
||||||
|
//|
|
||||||
|
STATIC mp_obj_t memorymonitor_allocationalarm_obj_ignore(mp_obj_t self_in, mp_obj_t count_obj) {
|
||||||
|
mp_int_t count = mp_obj_get_int(count_obj);
|
||||||
|
if (count < 0) {
|
||||||
|
mp_raise_ValueError_varg(translate("%q must be >= 0"), MP_QSTR_count);
|
||||||
|
}
|
||||||
|
common_hal_memorymonitor_allocationalarm_set_ignore(self_in, count);
|
||||||
|
return self_in;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_2(memorymonitor_allocationalarm_ignore_obj, memorymonitor_allocationalarm_obj_ignore);
|
||||||
|
|
||||||
|
//| def __enter__(self) -> memorymonitor.AllocationAlarm:
|
||||||
|
//| """Enables the alarm."""
|
||||||
|
//| ...
|
||||||
|
//|
|
||||||
|
STATIC mp_obj_t memorymonitor_allocationalarm_obj___enter__(mp_obj_t self_in) {
|
||||||
|
common_hal_memorymonitor_allocationalarm_resume(self_in);
|
||||||
|
return self_in;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(memorymonitor_allocationalarm___enter___obj, memorymonitor_allocationalarm_obj___enter__);
|
||||||
|
|
||||||
|
//| def __exit__(self) -> None:
|
||||||
|
//| """Automatically disables the allocation alarm when exiting a context. See
|
||||||
|
//| :ref:`lifetime-and-contextmanagers` for more info."""
|
||||||
|
//| ...
|
||||||
|
//|
|
||||||
|
STATIC mp_obj_t memorymonitor_allocationalarm_obj___exit__(size_t n_args, const mp_obj_t *args) {
|
||||||
|
(void)n_args;
|
||||||
|
common_hal_memorymonitor_allocationalarm_set_ignore(args[0], 0);
|
||||||
|
common_hal_memorymonitor_allocationalarm_pause(args[0]);
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(memorymonitor_allocationalarm___exit___obj, 4, 4, memorymonitor_allocationalarm_obj___exit__);
|
||||||
|
|
||||||
|
STATIC const mp_rom_map_elem_t memorymonitor_allocationalarm_locals_dict_table[] = {
|
||||||
|
// Methods
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_ignore), MP_ROM_PTR(&memorymonitor_allocationalarm_ignore_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&memorymonitor_allocationalarm___enter___obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&memorymonitor_allocationalarm___exit___obj) },
|
||||||
|
};
|
||||||
|
STATIC MP_DEFINE_CONST_DICT(memorymonitor_allocationalarm_locals_dict, memorymonitor_allocationalarm_locals_dict_table);
|
||||||
|
|
||||||
|
const mp_obj_type_t memorymonitor_allocationalarm_type = {
|
||||||
|
{ &mp_type_type },
|
||||||
|
.name = MP_QSTR_AllocationAlarm,
|
||||||
|
.make_new = memorymonitor_allocationalarm_make_new,
|
||||||
|
.locals_dict = (mp_obj_dict_t*)&memorymonitor_allocationalarm_locals_dict,
|
||||||
|
};
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR_ALLOCATIONALARM_H
|
||||||
|
#define MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR_ALLOCATIONALARM_H
|
||||||
|
|
||||||
|
#include "shared-module/memorymonitor/AllocationAlarm.h"
|
||||||
|
|
||||||
|
extern const mp_obj_type_t memorymonitor_allocationalarm_type;
|
||||||
|
|
||||||
|
void common_hal_memorymonitor_allocationalarm_construct(memorymonitor_allocationalarm_obj_t* self, size_t minimum_block_count);
|
||||||
|
void common_hal_memorymonitor_allocationalarm_pause(memorymonitor_allocationalarm_obj_t* self);
|
||||||
|
void common_hal_memorymonitor_allocationalarm_resume(memorymonitor_allocationalarm_obj_t* self);
|
||||||
|
void common_hal_memorymonitor_allocationalarm_set_ignore(memorymonitor_allocationalarm_obj_t* self, mp_int_t count);
|
||||||
|
|
||||||
|
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR_ALLOCATIONALARM_H
|
|
@ -0,0 +1,183 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "py/objproperty.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
#include "py/runtime0.h"
|
||||||
|
#include "shared-bindings/memorymonitor/AllocationSize.h"
|
||||||
|
#include "shared-bindings/util.h"
|
||||||
|
#include "supervisor/shared/translate.h"
|
||||||
|
|
||||||
|
//| class AllocationSize:
|
||||||
|
//|
|
||||||
|
//| def __init__(self):
|
||||||
|
//| """Tracks the number of allocations in power of two buckets.
|
||||||
|
//|
|
||||||
|
//| It will have 16 16-bit buckets to track allocation counts. It is total allocations
|
||||||
|
//| meaning frees are ignored. Reallocated memory is counted twice, at allocation and when
|
||||||
|
//| reallocated with the larger size.
|
||||||
|
//|
|
||||||
|
//| The buckets are measured in terms of blocks which is the finest granularity of the heap.
|
||||||
|
//| This means bucket 0 will count all allocations less than or equal to the number of bytes
|
||||||
|
//| per block, typically 16. Bucket 2 will be less than or equal to 4 blocks. See
|
||||||
|
//| `bytes_per_block` to convert blocks to bytes.
|
||||||
|
//|
|
||||||
|
//| Multiple AllocationSizes can be used to track different code boundaries.
|
||||||
|
//|
|
||||||
|
//| Track allocations::
|
||||||
|
//|
|
||||||
|
//| import memorymonitor
|
||||||
|
//|
|
||||||
|
//| mm = memorymonitor.AllocationSize()
|
||||||
|
//| with mm:
|
||||||
|
//| print("hello world" * 3)
|
||||||
|
//|
|
||||||
|
//| for bucket, count in enumerate(mm):
|
||||||
|
//| print("<", 2 ** bucket, count)
|
||||||
|
//|
|
||||||
|
//| """
|
||||||
|
//| ...
|
||||||
|
//|
|
||||||
|
STATIC mp_obj_t memorymonitor_allocationsize_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||||
|
memorymonitor_allocationsize_obj_t *self = m_new_obj(memorymonitor_allocationsize_obj_t);
|
||||||
|
self->base.type = &memorymonitor_allocationsize_type;
|
||||||
|
|
||||||
|
common_hal_memorymonitor_allocationsize_construct(self);
|
||||||
|
|
||||||
|
return MP_OBJ_FROM_PTR(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
//| def __enter__(self, ) -> Any:
|
||||||
|
//| """Clears counts and resumes tracking."""
|
||||||
|
//| ...
|
||||||
|
//|
|
||||||
|
STATIC mp_obj_t memorymonitor_allocationsize_obj___enter__(mp_obj_t self_in) {
|
||||||
|
common_hal_memorymonitor_allocationsize_clear(self_in);
|
||||||
|
common_hal_memorymonitor_allocationsize_resume(self_in);
|
||||||
|
return self_in;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(memorymonitor_allocationsize___enter___obj, memorymonitor_allocationsize_obj___enter__);
|
||||||
|
|
||||||
|
//| def __exit__(self, ) -> Any:
|
||||||
|
//| """Automatically pauses allocation tracking when exiting a context. See
|
||||||
|
//| :ref:`lifetime-and-contextmanagers` for more info."""
|
||||||
|
//| ...
|
||||||
|
//|
|
||||||
|
STATIC mp_obj_t memorymonitor_allocationsize_obj___exit__(size_t n_args, const mp_obj_t *args) {
|
||||||
|
(void)n_args;
|
||||||
|
common_hal_memorymonitor_allocationsize_pause(args[0]);
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(memorymonitor_allocationsize___exit___obj, 4, 4, memorymonitor_allocationsize_obj___exit__);
|
||||||
|
|
||||||
|
//| bytes_per_block: int = ...
|
||||||
|
//| """Number of bytes per block"""
|
||||||
|
//|
|
||||||
|
STATIC mp_obj_t memorymonitor_allocationsize_obj_get_bytes_per_block(mp_obj_t self_in) {
|
||||||
|
memorymonitor_allocationsize_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(common_hal_memorymonitor_allocationsize_get_bytes_per_block(self));
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(memorymonitor_allocationsize_get_bytes_per_block_obj, memorymonitor_allocationsize_obj_get_bytes_per_block);
|
||||||
|
|
||||||
|
const mp_obj_property_t memorymonitor_allocationsize_bytes_per_block_obj = {
|
||||||
|
.base.type = &mp_type_property,
|
||||||
|
.proxy = {(mp_obj_t)&memorymonitor_allocationsize_get_bytes_per_block_obj,
|
||||||
|
(mp_obj_t)&mp_const_none_obj,
|
||||||
|
(mp_obj_t)&mp_const_none_obj},
|
||||||
|
};
|
||||||
|
|
||||||
|
//| def __len__(self, ) -> Any:
|
||||||
|
//| """Returns the number of allocation buckets.
|
||||||
|
//|
|
||||||
|
//| This allows you to::
|
||||||
|
//|
|
||||||
|
//| mm = memorymonitor.AllocationSize()
|
||||||
|
//| print(len(mm))"""
|
||||||
|
//| ...
|
||||||
|
//|
|
||||||
|
STATIC mp_obj_t memorymonitor_allocationsize_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
|
||||||
|
memorymonitor_allocationsize_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
uint16_t len = common_hal_memorymonitor_allocationsize_get_len(self);
|
||||||
|
switch (op) {
|
||||||
|
case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0);
|
||||||
|
case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(len);
|
||||||
|
default: return MP_OBJ_NULL; // op not supported
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//| def __getitem__(self, index: Any) -> Any:
|
||||||
|
//| """Returns the allocation count for the given bucket.
|
||||||
|
//|
|
||||||
|
//| This allows you to::
|
||||||
|
//|
|
||||||
|
//| mm = memorymonitor.AllocationSize()
|
||||||
|
//| print(mm[0])"""
|
||||||
|
//| ...
|
||||||
|
//|
|
||||||
|
STATIC mp_obj_t memorymonitor_allocationsize_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value) {
|
||||||
|
if (value == mp_const_none) {
|
||||||
|
// delete item
|
||||||
|
mp_raise_AttributeError(translate("Cannot delete values"));
|
||||||
|
} else {
|
||||||
|
memorymonitor_allocationsize_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
|
||||||
|
if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) {
|
||||||
|
mp_raise_NotImplementedError(translate("Slices not supported"));
|
||||||
|
} else {
|
||||||
|
size_t index = mp_get_index(&memorymonitor_allocationsize_type, common_hal_memorymonitor_allocationsize_get_len(self), index_obj, false);
|
||||||
|
if (value == MP_OBJ_SENTINEL) {
|
||||||
|
// load
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(common_hal_memorymonitor_allocationsize_get_item(self, index));
|
||||||
|
} else {
|
||||||
|
mp_raise_AttributeError(translate("Read-only"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC const mp_rom_map_elem_t memorymonitor_allocationsize_locals_dict_table[] = {
|
||||||
|
// Methods
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&memorymonitor_allocationsize___enter___obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&memorymonitor_allocationsize___exit___obj) },
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_bytes_per_block), MP_ROM_PTR(&memorymonitor_allocationsize_bytes_per_block_obj) },
|
||||||
|
};
|
||||||
|
STATIC MP_DEFINE_CONST_DICT(memorymonitor_allocationsize_locals_dict, memorymonitor_allocationsize_locals_dict_table);
|
||||||
|
|
||||||
|
const mp_obj_type_t memorymonitor_allocationsize_type = {
|
||||||
|
{ &mp_type_type },
|
||||||
|
.name = MP_QSTR_AllocationSize,
|
||||||
|
.make_new = memorymonitor_allocationsize_make_new,
|
||||||
|
.subscr = memorymonitor_allocationsize_subscr,
|
||||||
|
.unary_op = memorymonitor_allocationsize_unary_op,
|
||||||
|
.getiter = mp_obj_new_generic_iterator,
|
||||||
|
.locals_dict = (mp_obj_dict_t*)&memorymonitor_allocationsize_locals_dict,
|
||||||
|
};
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR_ALLOCATIONSIZE_H
|
||||||
|
#define MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR_ALLOCATIONSIZE_H
|
||||||
|
|
||||||
|
#include "shared-module/memorymonitor/AllocationSize.h"
|
||||||
|
|
||||||
|
extern const mp_obj_type_t memorymonitor_allocationsize_type;
|
||||||
|
|
||||||
|
extern void common_hal_memorymonitor_allocationsize_construct(memorymonitor_allocationsize_obj_t* self);
|
||||||
|
extern void common_hal_memorymonitor_allocationsize_pause(memorymonitor_allocationsize_obj_t* self);
|
||||||
|
extern void common_hal_memorymonitor_allocationsize_resume(memorymonitor_allocationsize_obj_t* self);
|
||||||
|
extern void common_hal_memorymonitor_allocationsize_clear(memorymonitor_allocationsize_obj_t* self);
|
||||||
|
extern size_t common_hal_memorymonitor_allocationsize_get_bytes_per_block(memorymonitor_allocationsize_obj_t* self);
|
||||||
|
extern uint16_t common_hal_memorymonitor_allocationsize_get_len(memorymonitor_allocationsize_obj_t* self);
|
||||||
|
extern uint16_t common_hal_memorymonitor_allocationsize_get_item(memorymonitor_allocationsize_obj_t* self, int16_t index);
|
||||||
|
|
||||||
|
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR_ALLOCATIONSIZE_H
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Scott Shawcroft
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "py/obj.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
|
||||||
|
#include "shared-bindings/memorymonitor/__init__.h"
|
||||||
|
#include "shared-bindings/memorymonitor/AllocationAlarm.h"
|
||||||
|
#include "shared-bindings/memorymonitor/AllocationSize.h"
|
||||||
|
|
||||||
|
//| """Memory monitoring helpers"""
|
||||||
|
//|
|
||||||
|
|
||||||
|
//| class AllocationError:
|
||||||
|
//| def __init__(self, Exception: Any):
|
||||||
|
//| """Catchall exception for allocation related errors."""
|
||||||
|
//| ...
|
||||||
|
MP_DEFINE_MEMORYMONITOR_EXCEPTION(AllocationError, Exception)
|
||||||
|
|
||||||
|
NORETURN void mp_raise_memorymonitor_AllocationError(const compressed_string_t* fmt, ...) {
|
||||||
|
va_list argptr;
|
||||||
|
va_start(argptr,fmt);
|
||||||
|
mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_memorymonitor_AllocationError, fmt, argptr);
|
||||||
|
va_end(argptr);
|
||||||
|
nlr_raise(exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC const mp_rom_map_elem_t memorymonitor_module_globals_table[] = {
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_memorymonitor) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_AllocationAlarm), MP_ROM_PTR(&memorymonitor_allocationalarm_type) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_AllocationSize), MP_ROM_PTR(&memorymonitor_allocationsize_type) },
|
||||||
|
|
||||||
|
// Errors
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_AllocationError), MP_ROM_PTR(&mp_type_memorymonitor_AllocationError) },
|
||||||
|
};
|
||||||
|
|
||||||
|
STATIC MP_DEFINE_CONST_DICT(memorymonitor_module_globals, memorymonitor_module_globals_table);
|
||||||
|
|
||||||
|
void memorymonitor_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) {
|
||||||
|
mp_print_kind_t k = kind & ~PRINT_EXC_SUBCLASS;
|
||||||
|
bool is_subclass = kind & PRINT_EXC_SUBCLASS;
|
||||||
|
if (!is_subclass && (k == PRINT_EXC)) {
|
||||||
|
mp_print_str(print, qstr_str(MP_OBJ_QSTR_VALUE(memorymonitor_module_globals_table[0].value)));
|
||||||
|
mp_print_str(print, ".");
|
||||||
|
}
|
||||||
|
mp_obj_exception_print(print, o_in, kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
const mp_obj_module_t memorymonitor_module = {
|
||||||
|
.base = { &mp_type_module },
|
||||||
|
.globals = (mp_obj_dict_t*)&memorymonitor_module_globals,
|
||||||
|
};
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 Scott Shawcroft
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR___INIT___H
|
||||||
|
#define MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR___INIT___H
|
||||||
|
|
||||||
|
#include "py/obj.h"
|
||||||
|
|
||||||
|
|
||||||
|
void memorymonitor_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind);
|
||||||
|
|
||||||
|
#define MP_DEFINE_MEMORYMONITOR_EXCEPTION(exc_name, base_name) \
|
||||||
|
const mp_obj_type_t mp_type_memorymonitor_ ## exc_name = { \
|
||||||
|
{ &mp_type_type }, \
|
||||||
|
.name = MP_QSTR_ ## exc_name, \
|
||||||
|
.print = memorymonitor_exception_print, \
|
||||||
|
.make_new = mp_obj_exception_make_new, \
|
||||||
|
.attr = mp_obj_exception_attr, \
|
||||||
|
.parent = &mp_type_ ## base_name, \
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const mp_obj_type_t mp_type_memorymonitor_AllocationError;
|
||||||
|
|
||||||
|
NORETURN void mp_raise_memorymonitor_AllocationError(const compressed_string_t* msg, ...);
|
||||||
|
|
||||||
|
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMONITOR___INIT___H
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shared-bindings/memorymonitor/__init__.h"
|
||||||
|
#include "shared-bindings/memorymonitor/AllocationAlarm.h"
|
||||||
|
|
||||||
|
#include "py/gc.h"
|
||||||
|
#include "py/mpstate.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
|
||||||
|
void common_hal_memorymonitor_allocationalarm_construct(memorymonitor_allocationalarm_obj_t* self, size_t minimum_block_count) {
|
||||||
|
self->minimum_block_count = minimum_block_count;
|
||||||
|
self->next = NULL;
|
||||||
|
self->previous = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void common_hal_memorymonitor_allocationalarm_set_ignore(memorymonitor_allocationalarm_obj_t* self, mp_int_t count) {
|
||||||
|
self->count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void common_hal_memorymonitor_allocationalarm_pause(memorymonitor_allocationalarm_obj_t* self) {
|
||||||
|
// Check to make sure we aren't already paused. We can be if we're exiting from an exception we
|
||||||
|
// caused.
|
||||||
|
if (self->previous == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*self->previous = self->next;
|
||||||
|
self->next = NULL;
|
||||||
|
self->previous = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void common_hal_memorymonitor_allocationalarm_resume(memorymonitor_allocationalarm_obj_t* self) {
|
||||||
|
if (self->previous != NULL) {
|
||||||
|
mp_raise_RuntimeError(translate("Already running"));
|
||||||
|
}
|
||||||
|
self->next = MP_STATE_VM(active_allocationalarms);
|
||||||
|
self->previous = (memorymonitor_allocationalarm_obj_t**) &MP_STATE_VM(active_allocationalarms);
|
||||||
|
if (self->next != NULL) {
|
||||||
|
self->next->previous = &self->next;
|
||||||
|
}
|
||||||
|
MP_STATE_VM(active_allocationalarms) = self;
|
||||||
|
}
|
||||||
|
|
||||||
|
void memorymonitor_allocationalarms_allocation(size_t block_count) {
|
||||||
|
memorymonitor_allocationalarm_obj_t* alarm = MP_OBJ_TO_PTR(MP_STATE_VM(active_allocationalarms));
|
||||||
|
size_t alert_count = 0;
|
||||||
|
while (alarm != NULL) {
|
||||||
|
// Hold onto next in case we remove the alarm from the list.
|
||||||
|
memorymonitor_allocationalarm_obj_t* next = alarm->next;
|
||||||
|
if (block_count >= alarm->minimum_block_count) {
|
||||||
|
if (alarm->count > 0) {
|
||||||
|
alarm->count--;
|
||||||
|
} else {
|
||||||
|
// Uncomment the breakpoint below if you want to use a C debugger to figure out the C
|
||||||
|
// call stack for an allocation.
|
||||||
|
// asm("bkpt");
|
||||||
|
// Pause now because we may alert when throwing the exception too.
|
||||||
|
common_hal_memorymonitor_allocationalarm_pause(alarm);
|
||||||
|
alert_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
alarm = next;
|
||||||
|
}
|
||||||
|
if (alert_count > 0) {
|
||||||
|
mp_raise_memorymonitor_AllocationError(translate("Attempt to allocate %d blocks"), block_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void memorymonitor_allocationalarms_reset(void) {
|
||||||
|
MP_STATE_VM(active_allocationalarms) = NULL;
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MICROPY_INCLUDED_SHARED_MODULE_MEMORYMONITOR_ALLOCATIONALARM_H
|
||||||
|
#define MICROPY_INCLUDED_SHARED_MODULE_MEMORYMONITOR_ALLOCATIONALARM_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "py/obj.h"
|
||||||
|
|
||||||
|
typedef struct _memorymonitor_allocationalarm_obj_t memorymonitor_allocationalarm_obj_t;
|
||||||
|
|
||||||
|
#define ALLOCATION_SIZE_BUCKETS 16
|
||||||
|
|
||||||
|
typedef struct _memorymonitor_allocationalarm_obj_t {
|
||||||
|
mp_obj_base_t base;
|
||||||
|
size_t minimum_block_count;
|
||||||
|
mp_int_t count;
|
||||||
|
// Store the location that points to us so we can remove ourselves.
|
||||||
|
memorymonitor_allocationalarm_obj_t** previous;
|
||||||
|
memorymonitor_allocationalarm_obj_t* next;
|
||||||
|
} memorymonitor_allocationalarm_obj_t;
|
||||||
|
|
||||||
|
void memorymonitor_allocationalarms_allocation(size_t block_count);
|
||||||
|
void memorymonitor_allocationalarms_reset(void);
|
||||||
|
|
||||||
|
#endif // MICROPY_INCLUDED_SHARED_MODULE_MEMORYMONITOR_ALLOCATIONALARM_H
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shared-bindings/memorymonitor/AllocationSize.h"
|
||||||
|
|
||||||
|
#include "py/gc.h"
|
||||||
|
#include "py/mpstate.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
|
||||||
|
void common_hal_memorymonitor_allocationsize_construct(memorymonitor_allocationsize_obj_t* self) {
|
||||||
|
common_hal_memorymonitor_allocationsize_clear(self);
|
||||||
|
self->next = NULL;
|
||||||
|
self->previous = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void common_hal_memorymonitor_allocationsize_pause(memorymonitor_allocationsize_obj_t* self) {
|
||||||
|
*self->previous = self->next;
|
||||||
|
self->next = NULL;
|
||||||
|
self->previous = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void common_hal_memorymonitor_allocationsize_resume(memorymonitor_allocationsize_obj_t* self) {
|
||||||
|
if (self->previous != NULL) {
|
||||||
|
mp_raise_RuntimeError(translate("Already running"));
|
||||||
|
}
|
||||||
|
self->next = MP_STATE_VM(active_allocationsizes);
|
||||||
|
self->previous = (memorymonitor_allocationsize_obj_t**) &MP_STATE_VM(active_allocationsizes);
|
||||||
|
if (self->next != NULL) {
|
||||||
|
self->next->previous = &self->next;
|
||||||
|
}
|
||||||
|
MP_STATE_VM(active_allocationsizes) = self;
|
||||||
|
}
|
||||||
|
|
||||||
|
void common_hal_memorymonitor_allocationsize_clear(memorymonitor_allocationsize_obj_t* self) {
|
||||||
|
for (size_t i = 0; i < ALLOCATION_SIZE_BUCKETS; i++) {
|
||||||
|
self->buckets[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t common_hal_memorymonitor_allocationsize_get_len(memorymonitor_allocationsize_obj_t* self) {
|
||||||
|
return ALLOCATION_SIZE_BUCKETS;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t common_hal_memorymonitor_allocationsize_get_bytes_per_block(memorymonitor_allocationsize_obj_t* self) {
|
||||||
|
return BYTES_PER_BLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t common_hal_memorymonitor_allocationsize_get_item(memorymonitor_allocationsize_obj_t* self, int16_t index) {
|
||||||
|
return self->buckets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void memorymonitor_allocationsizes_track_allocation(size_t block_count) {
|
||||||
|
memorymonitor_allocationsize_obj_t* as = MP_OBJ_TO_PTR(MP_STATE_VM(active_allocationsizes));
|
||||||
|
size_t power_of_two = 0;
|
||||||
|
block_count >>= 1;
|
||||||
|
while (block_count != 0) {
|
||||||
|
power_of_two++;
|
||||||
|
block_count >>= 1;
|
||||||
|
}
|
||||||
|
while (as != NULL) {
|
||||||
|
as->buckets[power_of_two]++;
|
||||||
|
as = as->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void memorymonitor_allocationsizes_reset(void) {
|
||||||
|
MP_STATE_VM(active_allocationsizes) = NULL;
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MICROPY_INCLUDED_SHARED_MODULE_MEMORYMONITOR_ALLOCATIONSIZE_H
|
||||||
|
#define MICROPY_INCLUDED_SHARED_MODULE_MEMORYMONITOR_ALLOCATIONSIZE_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "py/obj.h"
|
||||||
|
|
||||||
|
typedef struct _memorymonitor_allocationsize_obj_t memorymonitor_allocationsize_obj_t;
|
||||||
|
|
||||||
|
#define ALLOCATION_SIZE_BUCKETS 16
|
||||||
|
|
||||||
|
typedef struct _memorymonitor_allocationsize_obj_t {
|
||||||
|
mp_obj_base_t base;
|
||||||
|
uint16_t buckets[ALLOCATION_SIZE_BUCKETS];
|
||||||
|
// Store the location that points to us so we can remove ourselves.
|
||||||
|
memorymonitor_allocationsize_obj_t** previous;
|
||||||
|
memorymonitor_allocationsize_obj_t* next;
|
||||||
|
bool paused;
|
||||||
|
} memorymonitor_allocationsize_obj_t;
|
||||||
|
|
||||||
|
void memorymonitor_allocationsizes_track_allocation(size_t block_count);
|
||||||
|
void memorymonitor_allocationsizes_reset(void);
|
||||||
|
|
||||||
|
#endif // MICROPY_INCLUDED_SHARED_MODULE_MEMORYMONITOR_ALLOCATIONSIZE_H
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Scott Shawcroft
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shared-module/memorymonitor/__init__.h"
|
||||||
|
#include "shared-module/memorymonitor/AllocationAlarm.h"
|
||||||
|
#include "shared-module/memorymonitor/AllocationSize.h"
|
||||||
|
|
||||||
|
void memorymonitor_track_allocation(size_t block_count) {
|
||||||
|
memorymonitor_allocationalarms_allocation(block_count);
|
||||||
|
memorymonitor_allocationsizes_track_allocation(block_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void memorymonitor_reset(void) {
|
||||||
|
memorymonitor_allocationalarms_reset();
|
||||||
|
memorymonitor_allocationsizes_reset();
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MICROPY_INCLUDED_MEMORYMONITOR___INIT___H
|
||||||
|
#define MICROPY_INCLUDED_MEMORYMONITOR___INIT___H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
void memorymonitor_track_allocation(size_t block_count);
|
||||||
|
void memorymonitor_reset(void);
|
||||||
|
|
||||||
|
#endif // MICROPY_INCLUDED_MEMORYMONITOR___INIT___H
|
Loading…
Reference in New Issue