Is it possible to use the new operator to allocate from a place other than a heap?

Here is the context of my application: I am working on an embedded system that uses RAM from different devices. One part of the internal memory of the microcontroller (128 KB), and the other part is external RAM (1 MB). These memories are mapped to the address space of the microcontroller, but in disjoint areas.

Internal memory is used for the system stack, task stacks, and heaps. External RAM is used for statically distributed data (pools, buffers, and all " static ... ")

I am trying to implement a simple memory management structure and, as part of it, be able to create a allocator that could use the operator new allocation algorithm, but using a different memory source, not a system heap, but a memory area in another place. Do you know if this is possible ?

An example of a use would be to reserve 100 KB of external RAM and create a allocator for its management, and then provide it with a given task that needs this memory.

 static const uint8_t* ramBase = reinterpret_cast<uint8_t*>(0x80000000); static const uint32_t ramAreaSize = 0x19000; //100kB BufferAllocator allocator(ramBase, ramAreaSize); //... //Assuming operator new is overloaded to use BufferAllocator MyObject * obj = new (allocator) MyObject(some, parameter); //... 

The question arises: how (if at all possible) is it possible to implement BufferAllocator to use operator new to control the area of โ€‹โ€‹raw memory?

 void* BufferAllocator::allocate(uint32_t bytes) { //I would like to write something like this //and so let the responsibility to manage this memory area to "new" //so I don't have to reimplement (or reuse) a different custom // allocator return ::operator new(ramBase, ramAreaSize, bytes) } 
+5
source share
2 answers

I ran into the same problem and the only solution I could find was to write my own malloc and free . I didn't need anything special, so I just modeled my code after it was shown in K & R's C programming language (they have a naive example, documented).

Then I created two heaps: one for internal memory and one for external memory. My stack is in a completely different memory block (CCRAM on STM32F4), so I don't need to worry about sbrk . However, I had to know the starting address of my internal SRAM heap based on data size and bss segments. This was determined from the extern characters entered by the script linker.

I have enough information about my heap to find out its current size, amount of free space, and whether there is enough continuous memory to complete the allocation. If this is not enough in the internal SRAM, it tries to use the external SRAM. If there is not enough memory, this is no different from the default malloc of memory.

I use the GNU toolchain, so I managed to use the -wrap option to override the default C library by default malloc , free , realloc and calloc (Actually malloc_r , free_r , realloc_r and calloc_r since I use newlib). Since new and delete are eventually called malloc and friends, I was able to get it to work (at least for my needs).

I'm not very sure about this, but this is the best I could do within the limits of my abilities. Examine with care.

I would be interested to know a simpler solution.

0
source

There is no standard way to provide the operator new or malloc() memory area. On POSIX-like systems, malloc() calls brk() , sbrk() and possibly mmap() to get this scope, so you can โ€œgrabโ€ these calls and provide your own implementation, but not portable (and the problem is for mmap() ).

Depending on your toolchain, you can โ€œexplainโ€ with your malloc() and / or operator new that it should process two or more separate memory areas, in some kind of script builder or some such thing. But there is no guarantee.

In addition, the only general solution I can think of is to use another shared memory manager (like jemalloc ) in your projects and find a way to configure it for your purpose.

0
source

Source: https://habr.com/ru/post/1216626/


All Articles