Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrik Rentz-Reichert2012-11-05 07:54:01 +0000
committerHenrik Rentz-Reichert2012-11-05 07:56:07 +0000
commit59eb76aee7a8e4021303394197c0008a8a39634d (patch)
treef5a7c72a90e11cdbb53aae645fccebd3893329df /runtime
parent5811dcd34fa10420d0f33523b4b39ed422321903 (diff)
downloadorg.eclipse.etrice-59eb76aee7a8e4021303394197c0008a8a39634d.tar.gz
org.eclipse.etrice-59eb76aee7a8e4021303394197c0008a8a39634d.tar.xz
org.eclipse.etrice-59eb76aee7a8e4021303394197c0008a8a39634d.zip
[runtime.c] added base components
- etQueue - two versions of memory management
Diffstat (limited to 'runtime')
-rw-r--r--runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory.h45
-rw-r--r--runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FixedSize.c79
-rw-r--r--runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FreeList.c162
-rw-r--r--runtime/org.eclipse.etrice.runtime.c/src/common/base/etQueue.c103
-rw-r--r--runtime/org.eclipse.etrice.runtime.c/src/common/base/etQueue.h49
-rw-r--r--runtime/org.eclipse.etrice.runtime.c/src/platforms/generic/etDatatypes.h2
6 files changed, 440 insertions, 0 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
new file mode 100644
index 000000000..17581b74e
--- /dev/null
+++ b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory.h
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * 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)
+ *
+ *******************************************************************************/
+
+#ifndef _ETMEMORY_H_
+#define _ETMEMORY_H_
+
+#include "etDatatypes.h"
+
+#define CEIL_ALIGN(n) ((n)+((ALIGNMENT-((n)&(ALIGNMENT-1)))&(ALIGNMENT-1)))
+
+/**
+ * initializes the heap
+ *
+ * \param heap pointer to the heap memory
+ * \param size the size of the heap in bytes
+ */
+void etMemory_init(void* heap, etUInt16 size);
+
+/**
+ * allocates memory from the heap
+ *
+ * \param heap pointer to the heap memory
+ * \param size the size of the requested memory in bytes
+ */
+void* etMemory_alloc(void* heap, etUInt16 size);
+
+/**
+ * frees memory previously allocated from the heap
+ *
+ * \param heap pointer to the heap memory
+ * \param obj pointer to the memory returned
+ * \param size the size in bytes of the memory returned
+ */
+void etMemory_free(void* heap, void* obj, etUInt16 size);
+
+#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
new file mode 100644
index 000000000..e3584819e
--- /dev/null
+++ b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FixedSize.c
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * 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.h"
+#include "base/etQueue.h"
+#include "debugging/etLogger.h"
+#include "debugging/etMSCLogger.h"
+
+#define BLOCK_SIZE 128
+
+
+typedef struct etFixedSizeMemory {
+ etUInt8 *buffer;
+ etUInt16 maxBlocks;
+ etUInt16 blockSize;
+ etQueue blockPool;
+} etFixedSizeMemory;
+
+/*
+ * the public interface
+ */
+void etMemory_init(void* heap, etUInt16 size) {
+ etFixedSizeMemory* self = (etFixedSizeMemory*) heap;
+ size_t data_size = CEIL_ALIGN(sizeof(etFixedSizeMemory));
+ int i;
+
+ ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "init")
+
+ if (size > data_size) {
+ self->buffer = ((etUInt8*) self) + data_size;
+ self->blockSize = BLOCK_SIZE;
+ self->maxBlocks = (size - data_size) / self->blockSize;
+ 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
+}
+
+void* etMemory_alloc(void* heap, etUInt16 size) {
+ etFixedSizeMemory* self = (etFixedSizeMemory*) heap;
+ void* mem = NULL;
+ size = CEIL_ALIGN(size);
+
+ ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "alloc")
+
+ if (size<=self->blockSize){
+ if (self->blockPool.size>0) {
+ mem = etQueue_pop(&self->blockPool);
+ }
+ }
+
+ ET_MSC_LOGGER_SYNC_EXIT
+ return mem;
+}
+
+void etMemory_free(void* heap, void* obj, etUInt16 size) {
+ etFixedSizeMemory* self = (etFixedSizeMemory*) heap;
+
+ ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "free")
+
+ etQueue_push(&self->blockPool, obj);
+
+ ET_MSC_LOGGER_SYNC_EXIT
+}
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
new file mode 100644
index 000000000..452377a39
--- /dev/null
+++ b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etMemory_FreeList.c
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * 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.h"
+#include "debugging/etLogger.h"
+#include "debugging/etMSCLogger.h"
+
+#define UNUSED_LIST 0
+#define NSLOTS 128
+
+/*
+ * private data structures
+ */
+
+typedef struct etFreeListObj {
+ struct etFreeListObj* next;
+} etFreeListObj;
+
+typedef struct etFreeListInfo {
+ /** the size in bytes of the objects in this list */
+ etUInt16 objsize;
+
+ /** the list head */
+ etFreeListObj* head;
+} etFreeListInfo;
+
+typedef struct etFreeListMemory {
+ /** size of the heap in bytes */
+ etUInt16 size;
+
+ /** next free position on the heap */
+ etUInt8* current;
+
+ /** number of free lists */
+ etUInt16 nslots;
+
+ /** array of free list infos (array used with size nslots) */
+ etFreeListInfo freelists[1];
+} etFreeListMemory;
+
+/*
+ * private functions
+ */
+static void* etMemory_getHeapMem(etFreeListMemory* self, etUInt16 size) {
+ etUInt8* obj = NULL;
+ ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "getHeapListMem")
+
+ if (self->current < ((etUInt8*)self)+self->size)
+ {
+ obj = self->current;
+ self->current += size;
+ }
+
+ ET_MSC_LOGGER_SYNC_EXIT
+ return obj;
+}
+
+static void* etMemory_getFreeListMem(etFreeListMemory* self, etUInt16 size) {
+ etUInt8* mem = NULL;
+ int asize, slot_offset, slot, slot_size;
+ ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "getFreeListMem")
+
+ asize = (size / ALIGNMENT);
+ for (slot_offset = 0; slot_offset < self->nslots; slot_offset++) {
+ slot = (asize + slot_offset) % self->nslots;
+ slot_size = self->freelists[slot].objsize;
+ if (slot_size == size) {
+ if (self->freelists[slot].head != NULL) {
+ etFreeListObj* obj = self->freelists[slot].head;
+ self->freelists[slot].head = obj->next;
+ mem = (void *) obj;
+ }
+ break;
+ }
+ else if (slot_size == UNUSED_LIST)
+ break;
+ }
+ ET_MSC_LOGGER_SYNC_EXIT
+ return mem;
+}
+
+static void etMemory_putFreeListMem(void* heap, void* obj, etUInt16 size) {
+ ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "putFreeListMem")
+ {
+ etFreeListMemory* self = (etFreeListMemory*) heap;
+ int asize, slot_offset, slot, slot_size;
+
+ asize = (size / ALIGNMENT);
+ for (slot_offset = 0; slot_offset < self->nslots; slot_offset++) {
+ slot = (asize + slot_offset) % self->nslots;
+ slot_size = self->freelists[slot].objsize;
+ if (slot_size == size) {
+ /* we insert the object as new head */
+ ((etFreeListObj*)obj)->next = self->freelists[slot].head;
+ self->freelists[slot].head = (etFreeListObj*)obj;
+ break;
+ }
+ else if (slot_size == UNUSED_LIST) {
+ /* initialize unused list and insert the object as new head */
+ self->freelists[slot].objsize = size;
+ ((etFreeListObj*)obj)->next = NULL;
+ self->freelists[slot].head = (etFreeListObj*)obj;
+ break;
+ }
+ }
+ }
+ ET_MSC_LOGGER_SYNC_EXIT
+}
+
+/*
+ * the public interface
+ */
+void etMemory_init(void* heap, etUInt16 size) {
+ etFreeListMemory* self = (etFreeListMemory*) heap;
+ ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "init")
+
+ self->size = size;
+ self->nslots = NSLOTS;
+ {
+ int used = sizeof(etFreeListMemory)+(self->nslots-1)*sizeof(etFreeListObj);
+ self->current = ((etUInt8*)self)+CEIL_ALIGN(used);
+ }
+
+ /* initialize the free lists */
+ {
+ int i;
+ for (i=0; i<self->nslots; ++i)
+ self->freelists[i].objsize = UNUSED_LIST;
+ }
+ ET_MSC_LOGGER_SYNC_EXIT
+}
+
+void* etMemory_alloc(void* heap, etUInt16 size) {
+ void* mem;
+ size = CEIL_ALIGN(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_EXIT
+ return mem;
+}
+
+void etMemory_free(void* heap, void* obj, etUInt16 size) {
+ ET_MSC_LOGGER_SYNC_ENTRY("etMemory", "free")
+ {
+ size = CEIL_ALIGN(size);
+ etMemory_putFreeListMem((etFreeListMemory*) heap, obj, size);
+ }
+ ET_MSC_LOGGER_SYNC_EXIT
+}
diff --git a/runtime/org.eclipse.etrice.runtime.c/src/common/base/etQueue.c b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etQueue.c
new file mode 100644
index 000000000..b2f92db18
--- /dev/null
+++ b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etQueue.c
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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:
+ * Thomas Schuetz (initial contribution)
+ *
+ *******************************************************************************/
+
+#include "base/etQueue.h"
+#include "debugging/etMSCLogger.h"
+
+void etQueue_init(etQueue* self){
+ ET_MSC_LOGGER_SYNC_ENTRY("etQueue", "init")
+
+ self->first = NULL;
+ self->last = NULL;
+ self->highWaterMark = 0;
+ self->size = 0;
+
+ ET_MSC_LOGGER_SYNC_EXIT
+}
+
+
+void etQueue_push(etQueue* self, void* obj){
+ // TODO: optimize queue for concurrent push / pop
+ ET_MSC_LOGGER_SYNC_ENTRY("etQueue", "push")
+
+ if (self->first == NULL) {
+ /*no object in queue*/
+ self->first = self->last = obj;
+ }
+ else {
+ /*at least one object in queue*/
+ self->last->next = obj;
+ self->last = obj;
+ }
+ ((etQueueObj*)obj)->next = NULL; /*TODO: optimization: this line could be removed if we assume that all objects are initialized*/
+
+ if (++self->size > self->highWaterMark)
+ self->highWaterMark++;
+
+ ET_MSC_LOGGER_SYNC_EXIT
+}
+
+void* etQueue_pop(etQueue* self){
+ etQueueObj* pop_msg = self->first;
+
+ ET_MSC_LOGGER_SYNC_ENTRY("etQueue", "pop")
+
+ if (self->first == NULL){
+ /*no message in queue*/
+ ET_MSC_LOGGER_SYNC_EXIT
+ return NULL;
+ }
+ if (self->first->next==NULL){
+ /*only one message in queue*/
+ self->first = self->last = NULL;
+ }
+ else {
+ /*more than one message in queue -> set first to nex message*/
+ self->first = self->first->next;
+ }
+
+ pop_msg->next=NULL;
+ self->size--;
+
+ ET_MSC_LOGGER_SYNC_EXIT
+ return pop_msg;
+}
+
+etInt16 etQueue_getSize(etQueue* self) {
+ ET_MSC_LOGGER_SYNC_ENTRY("etQueue", "getSize")
+ ET_MSC_LOGGER_SYNC_EXIT
+ return self->size;
+}
+
+void* etQueue_getFirst(etQueue* self){
+ ET_MSC_LOGGER_SYNC_ENTRY("etQueue", "getFirst")
+ ET_MSC_LOGGER_SYNC_EXIT
+ return self->first;
+}
+
+void* etQueue_getLast(etQueue* self){
+ ET_MSC_LOGGER_SYNC_ENTRY("etQueue", "getLast")
+ ET_MSC_LOGGER_SYNC_EXIT
+ return self->last;
+}
+
+etBool etQueue_isNotEmpty(etQueue* self){
+ ET_MSC_LOGGER_SYNC_ENTRY("etQueue", "isNotEmpty")
+ ET_MSC_LOGGER_SYNC_EXIT
+ return self->last != NULL;
+}
+
+etInt16 etQueue_getHighWaterMark(etQueue* self) {
+ ET_MSC_LOGGER_SYNC_ENTRY("etQueue", "getHightWaterMark")
+ ET_MSC_LOGGER_SYNC_EXIT
+ return self->highWaterMark;
+}
diff --git a/runtime/org.eclipse.etrice.runtime.c/src/common/base/etQueue.h b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etQueue.h
new file mode 100644
index 000000000..dc60d6ff2
--- /dev/null
+++ b/runtime/org.eclipse.etrice.runtime.c/src/common/base/etQueue.h
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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:
+ * Thomas Schuetz (initial contribution)
+ *
+ *******************************************************************************/
+
+#ifndef _ETQUEUE_H_
+#define _ETQUEUE_H_
+
+#include <stddef.h>
+#include "etDatatypes.h"
+
+typedef struct etQueueObj {
+ struct etQueueObj* next;
+} etQueueObj;
+
+typedef struct etQueue {
+ etQueueObj* first;
+ etQueueObj* last;
+ etInt16 highWaterMark;
+ etInt16 size;
+
+} etQueue;
+
+void etQueue_init(etQueue* self);
+
+void etQueue_push(etQueue* self, void* obj);
+
+void* etQueue_pop(etQueue* self);
+
+void* etQueue_getFirst(etQueue* self);
+
+void* etQueue_getLast(etQueue* self);
+
+etBool etQueue_isNotEmpty(etQueue* self);
+
+etInt16 etQueue_getHighWaterMark(etQueue* self);
+
+etInt16 etQueue_getSize(etQueue* self);
+
+
+
+#endif /* _ETQUEUE_H_ */
diff --git a/runtime/org.eclipse.etrice.runtime.c/src/platforms/generic/etDatatypes.h b/runtime/org.eclipse.etrice.runtime.c/src/platforms/generic/etDatatypes.h
index e3ca3c088..6b45744d4 100644
--- a/runtime/org.eclipse.etrice.runtime.c/src/platforms/generic/etDatatypes.h
+++ b/runtime/org.eclipse.etrice.runtime.c/src/platforms/generic/etDatatypes.h
@@ -52,6 +52,8 @@ typedef bool boolean;
#define FALSE 0
#endif
+#define ALIGNMENT 4
+
/*
* typedefs for eTrice Runtime and Testing
*

Back to the top