Merge pull request #3163 from tannewt/memmonitor

Add `memorymonitor` for memory allocation debugging
This commit is contained in:
Dan Halbert 2020-07-22 19:21:41 -04:00 committed by GitHub
commit d22283c9c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 957 additions and 6 deletions

View File

@ -78,10 +78,15 @@ msgstr ""
msgid "%q list must be a list"
msgstr ""
#: shared-bindings/memorymonitor/AllocationAlarm.c
msgid "%q must be >= 0"
msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
#: shared-bindings/displayio/Shape.c shared-bindings/vectorio/Circle.c
#: shared-bindings/vectorio/Rectangle.c
#: shared-bindings/displayio/Shape.c
#: shared-bindings/memorymonitor/AllocationAlarm.c
#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c
msgid "%q must be >= 1"
msgstr ""
@ -319,6 +324,11 @@ msgstr ""
msgid "Already advertising."
msgstr ""
#: shared-module/memorymonitor/AllocationAlarm.c
#: shared-module/memorymonitor/AllocationSize.c
msgid "Already running"
msgstr ""
#: ports/cxd56/common-hal/analogio/AnalogIn.c
msgid "AnalogIn not supported on given pin"
msgstr ""
@ -354,6 +364,11 @@ msgstr ""
msgid "At most %d %q may be specified (not %d)"
msgstr ""
#: shared-module/memorymonitor/AllocationAlarm.c
#, c-format
msgid "Attempt to allocate %d blocks"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Attempted heap allocation when MicroPython VM not running."
msgstr ""
@ -473,7 +488,9 @@ msgstr ""
msgid "Can't set CCCD on local Characteristic"
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"
msgstr ""
@ -1353,6 +1370,7 @@ msgstr ""
msgid "Random number generation error"
msgstr ""
#: shared-bindings/memorymonitor/AllocationSize.c
#: shared-bindings/pulseio/PulseIn.c
msgid "Read-only"
msgstr ""
@ -1437,7 +1455,9 @@ msgid "Slice and value different lengths."
msgstr ""
#: 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"
msgstr ""

7
main.c
View File

@ -64,6 +64,10 @@
#include "shared-module/displayio/__init__.h"
#endif
#if CIRCUITPY_MEMORYMONITOR
#include "shared-module/memorymonitor/__init__.h"
#endif
#if CIRCUITPY_NETWORK
#include "shared-module/network/__init__.h"
#endif
@ -206,6 +210,9 @@ void cleanup_after_vm(supervisor_allocation* heap) {
#if CIRCUITPY_DISPLAYIO
reset_displays();
#endif
#if CIRCUITPY_MEMORYMONITOR
memorymonitor_reset();
#endif
filesystem_flush();
stop_mp();
free_memory(heap);

View File

@ -174,6 +174,9 @@ endif
ifeq ($(CIRCUITPY__EVE),1)
SRC_PATTERNS += _eve/%
endif
ifeq ($(CIRCUITPY_MEMORYMONITOR),1)
SRC_PATTERNS += memorymonitor/%
endif
ifeq ($(CIRCUITPY_MICROCONTROLLER),1)
SRC_PATTERNS += microcontroller/%
endif
@ -398,6 +401,9 @@ SRC_SHARED_MODULE_ALL = \
gamepad/__init__.c \
gamepadshift/GamePadShift.c \
gamepadshift/__init__.c \
memorymonitor/__init__.c \
memorymonitor/AllocationAlarm.c \
memorymonitor/AllocationSize.c \
network/__init__.c \
os/__init__.c \
random/__init__.c \

View File

@ -430,6 +430,16 @@ extern const struct _mp_obj_module_t _eve_module;
#define _EVE_MODULE
#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
extern const struct _mp_obj_module_t microcontroller_module;
#define MICROCONTROLLER_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)&microcontroller_module },
@ -709,6 +719,7 @@ extern const struct _mp_obj_module_t watchdog_module;
JSON_MODULE \
MATH_MODULE \
_EVE_MODULE \
MEMORYMONITOR_MODULE \
MICROCONTROLLER_MODULE \
NEOPIXEL_WRITE_MODULE \
NETWORK_MODULE \
@ -766,6 +777,7 @@ extern const struct _mp_obj_module_t watchdog_module;
mp_obj_t terminal_tilegrid_tiles; \
BOARD_UART_ROOT_POINTER \
FLASH_ROOT_POINTERS \
MEMORYMONITOR_ROOT_POINTERS \
NETWORK_ROOT_POINTERS \
void supervisor_run_background_tasks_if_tick(void);

View File

@ -118,6 +118,9 @@ CFLAGS += -DCIRCUITPY_MATH=$(CIRCUITPY_MATH)
CIRCUITPY__EVE ?= 0
CFLAGS += -DCIRCUITPY__EVE=$(CIRCUITPY__EVE)
CIRCUITPY_MEMORYMONITOR ?= 0
CFLAGS += -DCIRCUITPY_MEMORYMONITOR=$(CIRCUITPY_MEMORYMONITOR)
CIRCUITPY_MICROCONTROLLER ?= 1
CFLAGS += -DCIRCUITPY_MICROCONTROLLER=$(CIRCUITPY_MICROCONTROLLER)

16
py/gc.c
View File

@ -33,6 +33,10 @@
#include "supervisor/shared/safe_mode.h"
#if CIRCUITPY_MEMORYMONITOR
#include "shared-module/memorymonitor/__init__.h"
#endif
#if MICROPY_ENABLE_GC
#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();
#endif
#if CIRCUITPY_MEMORYMONITOR
memorymonitor_track_allocation(end_block - start_block + 1);
#endif
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);
#endif
#if CIRCUITPY_MEMORYMONITOR
memorymonitor_track_allocation(new_blocks);
#endif
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);
#endif
#if CIRCUITPY_MEMORYMONITOR
memorymonitor_track_allocation(new_blocks);
#endif
return ptr_in;
}

View File

@ -58,9 +58,8 @@
//| This object is the sole instance of `_bleio.Adapter`."""
//|
//| class BluetoothError(Exception):
//| """Catch all exception for Bluetooth related errors."""
//| """Catchall exception for Bluetooth related errors."""
//| ...
MP_DEFINE_BLEIO_EXCEPTION(BluetoothError, Exception)

View File

@ -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,
};

View File

@ -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

View File

@ -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,
};

View File

@ -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

View File

@ -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,
};

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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();
}

View File

@ -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