I got more involved into interrupts and multi core programming and began wondering about safe memory management especially when multiple parts of a program attempt to access or modify the same memory at the same time.
What happens if the main program is currently allocating memory in heap and an ISR is suddenly called that also attempts to allocate some other memory into heap. Is there some underlying safe mechanisms built in to make sure the same memory isn't allocated twice? Or are we simply supposed to avoid the use of new/malloc(), delete/free() in all ISR's?
Same question applies to dual core processing on the ESP32 for example. What happens if both cores attempt to allocate/deallocate memory at the same time (assuming its a shared heap)
The question came up for stack memory also. I assume ISR and the main program use the same stack memory and in turn, the same stack pointer. Since on the atmega328p the pointer is two bytes long, it will take a minimum of two clock cycles to modify fully. What happens if an ISR is called in the middle of modifying the stack pointer? ISR's also need stack memory to accomplish their task which(im assuming) also needs the same stack pointer.
I know im still very inexperienced in this field as I am trying my best to grasp these concepts.
Any help will be greatly appreciated!
It is programmer responsibility to make memory allocation safe. If the ISR is allocating memory then you have to turn interrupts off in the main program during the allocation procedure.
Good that you realize this. It is an extremely important and complex subject in multitasking systems, with entire books devoted to the subject (intensely studied since the 1970s).
It's pretty common for malloc/free to be prohibited (by "policy") in ISRs.
(Leading to interesting workarounds, usually involving pre-allocated chunks of memory on some sort of queue.)
oof, so basically creating your own method of memory allocation with a pre-allocated memory pool.
What about dual core processing? I not sure how I can avoid that problem. Unless if one core is basically prohibited from using dynamic memory.
The prohibited core can request the first core to allocate some memory for it. Or have some semaphore to make sure only one core uses it at a time
Are there any good book recommendations I could read into?
I am not familiar with ESP32. Anyway, you can restrict allocation to use specific memory region and also operating systems in general are used on multiprocessor HW and C libraries are capable to deal with it like glibc does.
Heap functions are thread-safe, meaning they can be called from different tasks simultaneously without any limitations.
It is technically possible to call malloc, free, and related functions from interrupt handler (ISR) context (see Calling Heap-Related Functions from ISR). However, this is not recommended, as heap function calls may delay other interrupts. It is strongly recommended to refactor applications so that any buffers used by an ISR are pre-allocated outside of the ISR. Support for calling heap functions from ISRs may be removed in a future update.
If it's really necessary to access shared memory (or any resource) from both cores and in both ISR and non-ISR code, then you'll need to use ESP32 Critical Sections. Note that requesting to enter a Critical Section from an ISR will lock the entire core until the spinlock is acquired.