From 590df48760ecc9e9a146c5bd52b91c47489d4e99 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Mon, 25 Sep 2017 15:11:41 +0000 Subject: OS objects factory, work in progress. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10711 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/common/oslib/include/chfactory.h | 220 ++++++++++++++++++++++++++++++++++++ os/common/oslib/src/chfactory.c | 192 +++++++++++++++++++++++++++++++ 2 files changed, 412 insertions(+) create mode 100644 os/common/oslib/include/chfactory.h create mode 100644 os/common/oslib/src/chfactory.c diff --git a/os/common/oslib/include/chfactory.h b/os/common/oslib/include/chfactory.h new file mode 100644 index 000000000..d8cd20a22 --- /dev/null +++ b/os/common/oslib/include/chfactory.h @@ -0,0 +1,220 @@ +/* + ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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. + + ChibiOS 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 . +*/ + +/** + * @file chfactory.h + * @brief ChibiOS objects factory structures and macros. + * + * @addtogroup objects_factory + * @{ + */ + +#ifndef CHFACTORY_H +#define CHFACTORY_H + +#if (CH_CFG_USE_FACTORY == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @brief Maximum length for object names. + * @details If the specified length is zero then the name is stored by + * pointer but this could have unintended side effects. + */ +#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGHT) || defined(__DOXYGEN__) +#define CH_CFG_FACTORY_MAX_NAMES_LENGHT 8 +#endif + +/** + * @brief Enables factory for generic objects. + * @note Generic objects require the heap allocator. + */ +#if !defined(CH_CFG_FACTORY_GENERIC) || defined(__DOXYGEN__) +#define CH_CFG_FACTORY_GENERIC TRUE +#endif + +/** + * @brief Enables factory for semaphores. + */ +#if !defined(CH_CFG_FACTORY_SEMAPHORES) || defined(__DOXYGEN__) +#define CH_CFG_FACTORY_SEMAPHORES TRUE +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#define CH_FACTORY_REQUIRES_POOLS \ + ((CH_CFG_FACTORY_SEMAPHORES == TRUE)) + +#define CH_FACTORY_REQUIRES_HEAP \ + ((CH_CFG_FACTORY_GENERIC == TRUE)) + +#if (CH_CFG_FACTORY_MAX_NAMES_LENGHT < 0) || \ + (CH_CFG_FACTORY_MAX_NAMES_LENGHT > 32) +#error "invalid CH_CFG_FACTORY_MAX_NAMES_LENGHT value" +#endif + +#if CH_CFG_USE_MEMCORE == FALSE +#error "CH_CFG_USE_FACTORY requires CH_CFG_USE_MEMCORE" +#endif + +#if (CH_FACTORY_REQUIRES_POOLS == TRUE) && (CH_CFG_USE_MEMPOOLS == FALSE) +#error "CH_CFG_USE_MEMPOOLS is required" +#endif + +#if (CH_FACTORY_REQUIRES_HEAP == TRUE) && (CH_CFG_USE_HEAP == FALSE) +#error "CH_CFG_USE_HEAP is required" +#endif + +#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) && (CH_CFG_USE_SEMAPHORES == FALSE) +#error "CH_CFG_FACTORY_SEMAPHORES requires CH_CFG_USE_SEMAPHORES" +#endif + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of a dynamic object list element. + */ +typedef struct ch_dyn_element { + /** + * @brief Next dynamic object in the list. + */ + struct ch_dyn_element *next; + /** + * @brief Number of references to this object. + */ + ucnt_t refs; +#if (CH_CFG_FACTORY_MAX_NAMES_LENGHT > 0) || defined(__DOXIGEN__) + char name[CH_CFG_FACTORY_MAX_NAMES_LENGHT]; +#else + const char *name; +#endif +} dyn_element_t; + +/** + * @brief Type of a dynamic object list. + */ +typedef struct ch_dyn_list { + dyn_element_t *next; +} dyn_list_t; + +#if (CH_CFG_FACTORY_GENERIC == TRUE) || defined(__DOXIGEN__) +/** + * @brief Type of a dynamic semaphore. + */ +typedef struct ch_dyn_object { + /** + * @brief List element of the dynamic object. + */ + dyn_element_t list; + /** + * @brief Physical objects. + * @note This requires C99. + */ + uint8_t obj[]; +} dyn_object_t; +#endif + +#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__) +/** + * @brief Type of a dynamic semaphore. + */ +typedef struct ch_dyn_semaphore { + /** + * @brief List element of the dynamic semaphore. + */ + dyn_element_t list; + /** + * @brief Physical semaphore. + */ + semaphore_t sem; +} dyn_semaphore_t; +#endif + +/** + * @brief Type of the factory main object. + */ +typedef struct ch_objects_factory { +#if (CH_CFG_FACTORY_GENERIC == TRUE) || defined(__DOXIGEN__) + /** + * @brief List of the allocated objects. + */ + dyn_list_t obj_list; +#endif /* CH_CFG_FACTORY_GENERIC = TRUE */ +#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__) + /** + * @brief List of the allocated semaphores. + */ + dyn_list_t sem_list; + /** + * @brief Pool of the available semaphores. + */ + memory_pool_t sem_pool; +#endif /* CH_CFG_FACTORY_SEMAPHORES = TRUE */ +} objects_factory_t; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +objects_factory_t ch_factory; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void _factory_init(void); +#if (CH_CFG_FACTORY_GENERIC == TRUE) || defined(__DOXIGEN__) + dyn_object_t *chFactoryCreateObject(const char *name, size_t size); + dyn_object_t *chFactoryFindObject(const char *name); + void chFactoryReleaseObject(dyn_object_t *dop); + size_t chFactoryGetObjectSize(dyn_object_t *dop); +#endif +#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__) + dyn_semaphore_t *chFactoryCreateSemaphore(const char *name, cnt_t n); + dyn_semaphore_t *chFactoryFindSemaphore(const char *name); + void chFactoryReleaseSemaphore(dyn_semaphore_t *dsp); +#endif +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* CH_CFG_USE_FACTORY == TRUE */ + +#endif /* CHFACTORY_H */ + +/** @} */ diff --git a/os/common/oslib/src/chfactory.c b/os/common/oslib/src/chfactory.c new file mode 100644 index 000000000..7e8d3a273 --- /dev/null +++ b/os/common/oslib/src/chfactory.c @@ -0,0 +1,192 @@ +/* + ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS 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. + + ChibiOS 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 . +*/ + +/** + * @file chfactory.c + * @brief ChibiOS objects factory code. + * + * @addtogroup objects_factory + * @details The object factory is a subsystem that allows to: + * - Create objects and assign them a name. + * - Retrieve existing objects by name. + * - Free objects by reference. + * . + * Allocated OS objects are handled using a reference counter, only + * when all references have been released then the object memory is + * freed in a pool.
+ * @pre This subsystem requires the @p CH_CFG_USE_MEMCORE and + * @p CH_CFG_USE_MEMPOOLS options to be set to @p TRUE. The + * option @p CH_CFG_USE_HEAP is also required if the support + * for variable length objects is enabled. + * @note Compatible with RT and NIL. + * @{ + */ + +#include + +#include "ch.h" +#include "chfactory.h" + +#if (CH_CFG_USE_FACTORY == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/** + * @brief Factory object static instance. + * @note It is a global object because it could be accessed through + * a specific debugger plugin. + */ +objects_factory_t ch_factory; + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +static inline void dyn_list_init(dyn_list_t *dlp) { + + dlp->next = (dyn_element_t *)dlp; +} + +static dyn_element_t *dyn_list_find(dyn_list_t *dlp, const char *name) { + dyn_element_t *p = dlp->next; + + while (p != (dyn_element_t *)dlp) { + if (strncmp(p->name, name, CH_CFG_FACTORY_MAX_NAMES_LENGHT) == 0) { + return p; + } + p = p->next; + } + + return NULL; +} + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the objects factory. + * + * @init + */ +void _factory_init(void) { + +#if CH_CFG_FACTORY_GENERIC == TRUE + dyn_list_init(&ch_factory.obj_list); +#endif +#if CH_CFG_FACTORY_SEMAPHORES == TRUE + dyn_list_init(&ch_factory.sem_list); + chPoolObjectInit(&ch_factory.sem_pool, + sizeof (dyn_semaphore_t), + chCoreAllocAlignedI); +#endif +} + +#if (CH_CFG_FACTORY_GENERIC == TRUE) || defined(__DOXIGEN__) +/** + * @brief Allocates a generic dynamic object. + * @post A reference to the object is returned and the reference counter + * is initialized to one. + * @post The object is zero filled. + * + * @param[in] name name to be assigned to the new object + * @param[in] size payload size of the object to be created + * + * @return The reference to the created object. + * @retval NULL if the object cannot be allocated or an object with + * the same name exists. + */ +dyn_object_t *chFactoryCreateObject(const char *name, size_t size) { + dyn_object_t *dop; + + chSysLock(); + + /* Checking if an object with this name has already been created.*/ + dop = (dyn_object_t *)dyn_list_find(&ch_factory.obj_list, name); + if (dop != NULL) { + /* Object exists, error.*/ + chSysUnlock(); + return NULL; + } + + dop = chHeapAlloc(NULL, size); + if (dop == NULL) { + chSysUnlock(); + return NULL; + } + + /* Initializing object data and metadata.*/ + strncpy(&dop->list.name, name, CH_CFG_FACTORY_MAX_NAMES_LENGHT); + dop->list.refs = 1; + dop->list.next = ch_factory.obj_list.next; + memset((void *)dop->obj, 0, size); + + /* Updating factory list.*/ + ch_factory.obj_list.next = dop; + + chSysUnlock(); + + return dop; +} + +dyn_object_t *chFactoryFindObject(const char *name) { + +} + +void chFactoryReleaseObject(dyn_object_t *dop) { + +} + +size_t chFactoryGetObjectSize(dyn_object_t *dop) { + + return chHeapGetSize((void *)dop); +} +#endif /* CH_CFG_FACTORY_GENERIC = TRUE */ + +#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__) +dyn_semaphore_t *chFactoryCreateSemaphore(const char *name, cnt_t n) { + +} + +dyn_semaphore_t *chFactoryFindSemaphore(const char *name) { + +} + +void chFactoryReleaseSemaphore(dyn_semaphore_t *dsp) { + +} +#endif /* CH_CFG_FACTORY_SEMAPHORES = TRUE */ + +#endif /* CH_CFG_USE_FACTORY == TRUE */ + +/** @} */ -- cgit v1.2.3