commit 1c8ae144469b6d129183e316b382d38ed1e59cf0
parent d10582f8d28e8926ae8b13fcb9c7d5f36646aace
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 8 Dec 2017 10:08:14 +0100
Implement the Stardis data API
Diffstat:
2 files changed, 127 insertions(+), 0 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -42,6 +42,7 @@ set(VERSION_PATCH 0)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(SDIS_FILES_SRC
+ sdis_data.c
sdis_device.c)
set(SDIS_FILES_INC_API
diff --git a/src/sdis_data.c b/src/sdis_data.c
@@ -0,0 +1,126 @@
+/* Copyright (C) CNRS 2016-2017
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "sdis.h"
+#include "sdis_device_c.h"
+
+#include <rsys/math.h>
+#include <rsys/mem_allocator.h>
+
+struct sdis_data {
+ void* mem; /* Raw memory where user data are stored */
+ void (*release)(void*); /* Function to invoke priorly to `mem' destruction */
+
+ ref_T ref;
+ struct sdis_device* dev;
+};
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static void
+data_release(ref_T* ref)
+{
+ struct sdis_data* data;
+ struct sdis_device* dev;
+ ASSERT(ref);
+ data = CONTAINER_OF(ref, struct sdis_data, ref);
+ dev = data->dev;
+ if(data->release) data->release(data->mem);
+ if(data->mem) MEM_RM(dev->allocator, data->mem);
+ MEM_RM(dev->allocator, data);
+ SDIS(device_ref_put(dev));
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+sdis_data_create
+ (struct sdis_device* dev,
+ const size_t size,
+ const size_t align,
+ void (*release)(void*),
+ struct sdis_data** out_data)
+{
+ struct sdis_data* data = NULL;
+ res_T res = RES_OK;
+
+ if(!dev || !size || !IS_POW2(align) || !out_data) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ data = MEM_CALLOC(dev->allocator, 1, sizeof(struct sdis_data));
+ if(!data) {
+ log_err(dev, "Could not allocate the Stardis dataeter.\n");
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ref_init(&data->ref);
+ SDIS(device_ref_get(dev));
+ data->dev = dev;
+ data->release = release;
+
+ data->mem = MEM_ALLOC_ALIGNED(dev->allocator, size, align);
+ if(!data->mem) {
+ log_err(dev, "Could not allocate the memory of the Stardis dataeter. "
+ "Size: %lu; alignment: %lu\n.", size, align);
+ res = RES_MEM_ERR;
+ goto error;
+ }
+
+exit:
+ if(out_data) *out_data = data;
+ return res;
+
+error:
+ if(data) {
+ SDIS(data_ref_put(data));
+ data = NULL;
+ }
+ goto exit;
+}
+
+res_T
+sdis_data_ref_get(struct sdis_data* data)
+{
+ if(!data) return RES_BAD_ARG;
+ ref_get(&data->ref);
+ return RES_OK;
+}
+
+res_T
+sdis_data_ref_put(struct sdis_data* data)
+{
+ if(!data) return RES_BAD_ARG;
+ ref_put(&data->ref, data_release);
+ return RES_OK;
+}
+
+void*
+sdis_data_get(struct sdis_data* data)
+{
+ if(!data) FATAL("invalid argument.\n");
+ return data->mem;
+}
+
+const void*
+sdis_data_cget(const struct sdis_data* data)
+{
+ if(!data) FATAL("invalid argument.\n");
+ return data->mem;
+}
+