mirror of https://github.com/rusefi/ChibiOS.git
OS objects factory, work in progress.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10711 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
eae327a32e
commit
590df48760
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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 */
|
||||
|
||||
/** @} */
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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.<br>
|
||||
* @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 <string.h>
|
||||
|
||||
#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 */
|
||||
|
||||
/** @} */
|
Loading…
Reference in New Issue