diff options
author | Henrik Rentz-Reichert | 2019-05-10 14:21:10 +0000 |
---|---|---|
committer | Henrik Rentz-Reichert | 2019-05-15 17:30:58 +0000 |
commit | 5f88a96768e4e8d6336ad5d329d2049bce644b04 (patch) | |
tree | cec0bb1753979340c3b54607936bd6628d027749 /runtime/org.eclipse.etrice.runtime.c | |
parent | 877c88575ff8a7665aa78107a2b03d0ce0bbfb07 (diff) | |
download | org.eclipse.etrice-5f88a96768e4e8d6336ad5d329d2049bce644b04.tar.gz org.eclipse.etrice-5f88a96768e4e8d6336ad5d329d2049bce644b04.tar.xz org.eclipse.etrice-5f88a96768e4e8d6336ad5d329d2049bce644b04.zip |
Bug 546770 - improve and complete memory management
* memory managements hooked into runtime for access to statistics
* improved structure and code
Change-Id: Id2c0d7d4c77bf5de0753a155d0155738a3195bfe
Diffstat (limited to 'runtime/org.eclipse.etrice.runtime.c')
10 files changed, 459 insertions, 141 deletions
diff --git a/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory.c b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory.c new file mode 100644 index 000000000..53ce6636e --- /dev/null +++ b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory.c @@ -0,0 +1,61 @@ +/******************************************************************************* + * 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) + * + *******************************************************************************/ + +#include "base/etMemory.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); \ + } + +void etMemory_init(etMemory* self, etUInt32 size, etMemory_alloc* alloc, etMemory_free* free) { + ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "init") + + self->name = NULL; + self->size = size; + self->lock = NULL; + self->alloc = alloc; + self->free = free; + self->statistics.maxUsed = 0; + self->statistics.nFailingRequests = 0; + + etRuntime_registerMemoryManagement(self); + ET_MSC_LOGGER_SYNC_EXIT +} + +void etMemory_setUserLock(etMemory* self, etLock* lock) { + ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "setUserLock") + self->lock = lock; + ET_MSC_LOGGER_SYNC_EXIT +} + +void etMemory_resetStatistics(struct etMemory* self) { + ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "resetStatistics") + DO_LOCK + self->statistics.maxUsed = 0; + self->statistics.nFailingRequests = 0; + DO_UNLOCK + ET_MSC_LOGGER_SYNC_EXIT +} + +void etMemory_destroy(etMemory* self) { + ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "destroy") + etRuntime_unregisterMemoryManagement(self); + ET_MSC_LOGGER_SYNC_EXIT +} 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 13a9faee9..6d937b5e1 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 @@ -14,6 +14,7 @@ #define _ETMEMORY_H_ #include "etDatatypes.h" +#include "osal/etLock.h" /** * this macro computes the memory aligned value for a given size. It uses the ALIGNMENT @@ -26,29 +27,33 @@ struct etMemory; /** * allocates memory from the heap * - * \param heap pointer to the heap memory + * \param heap pointer to the memory management * \param size the size of the requested memory in bytes */ -typedef void* etMemory_alloc(struct etMemory* heap, etUInt16 size); +typedef void* etMemory_alloc(struct etMemory* mem, etUInt16 size); /** * frees memory previously allocated from the heap * - * \param heap pointer to the heap memory + * \param heap pointer to the memory management * \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); +typedef void etMemory_free(struct etMemory* mem, void* obj); typedef struct etMemoryStatistics { - const char* name; etUInt32 maxUsed; etUInt32 nFailingRequests; - struct etMemoryStatistics* next; } etMemoryStatistics; typedef struct etMemory { + /** name */ + const char* name; + + /** linked list */ + struct etMemory* next; + /** size of the heap in bytes */ etUInt32 size; @@ -59,6 +64,42 @@ typedef struct etMemory { etMemory_alloc* alloc; /** the configured freeing method */ etMemory_free* free; + + /** user supplied lock functions */ + etLock* lock; } etMemory; + +/** + * initializes the struct + * + * \param mem pointer to the heap to be managed + * \param size the size in bytes of the heap + * \param alloc the allocation function + * \param free the free function + * + * \return the pointer to the initialized etMemory struct + */ +void etMemory_init(etMemory* mem, etUInt32 size, etMemory_alloc* alloc, etMemory_free* free); + +/** + * resets the statistical data to their initial values + * + * \param heap pointer to the memory management + */ +void etMemory_resetStatistics(etMemory* mem); + +/** + * 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_setUserLock(etMemory* mem, etLock* lock); + +/** + * destroys the memory management and unregisters it from the runtime + * \param mem pointer to the memory management struct + */ +void etMemory_destroy(etMemory* mem); + #endif /* _ETMEMORY_H_ */ 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 99485173b..cd4bae31b 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 @@ -17,16 +17,16 @@ #define DO_LOCK \ - if (self->lock!=NULL) { \ - self->lock->lockFct(self->lock->lockData); \ + if (self->base.lock!=NULL) { \ + self->base.lock->lockFct(self->base.lock->lockData); \ } #define DO_UNLOCK \ - if (self->lock!=NULL) { \ - self->lock->unlockFct(self->lock->lockData); \ + if (self->base.lock!=NULL) { \ + self->base.lock->unlockFct(self->base.lock->lockData); \ } -#define GET_USED (etQueue_getSize(&self->blockPool) * self->blockSize) +#define GET_FREE (etQueue_getSize(&self->blockPool) * self->blockSize) typedef struct etFixedSizeMemory { etMemory base; @@ -35,7 +35,6 @@ typedef struct etFixedSizeMemory { etUInt16 maxBlocks; /**< the maximum number of blocks */ etUInt16 blockSize; /**< block size */ etQueue blockPool; /**< pool of free blocks */ - etLock* lock; /**< user supplied lock functions */ } etFixedSizeMemory; @@ -51,7 +50,7 @@ void* etMemory_FixedSize_alloc(etMemory* heap, etUInt16 size) { if (self->blockPool.size>0) { etUInt32 used; mem = etQueue_pop(&self->blockPool); - used = GET_USED; + used = self->base.size - GET_FREE; if (used > self->base.statistics.maxUsed) { self->base.statistics.maxUsed = used; } @@ -83,40 +82,31 @@ void etMemory_FixedSize_free(etMemory* heap, void* obj) { */ etMemory* etMemory_FixedSize_init(void* heap, etUInt32 size, etUInt16 blockSize) { etFixedSizeMemory* self = (etFixedSizeMemory*) heap; - size_t data_size = MEM_CEIL(sizeof(etFixedSizeMemory)); + etUInt32 data_size = MEM_CEIL(sizeof(etFixedSizeMemory)); + etUInt32 actual_size = size - data_size; + etMemory* result = NULL; int i; 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; + if (heap!=NULL && size > data_size) { + result = &self->base; + + etMemory_init(result, actual_size, etMemory_FixedSize_alloc, etMemory_FixedSize_free); - if (size > data_size) { self->buffer = ((etUInt8*) self) + data_size; self->blockSize = blockSize; self->maxBlocks = (size - data_size) / self->blockSize; + etQueue_init(&self->blockPool); for (i=0; i<self->maxBlocks; i++){ void* block = &(self->buffer[i*self->blockSize]); etQueue_push(&self->blockPool, block); } } - else { - self->blockSize = 0; - } ET_MSC_LOGGER_SYNC_EXIT - 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 + return result; } etUInt32 etMemory_FixedSize_getFreeHeapMem(etMemory* mem) { @@ -125,7 +115,7 @@ etUInt32 etMemory_FixedSize_getFreeHeapMem(etMemory* mem) { ET_MSC_LOGGER_SYNC_ENTRY("etMemory_FixedSize", "getFreeHeapMem") DO_LOCK - result = GET_USED; + result = GET_FREE; DO_UNLOCK ET_MSC_LOGGER_SYNC_EXIT 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 04558bf7a..6638b9417 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,7 +23,6 @@ #include "base/etMemory.h" #include "base/etQueue.h" -#include "osal/etLock.h" /** * initializes the heap with a simple block management @@ -37,13 +36,6 @@ 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 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 008acb047..724059bac 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 @@ -19,13 +19,13 @@ #define OBJ_OFFSET etALIGNMENT #define DO_LOCK \ - if (self->lock!=NULL) { \ - self->lock->lockFct(self->lock->lockData); \ + if (self->base.lock!=NULL) { \ + self->base.lock->lockFct(self->base.lock->lockData); \ } #define DO_UNLOCK \ - if (self->lock!=NULL) { \ - self->lock->unlockFct(self->lock->lockData); \ + if (self->base.lock!=NULL) { \ + self->base.lock->unlockFct(self->base.lock->lockData); \ } typedef struct etFreeListObj { @@ -46,7 +46,6 @@ 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; @@ -199,17 +198,16 @@ etUInt16 etMemory_FreeList_power2(etUInt16 v) { 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)); + etUInt32 data_size = MEM_CEIL(sizeof(etFreeListMemory)+(nslots-1)*sizeof(etFreeListInfo)); + etUInt32 actual_size = size - data_size; etMemory* result = NULL; - 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; + if (heap!=NULL & size > data_size) { + result = &self->base; + + etMemory_init(result, actual_size, etMemory_FreeList_alloc, etMemory_FreeList_free); + self->roundUp = etMemory_FreeList_identity; - self->lock = NULL; self->nslots = nslots; self->current = ((etUInt8*) self) + data_size; @@ -219,21 +217,12 @@ etMemory* etMemory_FreeList_init(void* heap, etUInt32 size, etUInt16 nslots) { for (i=0; i<self->nslots; ++i) self->freelists[i].objsize = UNUSED_LIST; } - - result = &self->base; } ET_MSC_LOGGER_SYNC_EXIT return result; } -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 -} - void etMemory_FreeList_setUserRounding(etMemory* mem, roundUpSize* roundup) { etFreeListMemory* self = (etFreeListMemory*) mem; ET_MSC_LOGGER_SYNC_ENTRY("etMemory_FreeList_init", "setUserRounding") 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 25cac9926..874416467 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 @@ -42,13 +42,6 @@ etUInt16 etMemory_FreeList_power2(etUInt16 v); 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 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 index dc0efad8d..dba017d79 100644 --- 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 @@ -17,20 +17,19 @@ #define DO_LOCK \ - if (self->lock!=NULL) { \ - self->lock->lockFct(self->lock->lockData); \ + if (self->base.lock!=NULL) { \ + self->base.lock->lockFct(self->base.lock->lockData); \ } #define DO_UNLOCK \ - if (self->lock!=NULL) { \ - self->lock->unlockFct(self->lock->lockData); \ + if (self->base.lock!=NULL) { \ + self->base.lock->unlockFct(self->base.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; @@ -71,20 +70,18 @@ void etMemory_VariableSize_free(etMemory* heap, void* obj) { */ etMemory* etMemory_VariableSize_init(void* heap, etUInt32 size) { etVariableSizeMemory* self = (etVariableSizeMemory*) heap; - size_t data_size = MEM_CEIL(sizeof(etVariableSizeMemory)); + etUInt32 data_size = MEM_CEIL(sizeof(etVariableSizeMemory)); + etUInt32 actual_size = size - data_size; 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; + if (heap!=NULL & size > data_size) { + result = &self->base; + + etMemory_init(result, actual_size, etMemory_VariableSize_alloc, etMemory_VariableSize_free); self->current = ((etUInt8*)self)+data_size; - result = &self->base; } ET_MSC_LOGGER_SYNC_EXIT @@ -95,10 +92,3 @@ 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 index 76e9d6a3c..dd5d8e030 100644 --- 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 @@ -37,13 +37,6 @@ 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 */ diff --git a/runtime/org.eclipse.etrice.runtime.c/src/common/runtime/etRuntime.c b/runtime/org.eclipse.etrice.runtime.c/src/common/runtime/etRuntime.c index 4bc54e6e8..7b1ac14fe 100644 --- a/runtime/org.eclipse.etrice.runtime.c/src/common/runtime/etRuntime.c +++ b/runtime/org.eclipse.etrice.runtime.c/src/common/runtime/etRuntime.c @@ -12,99 +12,309 @@ #include "runtime/etRuntime.h" +#include "debugging/etMSCLogger.h" static etSema terminateSemaphore; -static etMessageService* head = NULL; +static etMessageService* etRuntime_msgsvc_head; +static etMemory* etRuntime_memmgmt_head; etSema* etRuntime_getTerminateSemaphore() { static etBool initialized = ET_FALSE; + ET_MSC_LOGGER_SYNC_ENTRY("etRuntime", "getTerminateSemaphore") if (!initialized) { initialized = ET_TRUE; etSema_construct(&terminateSemaphore); } + ET_MSC_LOGGER_SYNC_EXIT return &terminateSemaphore; } -int etRuntime_getMessageServiceCount() { - etMessageService* p = head; +static void etRuntime_initInternal() { + // global variables might not be initialized before a function call - so we use this trick + static etBool initialized = ET_FALSE; + + if (!initialized) { + initialized = ET_TRUE; + etRuntime_msgsvc_head = NULL; + etRuntime_memmgmt_head = NULL; + } + +} +int etRuntime_getMessageServiceCount() { int count = 0; - while (p!=null) { - ++count; - p = p->next; + ET_MSC_LOGGER_SYNC_ENTRY("etRuntime", "getMessageServiceCount") + etRuntime_initInternal(); + { + etMessageService* p = etRuntime_msgsvc_head; + while (p!=null) { + ++count; + p = p->next; + } } + + ET_MSC_LOGGER_SYNC_EXIT return count; } int etRuntime_getMessageServiceByName(const char* name) { - etMessageService* p = head; + etRuntime_initInternal(); + ET_MSC_LOGGER_SYNC_ENTRY("etRuntime", "getMessageServiceByName") - int idx = 0; - while (p!=null) { - if (strcmp(p->name, name)==0) { - return idx; + { + etMessageService* p = etRuntime_msgsvc_head; + int idx = 0; + while (p!=null) { + if (strcmp(p->name, name)==0) { + ET_MSC_LOGGER_SYNC_EXIT + return idx; + } + ++idx; + p = p->next; } - ++idx; - p = p->next; } + ET_MSC_LOGGER_SYNC_EXIT return -1; } const etMessageServiceStatistics* etRuntime_getMessageServiceStatistics(unsigned int i) { - etMessageService* p = head; + etRuntime_initInternal(); + ET_MSC_LOGGER_SYNC_ENTRY("etRuntime", "getMessageServiceStatistics") - int count = 0; - while (p!=null) { - if (count==i) { - return &p->statistics; + { + etMessageService* p = etRuntime_msgsvc_head; + int count = 0; + while (p!=null) { + if (count==i) { + ET_MSC_LOGGER_SYNC_EXIT + return &p->statistics; + } + ++count; + p = p->next; } - ++count; - p = p->next; } + ET_MSC_LOGGER_SYNC_EXIT + return NULL; +} + +const char* etRuntime_getMessageServiceName(unsigned int i) { + etRuntime_initInternal(); + ET_MSC_LOGGER_SYNC_ENTRY("etRuntime", "getMessageServiceName") + + { + etMessageService* p = etRuntime_msgsvc_head; + int count = 0; + while (p!=null) { + if (count==i) { + ET_MSC_LOGGER_SYNC_EXIT + return p->name; + } + ++count; + p = p->next; + } + } + + ET_MSC_LOGGER_SYNC_EXIT return NULL; } void etRuntime_resetAllMessageServiceStatistics() { - etMessageService* p = head; + etRuntime_initInternal(); + ET_MSC_LOGGER_SYNC_ENTRY("etRuntime", "resetAllMessageServiceStatistics") - while (p!=null) { - p->resetStatistics = ET_TRUE; - p = p->next; + { + etMessageService* p = etRuntime_msgsvc_head; + while (p!=null) { + p->resetStatistics = ET_TRUE; + p = p->next; + } } + + ET_MSC_LOGGER_SYNC_EXIT } void etRuntime_registerMessageService(etMessageService* msgService) { - msgService->next = head; - head = msgService; + etRuntime_initInternal(); + ET_MSC_LOGGER_SYNC_ENTRY("etRuntime", "registerMessageService") - if (msgService->name==NULL) { - void* p = malloc(16); - sprintf(p, "MsgSvc_%d", etRuntime_getMessageServiceCount()); - msgService->name = (const char*) p; + { + msgService->next = etRuntime_msgsvc_head; + etRuntime_msgsvc_head = msgService; + if (msgService->name==NULL) { + void* p = malloc(16); + sprintf(p, "MsgSvc_%d", etRuntime_getMessageServiceCount()); + msgService->name = (const char*) p; + } } + + ET_MSC_LOGGER_SYNC_EXIT } void etRuntime_unregisterMessageService(etMessageService* msgService) { - etMessageService* p = head; - etMessageService* last = NULL; - - while (p!=null) { - if (p==msgService) { - if (last==NULL) { - /* remove the first one */ - head = p->next; + etRuntime_initInternal(); + ET_MSC_LOGGER_SYNC_ENTRY("etRuntime", "unregisterMessageService") + + { + etMessageService* p = etRuntime_msgsvc_head; + etMessageService* last = NULL; + while (p!=null) { + if (p==msgService) { + if (last==NULL) { + /* remove the first one */ + etRuntime_msgsvc_head = p->next; + } + else { + last->next = p->next; + } + break; + } + last = p; + p = p->next; + } + } + + ET_MSC_LOGGER_SYNC_EXIT +} + +void etRuntime_registerMemoryManagement(etMemory* mem) { + etRuntime_initInternal(); + ET_MSC_LOGGER_SYNC_ENTRY("etRuntime", "registerMemoryManagement") + + { + mem->next = etRuntime_memmgmt_head; + etRuntime_memmgmt_head = mem; + if (mem->name==NULL) { + void* p = malloc(16); + sprintf(p, "MemMgmt_%d", etRuntime_getMemoryManagementCount()); + mem->name = (const char*) p; + } + } + + ET_MSC_LOGGER_SYNC_EXIT +} + +void etRuntime_unregisterMemoryManagement(etMemory* mem) { + etRuntime_initInternal(); + ET_MSC_LOGGER_SYNC_ENTRY("etRuntime", "unregisterMemoryManagement") + + { + etMemory* p = etRuntime_memmgmt_head; + etMemory* last = NULL; + while (p!=null) { + if (p==mem) { + if (last==NULL) { + /* remove the first one */ + etRuntime_memmgmt_head = p->next; + } + else { + last->next = p->next; + } + break; } - else { - last->next = p->next; + last = p; + p = p->next; + } + } + + ET_MSC_LOGGER_SYNC_EXIT +} + +int etRuntime_getMemoryManagementCount() { + int count = 0; + etRuntime_initInternal(); + ET_MSC_LOGGER_SYNC_ENTRY("etRuntime", "getMemoryManagementCount") + + { + etMemory* p = etRuntime_memmgmt_head; + while (p!=null) { + ++count; + p = p->next; + } + } + + ET_MSC_LOGGER_SYNC_EXIT + return count; +} + +int etRuntime_getMemoryManagementByName(const char* name) { + etRuntime_initInternal(); + ET_MSC_LOGGER_SYNC_ENTRY("etRuntime", "getMemoryManagementByName") + + { + etMemory* p = etRuntime_memmgmt_head; + int idx = 0; + while (p!=null) { + if (strcmp(p->name, name)==0) { + ET_MSC_LOGGER_SYNC_EXIT + return idx; } - break; + ++idx; + p = p->next; } - last = p; - p = p->next; } + + ET_MSC_LOGGER_SYNC_EXIT + return -1; +} + +const etMemoryStatistics* etRuntime_getMemoryManagementStatistics(unsigned int i) { + etRuntime_initInternal(); + ET_MSC_LOGGER_SYNC_ENTRY("etRuntime", "getMemoryManagementStatistics") + + { + etMemory* p = etRuntime_memmgmt_head; + int count = 0; + while (p!=null) { + if (count==i) { + ET_MSC_LOGGER_SYNC_EXIT + return &p->statistics; + } + ++count; + p = p->next; + } + } + + ET_MSC_LOGGER_SYNC_EXIT + return NULL; +} + +const char* etRuntime_getMemoryManagementName(unsigned int i) { + etRuntime_initInternal(); + ET_MSC_LOGGER_SYNC_ENTRY("etRuntime", "getMemoryManagementName") + + { + etMemory* p = etRuntime_memmgmt_head; + int count = 0; + while (p!=null) { + if (count==i) { + ET_MSC_LOGGER_SYNC_EXIT + return p->name; + } + ++count; + p = p->next; + } + } + + ET_MSC_LOGGER_SYNC_EXIT + return NULL; +} + +void etRuntime_resetAllMemoryManagementStatistics() { + etRuntime_initInternal(); + ET_MSC_LOGGER_SYNC_ENTRY("etRuntime", "resetAllMemoryManagementStatistics") + + { + etMemory* p = etRuntime_memmgmt_head; + while (p!=null) { + etMemory_resetStatistics(p); + p = p->next; + } + } + + ET_MSC_LOGGER_SYNC_EXIT } diff --git a/runtime/org.eclipse.etrice.runtime.c/src/common/runtime/etRuntime.h b/runtime/org.eclipse.etrice.runtime.c/src/common/runtime/etRuntime.h index 5c5ff3d0b..4dab21678 100644 --- a/runtime/org.eclipse.etrice.runtime.c/src/common/runtime/etRuntime.h +++ b/runtime/org.eclipse.etrice.runtime.c/src/common/runtime/etRuntime.h @@ -18,6 +18,7 @@ extern "C" { #define _ETRUNTIME_H_ #include "messaging/etMessageService.h" +#include "base/etMemory.h" /** * \file etRuntime.h @@ -45,6 +46,14 @@ int etRuntime_getMessageServiceCount(); const etMessageServiceStatistics* etRuntime_getMessageServiceStatistics(unsigned int i); /** + * returns the name of a message service + * + * \param i the message service instance number + * \return the name of this message service + */ +const char* etRuntime_getMessageServiceName(unsigned int i); + +/** * finds a message service by its name and returns its index or -1 if not found * * \param name the name of the message service @@ -58,16 +67,66 @@ int etRuntime_getMessageServiceByName(const char* name); void etRuntime_resetAllMessageServiceStatistics(); /** - * registers the message service by hooking it into a linked list + * registers a message service + * \param msgService the message service */ void etRuntime_registerMessageService(etMessageService* msgService); /** - * unregisters the message service by removing it from the linked list + * unregisters a message service + * \param msgService the message service */ void etRuntime_unregisterMessageService(etMessageService* msgService); /** + * registers a memory management + * \param mem the memory management + */ +void etRuntime_registerMemoryManagement(etMemory* mem); + +/** + * unregisters a memory management + * \param mem the memory management + */ +void etRuntime_unregisterMemoryManagement(etMemory* mem); + +/** + * returns the number of memory managements in this process + * + * \return the number of memory managements in this process + */ +int etRuntime_getMemoryManagementCount(); + +/** + * returns the statistics of a memory management + * + * \param i the memory management instance number + * \return the statistics of this memory management + */ +const etMemoryStatistics* etRuntime_getMemoryManagementStatistics(unsigned int i); + +/** + * finds a memory management by its name and returns its index or -1 if not found + * + * \param name the name of the memory management + * \return the index of the memory management or -1 + */ +int etRuntime_getMemoryManagementByName(const char* name); + +/** + * returns the name of a memory management + * + * \param i the memory management instance number + * \return the name of this memory management + */ +const char* etRuntime_getMemoryManagementName(unsigned int i); + +/** + * sets a flag in all memory management structs that tells the memory managements to reset their statistics + */ +void etRuntime_resetAllMemoryManagementStatistics(); + +/** * a global semaphore used to terminate the application in headless mode * * \return the semaphore |