mbed.org local branch of microbit-dal. The real version lives in git at https://github.com/lancaster-university/microbit-dal

Dependencies:   BLE_API nRF51822 mbed-dev-bin

Dependents:   microbit Microbit IoTChallenge1 microbit ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MicroBitHeapAllocator.h Source File

MicroBitHeapAllocator.h

00001 /*
00002 The MIT License (MIT)
00003 
00004 Copyright (c) 2016 British Broadcasting Corporation.
00005 This software is provided by Lancaster University by arrangement with the BBC.
00006 
00007 Permission is hereby granted, free of charge, to any person obtaining a
00008 copy of this software and associated documentation files (the "Software"),
00009 to deal in the Software without restriction, including without limitation
00010 the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011 and/or sell copies of the Software, and to permit persons to whom the
00012 Software is furnished to do so, subject to the following conditions:
00013 
00014 The above copyright notice and this permission notice shall be included in
00015 all copies or substantial portions of the Software.
00016 
00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00020 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00022 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00023 DEALINGS IN THE SOFTWARE.
00024 */
00025 
00026 /**
00027   * A simple 32 bit block based memory allocator. This allows one or more memory segments to
00028   * be designated as heap storage, and is designed to run in a static memory area or inside the standard C
00029   * heap for use by the micro:bit runtime. This is required for several reasons:
00030   *
00031   * 1) It reduces memory fragmentation due to the high churn sometime placed on the heap
00032   * by ManagedTypes, fibers and user code. Underlying heap implentations are often have very simplistic
00033   * allocation pilicies and suffer from fragmentation in prolonged use - which can cause programs to
00034   * stop working after a period of time. The algorithm implemented here is simple, but highly tolerant to
00035   * large amounts of churn.
00036   *
00037   * 2) It allows us to reuse the 8K of SRAM set aside for SoftDevice as additional heap storage
00038   * when BLE is not in use.
00039   *
00040   * 3) It gives a simple example of how memory allocation works! :-)
00041   *
00042   * P.S. This is a very simple allocator, therefore not without its weaknesses. Why don't you consider
00043   * what these are, and consider the tradeoffs against simplicity...
00044   *
00045   * @note The need for this should be reviewed in the future, if a different memory allocator is
00046   * made availiable in the mbed platform.
00047   *
00048   * TODO: Consider caching recently freed blocks to improve allocation time.
00049   */
00050 
00051 #ifndef MICROBIT_HEAP_ALLOCTOR_H
00052 #define MICROBIT_HEAP_ALLOCTOR_H
00053 
00054 #include "mbed.h"
00055 #include "MicroBitConfig.h"
00056 #include <new>
00057 
00058 // The maximum number of heap segments that can be created.
00059 #define MICROBIT_MAXIMUM_HEAPS          2
00060 
00061 // Flag to indicate that a given block is FREE/USED
00062 #define MICROBIT_HEAP_BLOCK_FREE        0x80000000
00063 
00064 /**
00065   * Create and initialise a given memory region as for heap storage.
00066   * After this is called, any future calls to malloc, new, free or delete may use the new heap.
00067   * The heap allocator will attempt to allocate memory from heaps in the order that they are created.
00068   * i.e. memory will be allocated from first heap created until it is full, then the second heap, and so on.
00069   *
00070   * @param start The start address of memory to use as a heap region.
00071   *
00072   * @param end The end address of memory to use as a heap region.
00073   *
00074   * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if the heap could not be allocated.
00075   *
00076   * @note Only code that #includes MicroBitHeapAllocator.h will use this heap. This includes all micro:bit runtime
00077   * code, and user code targetting the runtime. External code can choose to include this file, or
00078   * simply use the standard heap.
00079   */
00080 int microbit_create_heap(uint32_t start, uint32_t end);
00081 
00082 /**
00083   * Create and initialise a heap region within the current the heap region specified
00084   * by the linker script.
00085   *
00086   * If the requested amount is not available, then the amount requested will be reduced
00087   * automatically to fit the space available.
00088   *
00089   * @param ratio The proportion of the underlying heap to allocate.
00090   *
00091   * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if the heap could not be allocated.
00092   */
00093 int microbit_create_nested_heap(float ratio);
00094 
00095 /**
00096   * Attempt to allocate a given amount of memory from any of our configured heap areas.
00097   *
00098   * @param size The amount of memory, in bytes, to allocate.
00099   *
00100   * @return A pointer to the allocated memory, or NULL if insufficient memory is available.
00101   */
00102 void *microbit_malloc(size_t size);
00103 
00104 
00105 /**
00106   * Release a given area of memory from the heap.
00107   *
00108   * @param mem The memory area to release.
00109   */
00110 void microbit_free(void *mem);
00111 
00112 /*
00113  * Wrapper function to ensure we have an explicit handle on the heap allocator provided
00114  * by our underlying platform.
00115  *
00116  * @param size The amount of memory, in bytes, to allocate.
00117  *
00118  * @return A pointer to the memory allocated. NULL if no memory is available.
00119  */
00120 inline void *native_malloc(size_t size)
00121 {
00122     return malloc(size);
00123 }
00124 
00125 /*
00126  * Wrapper function to ensure we have an explicit handle on the heap allocator provided
00127  * by our underlying platform.
00128  *
00129  * @param p Pointer to the memory to be freed.
00130  */
00131 inline void native_free(void *p)
00132 {
00133     free(p);
00134 }
00135 
00136 /**
00137   * Overrides the 'new' operator globally, and redirects calls to the micro:bit heap allocator.
00138   */
00139 inline void* operator new(size_t size) throw(std::bad_alloc)
00140 {
00141     return microbit_malloc(size);
00142 }
00143 
00144 /**
00145   * Overrides the 'new' operator globally, and redirects calls to the micro:bit theap allocator.
00146   */
00147 inline void* operator new[](size_t size) throw(std::bad_alloc)
00148 {
00149     return microbit_malloc(size);
00150 }
00151 
00152 /**
00153   * Overrides the 'delete' operator globally, and redirects calls to the micro:bit theap allocator.
00154   */
00155 inline void operator delete(void *ptr) throw()
00156 {
00157     microbit_free(ptr);
00158 }
00159 
00160 
00161 // Macros to override overrides the 'malloc' and 'delete' functions globally, and redirects calls
00162 // to the micro:bit theap allocator.
00163 
00164 #define malloc(X) microbit_malloc( X )
00165 #define free(X) microbit_free( X )
00166 
00167 #endif