diff options
author | Timo Dritschler <timo.dritschler@kit.edu> | 2014-05-27 15:30:08 +0200 |
---|---|---|
committer | Timo Dritschler <timo.dritschler@kit.edu> | 2014-05-27 15:31:04 +0200 |
commit | 69f57959d50cf08d063484551f15f6990582953d (patch) | |
tree | 5b445bc327ad2da38d26837b8693a16421d2111a /src/kiro-trb.c | |
parent | 72cb71c99131db200871dac9e17acefdf97292e7 (diff) | |
download | kiro-69f57959d50cf08d063484551f15f6990582953d.tar.gz kiro-69f57959d50cf08d063484551f15f6990582953d.tar.bz2 kiro-69f57959d50cf08d063484551f15f6990582953d.tar.xz kiro-69f57959d50cf08d063484551f15f6990582953d.zip |
Changed build system to CMake
Diffstat (limited to 'src/kiro-trb.c')
-rw-r--r-- | src/kiro-trb.c | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/src/kiro-trb.c b/src/kiro-trb.c new file mode 100644 index 0000000..e81a4f7 --- /dev/null +++ b/src/kiro-trb.c @@ -0,0 +1,270 @@ +/* Copyright (C) 2014 Timo Dritschler <timo.dritschler@kit.edu> + (Karlsruhe Institute of Technology) + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2.1 of the License, or (at your + option) any later version. + + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + + You should have received a copy of the GNU Lesser General Public License along + with this library; if not, write to the Free Software Foundation, Inc., 51 + Franklin St, Fifth Floor, Boston, MA 02110, USA +*/ + +/** + * SECTION: kiro-trb + * @Short_description: KIRO 'Transmittable Ring Buffer' + * @Title: KiroTrb + * + * KiroTrb implements a 'Transmittable Ring Buffer' that holds all necessary information + * about its content inside itself, so its data can be exchanged between different + * instances of the KiroTrb Class and/or sent over a network. + */ + +#include <stdio.h> + +#include <stdlib.h> +#include <string.h> +#include <glib.h> +#include "kiro-trb.h" + + +/* + * Definition of 'private' structures and members and macro to access them + */ + +#define KIRO_TRB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), KIRO_TYPE_TRB, KiroTrbPrivate)) + +struct _KiroTrbPrivate { + + /* Properties */ + // PLACEHOLDER // + + /* 'Real' private structures */ + /* (Not accessible by properties) */ + int initialized; // 1 if Buffer is Valid, 0 otherwise + void *mem; // Access to the actual buffer in Memory + void *frame_top; // First byte of the buffer storage + void *current; // Pointer to the current fill state + uint64_t element_size; + uint64_t max_elements; + uint64_t iteration; // How many times the buffer has wraped around + + /* easy access */ + uint64_t buff_size; +}; + + +G_DEFINE_TYPE_WITH_PRIVATE (KiroTrb, kiro_trb, G_TYPE_OBJECT); + + +static +void kiro_trb_init (KiroTrb *self) +{ + KiroTrbPrivate *priv = KIRO_TRB_GET_PRIVATE(self); + priv->initialized = 0; +} + +static void +kiro_trb_finalize (GObject *object) +{ + KiroTrb *self = KIRO_TRB(object); + KiroTrbPrivate *priv = KIRO_TRB_GET_PRIVATE(self); + if(priv->mem) + free(priv->mem); +} + +static void +kiro_trb_class_init (KiroTrbClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + gobject_class->finalize = kiro_trb_finalize; +} + + +/* Privat functions */ + +void write_header (KiroTrbPrivate* priv) +{ + if(!priv) + return; + struct KiroTrbInfo* tmp_info = (struct KiroTrbInfo*)priv->mem; + tmp_info->buffer_size_bytes = priv->buff_size; + tmp_info->element_size = priv->element_size; + tmp_info->offset = (priv->iteration * priv->max_elements) + ((priv->current - priv->frame_top) / priv->element_size); + memcpy(priv->mem, tmp_info, sizeof(struct KiroTrbInfo)); +} + + + +/* TRB functions */ + +uint64_t kiro_trb_get_element_size (KiroTrb* self) +{ + KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self); + if(priv->initialized != 1) + return 0; + return priv->element_size; +} + + +uint64_t kiro_trb_get_max_elements (KiroTrb* self) +{ + KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self); + if(priv->initialized != 1) + return 0; + return priv->max_elements; +} + + +uint64_t kiro_trb_get_raw_size (KiroTrb* self) +{ + KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self); + if(priv->initialized != 1) + return 0; + return priv->buff_size; +} + + +void* kiro_trb_get_raw_buffer (KiroTrb* self) +{ + KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self); + if(priv->initialized != 1) + return NULL; + write_header(priv); + return priv->mem; +} + + + +void* kiro_trb_get_element (KiroTrb* self, uint64_t element) +{ + KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self); + if(priv->initialized != 1) + return NULL; + + uint64_t relative = 0; + if(priv->iteration == 0) + relative = element * priv->element_size; + else + relative = ((priv->current - priv->frame_top) + (priv->element_size * element)) % (priv->buff_size - sizeof(struct KiroTrbInfo)); + + return priv->frame_top + relative; +} + + +void kiro_trb_flush (KiroTrb *self) +{ + KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self); + priv->iteration = 0; + priv->current = priv->frame_top; + write_header(priv); +} + + +int kiro_trb_is_setup (KiroTrb *self) +{ + KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self); + return priv->initialized; +} + + +int kiro_trb_reshape (KiroTrb *self, uint64_t element_size, uint64_t element_count) +{ + size_t new_size = (element_size * element_count) + sizeof(struct KiroTrbInfo); + void* newmem = malloc(new_size); + if(!newmem) + return -1; + ((struct KiroTrbInfo *)newmem)->buffer_size_bytes = new_size; + ((struct KiroTrbInfo *)newmem)->element_size = element_size; + ((struct KiroTrbInfo *)newmem)->offset = 0; + kiro_trb_adopt(self, newmem); + return 0; +} + + +int kiro_trb_push (KiroTrb *self, void *element_in) +{ + KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self); + if(priv->initialized != 1) + return -1; + if((priv->current + priv->element_size) > (priv->mem + priv->buff_size)) + return -1; + memcpy(priv->current, element_in, priv->element_size); + priv->current += priv->element_size; + if(priv->current >= priv->frame_top + (priv->element_size * priv->max_elements)) + { + priv->current = priv->frame_top; + priv->iteration++; + } + write_header(priv); + return 0; +} + + +void* kiro_trb_dma_push (KiroTrb *self) +{ + KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self); + if(priv->initialized != 1) + return NULL; + if((priv->current + priv->element_size) > (priv->mem + priv->buff_size)) + return NULL; + void *mem_out = priv->current; + priv->current += priv->element_size; + if(priv->current >= priv->frame_top + (priv->element_size * priv->max_elements)) + { + priv->current = priv->frame_top; + priv->iteration++; + } + write_header(priv); + return mem_out; +} + + +void kiro_trb_refresh (KiroTrb *self) +{ + KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self); + if(priv->initialized != 1) + return; + struct KiroTrbInfo *tmp = (struct KiroTrbInfo *)priv->mem; + priv->buff_size = tmp->buffer_size_bytes; + priv->element_size = tmp->element_size; + priv->max_elements = (tmp->buffer_size_bytes - sizeof(struct KiroTrbInfo)) / tmp->element_size; + priv->iteration = tmp->offset / priv->max_elements; + priv->frame_top = priv->mem + sizeof(struct KiroTrbInfo); + priv->current = priv->frame_top + ((tmp->offset % priv->max_elements) * priv->element_size); + priv->initialized = 1; +} + + +void kiro_trb_adopt (KiroTrb *self, void *buff_in) +{ + KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self); + if(priv->mem) + free(priv->mem); + priv->mem = buff_in; + priv->initialized = 1; + kiro_trb_refresh(self); +} + + +int kiro_trb_clone (KiroTrb *self, void *buff_in) +{ + KiroTrbPrivate* priv = KIRO_TRB_GET_PRIVATE(self); + struct KiroTrbInfo *header = (struct KiroTrbInfo *)buff_in; + void *newmem = malloc(header->buffer_size_bytes); + if(!newmem) + return -1; + memcpy(newmem, buff_in, header->buffer_size_bytes); + if(priv->mem) + free(priv->mem); + priv->mem = newmem; + priv->initialized = 1; + kiro_trb_refresh(self); + return 0; +} |