This repository was archived by the owner on Jan 15, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,12 +27,44 @@ extern int printf(const char *, ...); | |
|
|
||
| extern void * volatile mbed_sbrk_ptr; | ||
|
|
||
| // Set debug level to 0 until non-allocating printf is available | ||
| const UAllocDebug_t ualloc_debug_level = UALLOC_DEBUG_NONE;//(DEBUG?UALLOC_DEBUG_MAX:UALLOC_DEBUG_NONE); | ||
| /***************************************************************************************** | ||
| UALLOC_DEBUG_LOG is effectively reserved for tracing memory allocations | ||
| Tracing must be enabled via "yotta config": | ||
| { | ||
| "debug": { | ||
| "options": { | ||
| "memory-trace": true | ||
| } | ||
| } | ||
| } | ||
| [TODO]: ualloc_debug_level probably needs better control with "yotta config" | ||
| *****************************************************************************************/ | ||
| #ifdef YOTTA_CFG_DEBUG_OPTIONS_MEMORY_TRACE | ||
| const UAllocDebug_t ualloc_debug_level = UALLOC_DEBUG_LOG; | ||
| #else | ||
| const UAllocDebug_t ualloc_debug_level = UALLOC_DEBUG_NONE; | ||
| #endif | ||
|
|
||
| // Debug characters | ||
| const char ua_chars[] = "NFEWIL"; | ||
|
|
||
| /***************************************************************************************** | ||
| The purpose of "prevent_tracing" below is twofold: | ||
|
|
||
| 1. prevent infinite loops (mbed_ualloc_internal -> ualloc_debug -> printf -> | ||
| mbed_ualloc_internal -> ualloc_debug -> printf...) | ||
| 2. prevent a possible scenario when an interrupt occurs while ualloc_debug | ||
| is printing debug information and the interrupt also calls 'mbed_ualloc' or | ||
| another memory operation that would result in ualloc_debug being called, | ||
| which would in turn result in garbled output. By using "prevent_tracing", | ||
| the output is kept consistent, but the memory operation invoked in the | ||
| interrupt handler is not logged. | ||
|
|
||
| 1 above can be prevented by using a logging function that doesn't allocate memory. | ||
| 2 above can be prevented by queueing log messages instead of logging them immediately. | ||
| *****************************************************************************************/ | ||
| static volatile int prevent_tracing = 0; | ||
|
|
||
| #define ualloc_debug(ADBG_LEVEL, fmt, ...) do { \ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should be inside separate trace library, because for example it might be that sometimes user wan't to change endpoint where to print these debug messages (=traces), or change trace format easily without touching ualloc -library.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please file this as an issue against this repo. |
||
| if (ADBG_LEVEL <= ualloc_debug_level && ADBG_LEVEL < UALLOC_DEBUG_MAX) { \ | ||
| printf("UAL:%c " fmt, ua_chars[ADBG_LEVEL], __VA_ARGS__); \ | ||
|
|
@@ -52,10 +84,9 @@ const char ua_chars[] = "NFEWIL"; | |
| #define caller_addr() (NULL) | ||
| #endif | ||
|
|
||
| void * mbed_ualloc(size_t bytes, UAllocTraits_t traits) | ||
| static void * mbed_ualloc_internal(size_t bytes, UAllocTraits_t traits, void *caller) | ||
| { | ||
| void * ptr = NULL; | ||
| void * caller = (void*) caller_addr(); | ||
| if (UALLOC_TEST_TRAITS(traits.flags, UALLOC_TRAITS_NEVER_FREE)) { | ||
| ptr = mbed_krbs(bytes); | ||
| // krbs uses the same semantics as sbrk, so translate a -1 to NULL. | ||
|
|
@@ -76,47 +107,79 @@ void * mbed_ualloc(size_t bytes, UAllocTraits_t traits) | |
|
|
||
| if(ptr == NULL) { | ||
| ualloc_debug(UALLOC_DEBUG_WARNING, "ua c:%p fail\n", caller); | ||
| } else { | ||
| ualloc_debug(UALLOC_DEBUG_LOG, "ua c:%p m:%p\n", caller, ptr); | ||
| } | ||
|
|
||
| return ptr; | ||
| } | ||
| void * mbed_urealloc(void * ptr, size_t bytes, UAllocTraits_t traits) | ||
|
|
||
| void *mbed_ualloc(size_t bytes, UAllocTraits_t traits) | ||
| { | ||
| void *caller = (void*)caller_addr(); | ||
| void *p = mbed_ualloc_internal(bytes, traits, caller); | ||
| if (!prevent_tracing) { | ||
| prevent_tracing = 1; | ||
| ualloc_debug(UALLOC_DEBUG_LOG, "ua c:%p s:%u m:%p\n", caller, (unsigned)bytes, p); | ||
| prevent_tracing = 0; | ||
| } | ||
| return p; | ||
| } | ||
|
|
||
| static void * mbed_urealloc_internal(void * ptr, size_t bytes, UAllocTraits_t traits, void *caller) | ||
| { | ||
| void * caller = (void*) caller_addr(); | ||
| void *newptr = NULL; | ||
| if (ptr == NULL) { | ||
| return mbed_ualloc(bytes, traits); | ||
| } | ||
| if(traits.flags & ~UALLOC_TRAITS_BITMASK) { | ||
| // Traits not supported in urealloc yet | ||
| ualloc_debug(UALLOC_DEBUG_WARNING, "ua c:%p fail\n", caller); | ||
| ualloc_debug(UALLOC_DEBUG_ERROR, "ur c:%p fail\n", caller); | ||
| return NULL; | ||
| } | ||
| uintptr_t ptr_tmp = (uintptr_t) ptr; | ||
| if ((ptr_tmp < (uintptr_t) mbed_sbrk_ptr) && | ||
| (ptr_tmp >= (uintptr_t)&__mbed_sbrk_start)) { | ||
| newptr = dlrealloc(ptr, bytes); | ||
| } else { | ||
| ualloc_debug(UALLOC_DEBUG_LOG, "uf c:%p m:%p non-heap realloc\n", caller, ptr); | ||
| ualloc_debug(UALLOC_DEBUG_ERROR, "ur c:%p m:%p non-heap realloc\n", caller, ptr); | ||
| } | ||
|
|
||
| if(newptr == NULL) { | ||
| ualloc_debug(UALLOC_DEBUG_WARNING, "ur c:%p m0:%p fail\n", caller, ptr); | ||
| } else { | ||
| ualloc_debug(UALLOC_DEBUG_LOG, "ur c:%p m0:%p m1:%p\n", caller, ptr, newptr); | ||
| ualloc_debug(UALLOC_DEBUG_WARNING, "ur c:%p p:%p fail\n", caller, ptr); | ||
| } | ||
| return newptr; | ||
| } | ||
| void mbed_ufree(void * ptr) | ||
|
|
||
| void * mbed_urealloc(void * ptr, size_t bytes, UAllocTraits_t traits) | ||
| { | ||
| void *caller = (void*)caller_addr(); | ||
| void *p = mbed_urealloc_internal(ptr, bytes, traits, caller); | ||
| if (!prevent_tracing) { | ||
| prevent_tracing = 1; | ||
| ualloc_debug(UALLOC_DEBUG_LOG, "ur c:%p s:%u p:%p m:%p\n", caller, (unsigned)bytes, ptr, p); | ||
| prevent_tracing = 0; | ||
| } | ||
| return p; | ||
| } | ||
|
|
||
| static void mbed_ufree_internal(void * ptr, void *caller) | ||
| { | ||
| void * caller = (void*) caller_addr(); | ||
| ualloc_debug(UALLOC_DEBUG_LOG, "uf c:%p m:%p\n", caller, ptr); | ||
| uintptr_t ptr_tmp = (uintptr_t) ptr; | ||
| if ((ptr_tmp < (uintptr_t) mbed_sbrk_ptr) && | ||
| (ptr_tmp >= (uintptr_t)&__mbed_sbrk_start)) { | ||
| dlfree(ptr); | ||
| } else { | ||
| ualloc_debug(UALLOC_DEBUG_LOG, "uf c:%p m:%p non-heap free\n", caller, ptr); | ||
| ualloc_debug(UALLOC_DEBUG_WARNING, "uf c:%p m:%p non-heap free\n", caller, ptr); | ||
| } | ||
| } | ||
|
|
||
| void mbed_ufree(void *ptr) | ||
| { | ||
| void *caller = (void*)caller_addr(); | ||
| mbed_ufree_internal(ptr, caller); | ||
| if (!prevent_tracing) { | ||
| prevent_tracing = 1; | ||
| ualloc_debug(UALLOC_DEBUG_LOG, "uf c:%p m:%p\n", caller, ptr); | ||
| prevent_tracing = 0; | ||
| } | ||
| } | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be possible to have a re-entrant logging format (surround messages by matching brackets?), which would make this OK. This seems like a suitable solution for now though, especially as we don't malloc from interrupt handlers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I think this is already re-entrant, since it always starts with a known prefix that isn't repeated im the rest of the message. I can't remove
prevent_tracingyet tohugh, because of printf.