diff options
author | Henrik Rentz-Reichert | 2019-05-10 09:05:44 +0000 |
---|---|---|
committer | Gerrit Code Review @ Eclipse.org | 2019-05-10 09:05:44 +0000 |
commit | 877c88575ff8a7665aa78107a2b03d0ce0bbfb07 (patch) | |
tree | 0628b685ab1386a0d4b3eb251db1e1f47c6adaef /runtime/org.eclipse.etrice.runtime.c | |
parent | f7590cbfbde3879099cd9ee78efc5e0c8c24b7ad (diff) | |
parent | 0347fa1887a7042769517eb14b432637680f6b56 (diff) | |
download | org.eclipse.etrice-877c88575ff8a7665aa78107a2b03d0ce0bbfb07.tar.gz org.eclipse.etrice-877c88575ff8a7665aa78107a2b03d0ce0bbfb07.tar.xz org.eclipse.etrice-877c88575ff8a7665aa78107a2b03d0ce0bbfb07.zip |
Merge "Bug 546770 - improve and complete memory management"
Diffstat (limited to 'runtime/org.eclipse.etrice.runtime.c')
8 files changed, 465 insertions, 66 deletions
diff --git a/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory.h b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory.h index 2b960e259..13a9faee9 100644 --- a/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory.h +++ b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory.h @@ -38,12 +38,23 @@ typedef void* etMemory_alloc(struct etMemory* heap, etUInt16 size); * \param obj pointer to the memory returned * \param size the size in bytes of the memory returned */ -typedef void etMemory_free(struct etMemory* heap, void* obj, etUInt16 size); +typedef void etMemory_free(struct etMemory* heap, void* obj); + +typedef struct etMemoryStatistics { + const char* name; + etUInt32 maxUsed; + etUInt32 nFailingRequests; + struct etMemoryStatistics* next; +} +etMemoryStatistics; typedef struct etMemory { /** size of the heap in bytes */ etUInt32 size; + /** statistical data made available through the runtime */ + etMemoryStatistics statistics; + /** the configured allocation method */ etMemory_alloc* alloc; /** the configured freeing method */ diff --git a/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FixedSize.c b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FixedSize.c index bcd5f0501..99485173b 100644 --- a/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FixedSize.c +++ b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FixedSize.c @@ -16,13 +16,26 @@ #include "debugging/etMSCLogger.h" +#define DO_LOCK \ + if (self->lock!=NULL) { \ + self->lock->lockFct(self->lock->lockData); \ + } + +#define DO_UNLOCK \ + if (self->lock!=NULL) { \ + self->lock->unlockFct(self->lock->lockData); \ + } + +#define GET_USED (etQueue_getSize(&self->blockPool) * self->blockSize) + typedef struct etFixedSizeMemory { etMemory base; - etUInt8 *buffer; - etUInt16 maxBlocks; - etUInt16 blockSize; - etQueue blockPool; + etUInt8 *buffer; /**< the heap to be allocated from */ + etUInt16 maxBlocks; /**< the maximum number of blocks */ + etUInt16 blockSize; /**< block size */ + etQueue blockPool; /**< pool of free blocks */ + etLock* lock; /**< user supplied lock functions */ } etFixedSizeMemory; @@ -31,24 +44,36 @@ void* etMemory_FixedSize_alloc(etMemory* heap, etUInt16 size) { void* mem = NULL; size = MEM_CEIL(size); - ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "alloc") + ET_MSC_LOGGER_SYNC_ENTRY("etMemory_FixedSize", "alloc") + DO_LOCK if (size<=self->blockSize){ if (self->blockPool.size>0) { + etUInt32 used; mem = etQueue_pop(&self->blockPool); + used = GET_USED; + if (used > self->base.statistics.maxUsed) { + self->base.statistics.maxUsed = used; + } } } + if (mem==NULL) { + self->base.statistics.nFailingRequests++; + } + DO_UNLOCK ET_MSC_LOGGER_SYNC_EXIT return mem; } -void etMemory_FixedSize_free(etMemory* heap, void* obj, etUInt16 size) { +void etMemory_FixedSize_free(etMemory* heap, void* obj) { etFixedSizeMemory* self = (etFixedSizeMemory*) heap; - ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "free") + ET_MSC_LOGGER_SYNC_ENTRY("etMemory_FixedSize", "free") + DO_LOCK etQueue_push(&self->blockPool, obj); + DO_UNLOCK ET_MSC_LOGGER_SYNC_EXIT } @@ -61,9 +86,11 @@ etMemory* etMemory_FixedSize_init(void* heap, etUInt32 size, etUInt16 blockSize) size_t data_size = MEM_CEIL(sizeof(etFixedSizeMemory)); int i; - ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "init") + ET_MSC_LOGGER_SYNC_ENTRY("etMemory_FixedSize", "init") self->base.size = size; + self->base.statistics.maxUsed = 0; + self->base.statistics.nFailingRequests = 0; self->base.alloc = etMemory_FixedSize_alloc; self->base.free = etMemory_FixedSize_free; @@ -84,3 +111,23 @@ etMemory* etMemory_FixedSize_init(void* heap, etUInt32 size, etUInt16 blockSize) return &self->base; } + +void etMemory_FixedSize_setUserLock(etMemory* mem, etLock* lock) { + etFixedSizeMemory* self = (etFixedSizeMemory*) mem; + ET_MSC_LOGGER_SYNC_ENTRY("etMemory_FixedSize", "setUserLock") + self->lock = lock; + ET_MSC_LOGGER_SYNC_EXIT +} + +etUInt32 etMemory_FixedSize_getFreeHeapMem(etMemory* mem) { + etFixedSizeMemory* self = (etFixedSizeMemory*) mem; + etUInt32 result; + ET_MSC_LOGGER_SYNC_ENTRY("etMemory_FixedSize", "getFreeHeapMem") + + DO_LOCK + result = GET_USED; + DO_UNLOCK + + ET_MSC_LOGGER_SYNC_EXIT + return result; +} diff --git a/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FixedSize.h b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FixedSize.h index 855f3e53f..04558bf7a 100644 --- a/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FixedSize.h +++ b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FixedSize.h @@ -23,6 +23,7 @@ #include "base/etMemory.h" #include "base/etQueue.h" +#include "osal/etLock.h" /** * initializes the heap with a simple block management @@ -35,4 +36,20 @@ */ etMemory* etMemory_FixedSize_init(void* heap, etUInt32 size, etUInt16 blockSize); +/** + * supply optional user lock/unlock functions for usage in a multi-threaded environment. + * \param mem pointer to the memory management struct + * \lock pointer to a user supplied locking struct + */ +void etMemory_FixedSize_setUserLock(etMemory* mem, etLock* lock); + +/** + * determines and returns the free memory of the heap + * + * \param mem pointer to the heap to be managed + * + * \return the free memory of the heap + */ +etUInt32 etMemory_FixedSize_getFreeHeapMem(etMemory* mem); + #endif /* _ETMEMORY_FIXED_SIZE_H_ */ diff --git a/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FreeList.c b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FreeList.c index 09e2008ab..008acb047 100644 --- a/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FreeList.c +++ b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FreeList.c @@ -14,8 +14,19 @@ #include "debugging/etLogger.h" #include "debugging/etMSCLogger.h" -#define UNUSED_LIST 0 +#define UNUSED_LIST 0 #define DEBUG_FREE_LISTS 1 +#define OBJ_OFFSET etALIGNMENT + +#define DO_LOCK \ + if (self->lock!=NULL) { \ + self->lock->lockFct(self->lock->lockData); \ + } + +#define DO_UNLOCK \ + if (self->lock!=NULL) { \ + self->lock->unlockFct(self->lock->lockData); \ + } typedef struct etFreeListObj { struct etFreeListObj* next; @@ -35,30 +46,49 @@ typedef struct etFreeListMemory { etMemory base; /** the "base class" */ etUInt8* current; /**< next free position on the heap */ etUInt16 nslots; /**< number of free lists */ + etLock* lock; /**< user supplied lock functions */ + roundUpSize* roundUp; /**< rounding method (identity by default) */ etFreeListInfo freelists[1]; /**< array of free list infos (array used with size nslots) */ } etFreeListMemory; /* * private functions */ -static void* etMemory_getHeapMem(etFreeListMemory* self, etUInt16 size) { +static void* etMemory_FreeList_getHeapMem(etFreeListMemory* self, etUInt16 size) { etUInt8* obj = NULL; - ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "getHeapListMem") + ET_MSC_LOGGER_SYNC_ENTRY("etMemory_FreeList", "getHeapListMem") if (self->current + size < ((etUInt8*)self) + self->base.size) { - obj = self->current; + etUInt32 used; + + // store size in the first bytes + *((etUInt16*)self->current) = size; + + // object pointer at offset + obj = self->current + OBJ_OFFSET; + + // shift current self->current += size; + + used = ((etUInt8*)self) + self->base.size - self->current; + if (used > self->base.statistics.maxUsed) { + self->base.statistics.maxUsed = used; + } + } + + if (obj==NULL) { + self->base.statistics.nFailingRequests++; } ET_MSC_LOGGER_SYNC_EXIT return obj; } -static void* etMemory_getFreeListMem(etFreeListMemory* self, etUInt16 size) { +static void* etMemory_FreeList_getFreeListMem(etFreeListMemory* self, etUInt16 size) { etUInt8* mem = NULL; int asize, slot_offset, slot, slot_size; - ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "getFreeListMem") + ET_MSC_LOGGER_SYNC_ENTRY("etMemory_FreeList", "getFreeListMem") asize = (size / etALIGNMENT); for (slot_offset = 0; slot_offset < self->nslots; slot_offset++) { @@ -82,10 +112,11 @@ static void* etMemory_getFreeListMem(etFreeListMemory* self, etUInt16 size) { return mem; } -static void etMemory_putFreeListMem(etFreeListMemory* self, void* obj, etUInt16 size) { - ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "putFreeListMem") +static void etMemory_FreeList_putFreeListMem(etFreeListMemory* self, void* obj) { + ET_MSC_LOGGER_SYNC_ENTRY("etMemory_FreeList", "putFreeListMem") { int asize, slot_offset, slot, slot_size; + etUInt16 size = *((etUInt16*) (((etUInt8*) obj) - OBJ_OFFSET)); asize = (size / etALIGNMENT); for (slot_offset = 0; slot_offset < self->nslots; slot_offset++) { @@ -115,84 +146,149 @@ static void etMemory_putFreeListMem(etFreeListMemory* self, void* obj, etUInt16 ET_MSC_LOGGER_SYNC_EXIT } -void* etMemory_FreeList_alloc(etMemory* heap, etUInt16 size) { +static void* etMemory_FreeList_alloc(etMemory* heap, etUInt16 size) { + etFreeListMemory* self = (etFreeListMemory*) heap; void* mem; - size = MEM_CEIL(size); - ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "alloc") - mem = etMemory_getFreeListMem((etFreeListMemory*) heap, size); - if (mem==NULL) - mem = etMemory_getHeapMem((etFreeListMemory*) heap, size); + ET_MSC_LOGGER_SYNC_ENTRY("etMemory_FreeList", "alloc") + + // rounded required size + space to store the size + size = MEM_CEIL(self->roundUp(size) + OBJ_OFFSET); + + DO_LOCK + mem = etMemory_FreeList_getFreeListMem((etFreeListMemory*) heap, size); + if (mem==NULL) { + mem = etMemory_FreeList_getHeapMem((etFreeListMemory*) heap, size); + } + DO_UNLOCK ET_MSC_LOGGER_SYNC_EXIT return mem; } -void etMemory_FreeList_free(etMemory* heap, void* obj, etUInt16 size) { - ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "free") - { - size = MEM_CEIL(size); - etMemory_putFreeListMem((etFreeListMemory*) heap, obj, size); - } +static void etMemory_FreeList_free(etMemory* heap, void* obj) { + etFreeListMemory* self = (etFreeListMemory*) heap; + ET_MSC_LOGGER_SYNC_ENTRY("etMemory_FreeList", "free") + + DO_LOCK + etMemory_FreeList_putFreeListMem(self, obj); + DO_UNLOCK + ET_MSC_LOGGER_SYNC_EXIT } +static etUInt16 etMemory_FreeList_identity(etUInt16 size) { + return size; +} + +etUInt16 etMemory_FreeList_power2(etUInt16 v) { + /* https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 */ + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v++; + return v; +} + + /* * the public interface */ etMemory* etMemory_FreeList_init(void* heap, etUInt32 size, etUInt16 nslots) { etFreeListMemory* self = (etFreeListMemory*) heap; ET_MSC_LOGGER_SYNC_ENTRY("etMemory_FreeList_init", "init") + int data_size = MEM_CEIL(sizeof(etFreeListMemory)+(nslots-1)*sizeof(etFreeListInfo)); + etMemory* result = NULL; - self->base.size = size; - self->base.alloc = etMemory_FreeList_alloc; - self->base.free = etMemory_FreeList_free; - self->nslots = nslots; - { - int used = sizeof(etFreeListMemory)+(self->nslots-1)*sizeof(etFreeListInfo); - self->current = ((etUInt8*)self)+MEM_CEIL(used); - } + if (size > data_size) { + self->base.size = size; + self->base.statistics.maxUsed = 0; + self->base.statistics.nFailingRequests = 0; + self->base.alloc = etMemory_FreeList_alloc; + self->base.free = etMemory_FreeList_free; + self->roundUp = etMemory_FreeList_identity; + self->lock = NULL; + self->nslots = nslots; + self->current = ((etUInt8*) self) + data_size; - /* initialize the free lists */ - { - int i; - for (i=0; i<self->nslots; ++i) - self->freelists[i].objsize = UNUSED_LIST; + /* initialize the free lists */ + { + int i; + for (i=0; i<self->nslots; ++i) + self->freelists[i].objsize = UNUSED_LIST; + } + + result = &self->base; } + ET_MSC_LOGGER_SYNC_EXIT + return result; +} - return &self->base; +void etMemory_FreeList_setUserLock(etMemory* mem, etLock* lock) { + etFreeListMemory* self = (etFreeListMemory*) mem; + ET_MSC_LOGGER_SYNC_ENTRY("etMemory_FreeList_init", "setUserLock") + self->lock = lock; + ET_MSC_LOGGER_SYNC_EXIT } -etUInt32 etMemory_FreeList_freeHeapMem(void* heap) { - etFreeListMemory* self = (etFreeListMemory*) heap; - return ((etUInt8*)self)+self->base.size - self->current; +void etMemory_FreeList_setUserRounding(etMemory* mem, roundUpSize* roundup) { + etFreeListMemory* self = (etFreeListMemory*) mem; + ET_MSC_LOGGER_SYNC_ENTRY("etMemory_FreeList_init", "setUserRounding") + self->roundUp = roundup; + ET_MSC_LOGGER_SYNC_EXIT } -etUInt16 etMemory_FreeList_freeSlots(void* heap) { - etFreeListMemory* self = (etFreeListMemory*) heap; +etUInt32 etMemory_FreeList_getFreeHeapMem(etMemory* mem) { + etFreeListMemory* self = (etFreeListMemory*) mem; + + DO_LOCK + etUInt32 result = ((etUInt8*) self) + self->base.size - self->current; + DO_UNLOCK + + return result; +} + +etUInt16 etMemory_FreeList_freeSlots(etMemory* mem) { + etFreeListMemory* self = (etFreeListMemory*) mem; etUInt16 free = 0; int slot; + DO_LOCK for (slot=0; slot<self->nslots; ++slot) if (self->freelists[slot].objsize==UNUSED_LIST) ++free; + DO_UNLOCK return free; } -etUInt16 etMemory_FreeList_nObjects(void* heap, etUInt16 slot) { +etUInt16 etMemory_FreeList_nObjects(etMemory* mem, etUInt16 slot) { + etUInt16 result = 0; #if DEBUG_FREE_LISTS - etFreeListMemory* self = (etFreeListMemory*) heap; - if (slot<self->nslots) - return self->freelists[slot].nobjects; + etFreeListMemory* self = (etFreeListMemory*) mem; + DO_LOCK + if (slot<self->nslots) { + result = self->freelists[slot].nobjects; + } + DO_UNLOCK #endif - return 0; + return result; } -etUInt16 etMemory_FreeList_sizeObjects(void* heap, etUInt16 slot) { - etFreeListMemory* self = (etFreeListMemory*) heap; - if (slot<self->nslots) - return self->freelists[slot].objsize; - return 0; +etUInt16 etMemory_FreeList_sizeObjects(etMemory* mem, etUInt16 slot) { + etFreeListMemory* self = (etFreeListMemory*) mem; + etUInt16 result = 0; + DO_LOCK + if (slot<self->nslots) { + result = self->freelists[slot].objsize - OBJ_OFFSET; + } + DO_UNLOCK + return result; +} + +etUInt16 etMemory_FreeList_MgmtDataPerObject() { + return OBJ_OFFSET; } diff --git a/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FreeList.h b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FreeList.h index ff2806593..25cac9926 100644 --- a/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FreeList.h +++ b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FreeList.h @@ -21,6 +21,14 @@ * \author Henrik Rentz-Reichert */ #include "base/etMemory.h" +#include "osal/etLock.h" + +typedef etUInt16 roundUpSize(etUInt16 size); + +/** + * this function rounds up to the next highest power of 2 + */ +etUInt16 etMemory_FreeList_power2(etUInt16 v); /** * initializes the free list memory management on the given heap @@ -34,42 +42,63 @@ etMemory* etMemory_FreeList_init(void* heap, etUInt32 size, etUInt16 nslots); /** + * supply optional user lock/unlock functions for usage in a multi-threaded environment. + * \param mem pointer to the memory management struct + * \lock pointer to a user supplied locking struct + */ +void etMemory_FreeList_setUserLock(etMemory* mem, etLock* lock); + +/** + * by default the requested size is just rounded up to the next alignment boundary. + * In this case for every new size a slot is used. To use less slots at the cost of some 'wasted' memory + * the user can supply an optional round-up method to create less equivalence classes of object sized + * and thus reduce the number of slots needed. + * An alternative is to use etMemory_FreeList_power2(). + */ +void etMemory_FreeList_setUserRounding(etMemory* mem, roundUpSize* roundup); + +/** * determines and returns the free memory of the heap * - * \param heap pointer to the heap to be managed + * \param mem pointer to the heap to be managed * * \return the free memory of the heap */ -etUInt32 etMemory_FreeList_freeHeapMem(void* heap); +etUInt32 etMemory_FreeList_getFreeHeapMem(etMemory* mem); /** * returns the number of objects in a given slot * - * \param heap pointer to the heap to be managed + * \param mem pointer to the heap to be managed * \param slot the slot number * * \return the number of objects in a given slot or <code>0</code> if invalid slot * or <code>DEBUG_FREE_LISTS</code> isn't <code>true</code> */ -etUInt16 etMemory_FreeList_nObjects(void* heap, etUInt16 slot); +etUInt16 etMemory_FreeList_nObjects(etMemory* mem, etUInt16 slot); /** * returns the size of the objects in a given slot * - * \param heap pointer to the heap to be managed + * \param mem pointer to the heap to be managed * \param slot the slot number * * \return the size of the objects in a given slot */ -etUInt16 etMemory_FreeList_sizeObjects(void* heap, etUInt16 slot); +etUInt16 etMemory_FreeList_sizeObjects(etMemory* mem, etUInt16 slot); /** * returns the number of free slots * - * \param heap pointer to the heap to be managed + * \param mem pointer to the heap to be managed * * \return the number of free slots */ -etUInt16 etMemory_FreeList_freeSlots(void* heap); +etUInt16 etMemory_FreeList_freeSlots(etMemory* mem); + +/** + * the size of the management data per allocated object + */ +etUInt16 etMemory_FreeList_MgmtDataPerObject(); #endif /* _ETMEMORY_FREE_LIST_H_ */ diff --git a/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_VariableSize.c b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_VariableSize.c new file mode 100644 index 000000000..dc0efad8d --- /dev/null +++ b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_VariableSize.c @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2012 protos software gmbh (http://www.protos.de). + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * CONTRIBUTORS: + * Henrik Rentz-Reichert (initial contribution) + * + *******************************************************************************/ + +#include "base/etMemory_VariableSize.h" +#include "base/etQueue.h" +#include "debugging/etLogger.h" +#include "debugging/etMSCLogger.h" + + +#define DO_LOCK \ + if (self->lock!=NULL) { \ + self->lock->lockFct(self->lock->lockData); \ + } + +#define DO_UNLOCK \ + if (self->lock!=NULL) { \ + self->lock->unlockFct(self->lock->lockData); \ + } + +typedef struct etVariableSizeMemory { + etMemory base; /** the "base class" */ + + etUInt8* current; /**< next free position on the heap */ + etLock* lock; /**< user supplied lock functions */ +} etVariableSizeMemory; + + +void* etMemory_VariableSize_alloc(etMemory* heap, etUInt16 size) { + etVariableSizeMemory* self = (etVariableSizeMemory*) heap; + void* mem = NULL; + size = MEM_CEIL(size); + + DO_LOCK + if (self->current + size < ((etUInt8*)self) + self->base.size) { + etUInt32 used; + + mem = (void*) self->current; + self->current += size; + + used = ((etUInt8*)self) + self->base.size - self->current; + if (used > self->base.statistics.maxUsed) { + self->base.statistics.maxUsed = used; + } + } + if (mem==NULL) { + self->base.statistics.nFailingRequests++; + } + DO_UNLOCK + + ET_MSC_LOGGER_SYNC_EXIT + return mem; +} + +void etMemory_VariableSize_free(etMemory* heap, void* obj) { + ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "free") + /* do nothing */ + ET_MSC_LOGGER_SYNC_EXIT +} + +/* + * the public interface + */ +etMemory* etMemory_VariableSize_init(void* heap, etUInt32 size) { + etVariableSizeMemory* self = (etVariableSizeMemory*) heap; + size_t data_size = MEM_CEIL(sizeof(etVariableSizeMemory)); + etMemory* result = NULL; + + ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "init") + + if (size > data_size) { + self->base.size = size; + self->base.statistics.maxUsed = 0; + self->base.statistics.nFailingRequests = 0; + self->base.alloc = etMemory_VariableSize_alloc; + self->base.free = etMemory_VariableSize_free; + + self->current = ((etUInt8*)self)+data_size; + result = &self->base; + } + + ET_MSC_LOGGER_SYNC_EXIT + return result; +} + +etUInt8 etMemory_VariableSize_freeHeapMem(etMemory* mem) { + etVariableSizeMemory* self = (etVariableSizeMemory*) mem; + return ((etUInt8*) self) + self->base.size - self->current; +} + +void etMemory_VariableSize_setUserLock(etMemory* mem, etLock* lock) { + etVariableSizeMemory* self = (etVariableSizeMemory*) mem; + ET_MSC_LOGGER_SYNC_ENTRY("etMemory_VariableSize", "setUserLock") + self->lock = lock; + ET_MSC_LOGGER_SYNC_EXIT +} diff --git a/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_VariableSize.h b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_VariableSize.h new file mode 100644 index 000000000..76e9d6a3c --- /dev/null +++ b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_VariableSize.h @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2019 protos software gmbh (http://www.protos.de). + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * CONTRIBUTORS: + * Henrik Rentz-Reichert (initial contribution) + * + *******************************************************************************/ + +/** + * \file etMemory_VariableSize.h + * + * a simple memory management that uses equal sized chunks. The free chunks are maintained in + * a \ref etQueue + * + * \author Henrik Rentz-Reichert + */ +#ifndef _ETMEMORY_VARIABLE_SIZE_H_ +#define _ETMEMORY_VARIABLE_SIZE_H_ + +#include "base/etMemory.h" +#include "base/etQueue.h" +#include "osal/etLock.h" + +/** + * initializes the heap with a simple block management + * + * \param heap pointer to the heap to be managed + * \param size the size in bytes of the heap + * \param blockSize the size of the (equal sized) blocks + * + * \return the pointer to the initialized etMemory struct + */ +etMemory* etMemory_VariableSize_init(void* heap, etUInt32 size); + +/** + * supply optional user lock/unlock functions for usage in a multi-threaded environment. + * \param mem pointer to the memory management struct + * \lock pointer to a user supplied locking struct + */ +void etMemory_VariableSize_setUserLock(etMemory* mem, etLock* lock); + +/** + * returns the free memory left in bytes + * \return the free memory left in bytes + */ +etUInt8 etMemory_VariableSize_freeHeapMem(etMemory* mem); + + +#endif /* _ETMEMORY_VARIABLE_SIZE_H_ */ diff --git a/runtime/org.eclipse.etrice.runtime.c/src/common/osal/etLock.h b/runtime/org.eclipse.etrice.runtime.c/src/common/osal/etLock.h new file mode 100644 index 000000000..98849f0fa --- /dev/null +++ b/runtime/org.eclipse.etrice.runtime.c/src/common/osal/etLock.h @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2013 protos software gmbh (http://www.protos.de). + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * CONTRIBUTORS: + * Henrik Rentz-Reichert (initial contribution) + * + * + *******************************************************************************/ + +/** + * \file etMutex.h + * + * etMutex.h defines a generic interface for platform specific implementations of a mutex + * + * \author Henrik Rentz-Reichert + */ +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ETLOCK_H_ +#define _ETLOCK_H_ + +typedef void etLock_lock(void* lockData); +typedef void etLock_unlock(void* lockData); + +typedef struct etLock { + etLock_lock* lockFct; + etLock_unlock* unlockFct; + void* lockData; +} +etLock; + +#endif /* _ETLOCK_H_ */ + +#ifdef __cplusplus +} +#endif |