Factory enhanced.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10727 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
6568f70bd8
commit
76663a4a79
|
@ -48,11 +48,17 @@
|
|||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables factory for generic objects.
|
||||
* @note Generic objects require the heap allocator.
|
||||
* @brief Enables the registry of generic objects.
|
||||
*/
|
||||
#if !defined(CH_CFG_FACTORY_GENERIC_BUFFER) || defined(__DOXYGEN__)
|
||||
#define CH_CFG_FACTORY_GENERIC_BUFFER TRUE
|
||||
#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY) || defined(__DOXYGEN__)
|
||||
#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables factory for generic buffers.
|
||||
*/
|
||||
#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS) || defined(__DOXYGEN__)
|
||||
#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -70,7 +76,7 @@
|
|||
((CH_CFG_FACTORY_SEMAPHORES == TRUE))
|
||||
|
||||
#define CH_FACTORY_REQUIRES_HEAP \
|
||||
((CH_CFG_FACTORY_GENERIC_BUFFER == TRUE))
|
||||
((CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE))
|
||||
|
||||
#if (CH_CFG_FACTORY_MAX_NAMES_LENGHT < 0) || \
|
||||
(CH_CFG_FACTORY_MAX_NAMES_LENGHT > 32)
|
||||
|
@ -123,17 +129,34 @@ typedef struct ch_dyn_list {
|
|||
dyn_element_t *next;
|
||||
} dyn_list_t;
|
||||
|
||||
#if (CH_CFG_FACTORY_GENERIC_BUFFER == TRUE) || defined(__DOXIGEN__)
|
||||
#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXIGEN__)
|
||||
/**
|
||||
* @brief Type of a dynamic semaphore.
|
||||
* @brief Type of a registered object.
|
||||
*/
|
||||
typedef struct ch_dyn_object {
|
||||
typedef struct ch_registered_static_object {
|
||||
/**
|
||||
* @brief List element of the dynamic object.
|
||||
* @brief List element of the registered object.
|
||||
*/
|
||||
dyn_element_t element;
|
||||
/**
|
||||
* @brief Physical objects.
|
||||
* @brief Pointer to the object.
|
||||
* @note The type of the object is not stored in anyway.
|
||||
*/
|
||||
void *objp;
|
||||
} registered_object_t;
|
||||
#endif
|
||||
|
||||
#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXIGEN__)
|
||||
/**
|
||||
* @brief Type of a dynamic buffer object.
|
||||
*/
|
||||
typedef struct ch_dyn_object {
|
||||
/**
|
||||
* @brief List element of the dynamic buffer object.
|
||||
*/
|
||||
dyn_element_t element;
|
||||
/**
|
||||
* @brief Physical buffer objects.
|
||||
* @note This requires C99.
|
||||
*/
|
||||
uint8_t buffer[];
|
||||
|
@ -160,12 +183,20 @@ typedef struct ch_dyn_semaphore {
|
|||
* @brief Type of the factory main object.
|
||||
*/
|
||||
typedef struct ch_objects_factory {
|
||||
#if (CH_CFG_FACTORY_GENERIC_BUFFER == TRUE) || defined(__DOXIGEN__)
|
||||
/**
|
||||
* @brief List of the allocated objects.
|
||||
* @brief List of the registered objects.
|
||||
*/
|
||||
dyn_list_t obj_list;
|
||||
#endif /* CH_CFG_FACTORY_GENERIC_BUFFER = TRUE */
|
||||
/**
|
||||
* @brief Pool of the available registered objects.
|
||||
*/
|
||||
memory_pool_t obj_pool;
|
||||
#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXIGEN__)
|
||||
/**
|
||||
* @brief List of the allocated buffer objects.
|
||||
*/
|
||||
dyn_list_t buf_list;
|
||||
#endif /* CH_CFG_FACTORY_GENERIC_BUFFERS = TRUE */
|
||||
#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__)
|
||||
/**
|
||||
* @brief List of the allocated semaphores.
|
||||
|
@ -194,9 +225,13 @@ objects_factory_t ch_factory;
|
|||
extern "C" {
|
||||
#endif
|
||||
void _factory_init(void);
|
||||
// dyn_registered_object_t *chFactoryRegisterObject(const char *name,
|
||||
// void *objp);
|
||||
#if (CH_CFG_FACTORY_GENERIC_BUFFER == TRUE) || defined(__DOXIGEN__)
|
||||
#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXIGEN__)
|
||||
registered_object_t *chFactoryRegisterObject(const char *name,
|
||||
void *objp);
|
||||
registered_object_t *chFactoryFindObject(const char *name);
|
||||
void chFactoryReleaseObject(registered_object_t *rop);
|
||||
#endif
|
||||
#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXIGEN__)
|
||||
dyn_buffer_t *chFactoryCreateBuffer(const char *name, size_t size);
|
||||
dyn_buffer_t *chFactoryFindBuffer(const char *name);
|
||||
void chFactoryReleaseBuffer(dyn_buffer_t *dbp);
|
||||
|
@ -231,7 +266,7 @@ static inline dyn_element_t *chFactoryDuplicateReferenceI(dyn_element_t *dep) {
|
|||
return dep;
|
||||
}
|
||||
|
||||
#if (CH_CFG_FACTORY_GENERIC_BUFFER == TRUE) || defined(__DOXIGEN__)
|
||||
#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXIGEN__)
|
||||
/**
|
||||
* @brief Returns the size of a generic dynamic buffer object.
|
||||
*
|
||||
|
|
|
@ -19,11 +19,12 @@
|
|||
|
||||
/**
|
||||
* @file chfactory.c
|
||||
* @brief ChibiOS objects factory code.
|
||||
* @brief ChibiOS objects factory and registry code.
|
||||
*
|
||||
* @addtogroup objects_factory
|
||||
* @details The object factory is a subsystem that allows to:
|
||||
* - Create objects and assign them a name.
|
||||
* - Register static objects by name.
|
||||
* - Dynamically create objects and assign them a name.
|
||||
* - Retrieve existing objects by name.
|
||||
* - Free objects by reference.
|
||||
* .
|
||||
|
@ -77,7 +78,7 @@ 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) {
|
||||
static dyn_element_t *dyn_list_find(const char *name, dyn_list_t *dlp) {
|
||||
dyn_element_t *p = dlp->next;
|
||||
|
||||
while (p != (dyn_element_t *)dlp) {
|
||||
|
@ -87,10 +88,13 @@ static dyn_element_t *dyn_list_find(dyn_list_t *dlp, const char *name) {
|
|||
p = p->next;
|
||||
}
|
||||
|
||||
chDbgAssert(true, "invalid reference passed");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static dyn_element_t *dyn_list_unlink(dyn_list_t *dlp, dyn_element_t *element) {
|
||||
static dyn_element_t *dyn_list_unlink(dyn_element_t *element,
|
||||
dyn_list_t *dlp) {
|
||||
dyn_element_t *prev = (dyn_element_t *)dlp;
|
||||
|
||||
/* Scanning the list.*/
|
||||
|
@ -108,6 +112,114 @@ static dyn_element_t *dyn_list_unlink(dyn_list_t *dlp, dyn_element_t *element) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if (CH_FACTORY_REQUIRES_HEAP == TRUE) || defined(__DOXYGEN__)
|
||||
static dyn_element_t *dyn_create_object_heap(const char *name,
|
||||
dyn_list_t *dlp,
|
||||
size_t size) {
|
||||
dyn_element_t *dep;
|
||||
|
||||
chDbgCheck(name != NULL);
|
||||
|
||||
/* Checking if an object with this name has already been created.*/
|
||||
dep = dyn_list_find(name, dlp);
|
||||
if (dep != NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocating space for the new buffer object.*/
|
||||
dep = (dyn_element_t *)chHeapAlloc(NULL, size);
|
||||
if (dep) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initializing object list element.*/
|
||||
strncpy(dep->name, name, CH_CFG_FACTORY_MAX_NAMES_LENGHT);
|
||||
dep->refs = 1U;
|
||||
dep->next = dlp->next;
|
||||
|
||||
/* Updating factory list.*/
|
||||
dlp->next = dep;
|
||||
|
||||
return dep;
|
||||
}
|
||||
|
||||
static void dyn_release_object_heap(dyn_element_t *dep,
|
||||
dyn_list_t *dlp) {
|
||||
|
||||
chDbgCheck(dep != NULL);
|
||||
chDbgAssert(dep->refs > 0U, "invalid references number");
|
||||
|
||||
dep = dyn_list_unlink(dep, dlp);
|
||||
|
||||
dep->refs--;
|
||||
if (dep->refs == 0U) {
|
||||
chHeapFree((void *)dep);
|
||||
}
|
||||
}
|
||||
#endif /* CH_FACTORY_REQUIRES_HEAP == TRUE */
|
||||
|
||||
#if (CH_FACTORY_REQUIRES_POOLS == TRUE) || defined(__DOXYGEN__)
|
||||
static dyn_element_t *dyn_create_object_pool(const char *name,
|
||||
dyn_list_t *dlp,
|
||||
memory_pool_t *mp) {
|
||||
dyn_element_t *dep;
|
||||
|
||||
chDbgCheck(name != NULL);
|
||||
|
||||
/* Checking if an object object with this name has already been created.*/
|
||||
dep = dyn_list_find(name, dlp);
|
||||
if (dep != NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocating space for the new object.*/
|
||||
dep = (dyn_element_t *)chPoolAlloc(mp);
|
||||
if (dep == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initializing object list element.*/
|
||||
strncpy(dep->name, name, CH_CFG_FACTORY_MAX_NAMES_LENGHT);
|
||||
dep->refs = 1U;
|
||||
dep->next = ch_factory.sem_list.next;
|
||||
|
||||
/* Updating factory list.*/
|
||||
dlp->next = (dyn_element_t *)dep;
|
||||
|
||||
return dep;
|
||||
}
|
||||
|
||||
static void dyn_release_object_pool(dyn_element_t *dep,
|
||||
dyn_list_t *dlp,
|
||||
memory_pool_t *mp) {
|
||||
|
||||
chDbgCheck(dep != NULL);
|
||||
chDbgAssert(dep->refs > 0U, "invalid references number");
|
||||
|
||||
dep = dyn_list_unlink(dep, dlp);
|
||||
|
||||
dep->refs--;
|
||||
if (dep->refs == 0U) {
|
||||
chPoolFree(mp, (void *)dep);
|
||||
}
|
||||
}
|
||||
#endif /* CH_FACTORY_REQUIRES_POOLS == TRUE */
|
||||
|
||||
static dyn_element_t *dyn_find_object(const char *name, dyn_list_t *dlp) {
|
||||
dyn_element_t *dep;
|
||||
|
||||
chDbgCheck(name != NULL);
|
||||
|
||||
/* Checking if an object with this name has already been created.*/
|
||||
dep = dyn_list_find(name, dlp);
|
||||
if (dep != NULL) {
|
||||
/* Increasing references counter.*/
|
||||
dep->refs++;
|
||||
}
|
||||
|
||||
return dep;
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
@ -119,8 +231,14 @@ static dyn_element_t *dyn_list_unlink(dyn_list_t *dlp, dyn_element_t *element) {
|
|||
*/
|
||||
void _factory_init(void) {
|
||||
|
||||
#if CH_CFG_FACTORY_GENERIC_BUFFER == TRUE
|
||||
#if CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE
|
||||
dyn_list_init(&ch_factory.obj_list);
|
||||
chPoolObjectInit(&ch_factory.obj_pool,
|
||||
sizeof (registered_object_t),
|
||||
chCoreAllocAlignedI);
|
||||
#endif
|
||||
#if CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE
|
||||
dyn_list_init(&ch_factory.buf_list);
|
||||
#endif
|
||||
#if CH_CFG_FACTORY_SEMAPHORES == TRUE
|
||||
dyn_list_init(&ch_factory.sem_list);
|
||||
|
@ -130,88 +248,138 @@ void _factory_init(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
#if (CH_CFG_FACTORY_GENERIC_BUFFER == TRUE) || defined(__DOXIGEN__)
|
||||
#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXIGEN__)
|
||||
/**
|
||||
* @brief Registers a generic object.
|
||||
* @post A reference to the registered object is returned and the
|
||||
* reference counter is initialized to one.
|
||||
*
|
||||
* @param[in] name name to be assigned to the registered object
|
||||
* @param[in] objp pointer to the object to be registered
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
registered_object_t *chFactoryRegisterObject(const char *name,
|
||||
void *objp) {
|
||||
registered_object_t *rop;
|
||||
|
||||
chSysLock();
|
||||
|
||||
rop = (registered_object_t *)dyn_create_object_pool(name,
|
||||
&ch_factory.obj_list,
|
||||
&ch_factory.obj_pool);
|
||||
if (rop != NULL) {
|
||||
/* Initializing registered object data.*/
|
||||
rop->objp = objp;
|
||||
}
|
||||
|
||||
chSysUnlock();
|
||||
|
||||
return rop;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves a registered object.
|
||||
* @post A reference to the registered object is returned with the
|
||||
* reference counter increased by one.
|
||||
*
|
||||
* @param[in] name name of the registered object
|
||||
*
|
||||
* @return The reference to the found registered object.
|
||||
* @retval NULL if a registered object with the specified name
|
||||
* does not exist.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
registered_object_t *chFactoryFindObject(const char *name) {
|
||||
registered_object_t *rop;
|
||||
|
||||
chSysLock();
|
||||
|
||||
rop = (registered_object_t *)dyn_find_object(name, &ch_factory.obj_list);
|
||||
|
||||
chSysUnlock();
|
||||
|
||||
return rop;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Releases a registered object.
|
||||
* @details The reference counter of the registered object is decreased
|
||||
* by one, if reaches zero then the registered object memory
|
||||
* is freed.
|
||||
* @note The object itself is not freed, it could be static, only the
|
||||
* allocated list element is freed.
|
||||
*
|
||||
* @param[in] rop registered object reference
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void chFactoryReleaseObject(registered_object_t *rop){
|
||||
|
||||
chSysLock();
|
||||
|
||||
dyn_release_object_pool(&rop->element,
|
||||
&ch_factory.obj_list,
|
||||
&ch_factory.obj_pool);
|
||||
|
||||
chSysUnlock();
|
||||
}
|
||||
#endif /* CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE */
|
||||
|
||||
#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXIGEN__)
|
||||
/**
|
||||
* @brief Creates a generic dynamic buffer object.
|
||||
* @post A reference to the buffer object is returned and the reference
|
||||
* counter is initialized to one.
|
||||
* @post The buffer object is zero filled.
|
||||
* @post A reference to the dynamic buffer object is returned and the
|
||||
* reference counter is initialized to one.
|
||||
* @post The dynamic buffer object is filled with zeros.
|
||||
*
|
||||
* @param[in] name name to be assigned to the new buffer object
|
||||
* @param[in] size payload size of the buffer object to be created
|
||||
* @param[in] name name to be assigned to the new dynamic buffer object
|
||||
* @param[in] size payload size of the dynamic buffer object to be created
|
||||
*
|
||||
* @return The reference to the created buffer object.
|
||||
* @retval NULL if the buffer object cannot be allocated or a buffer
|
||||
* object with the same name exists.
|
||||
* @return The reference to the created dynamic buffer object.
|
||||
* @retval NULL if the dynamic buffer object cannot be allocated or
|
||||
* a dynamic buffer object with the same name exists.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
dyn_buffer_t *chFactoryCreateBuffer(const char *name, size_t size) {
|
||||
dyn_buffer_t *dbp;
|
||||
|
||||
chDbgCheck(name != NULL);
|
||||
|
||||
chSysLock();
|
||||
|
||||
/* Checking if a buffer object with this name has already been created.*/
|
||||
dbp = (dyn_buffer_t *)dyn_list_find(&ch_factory.obj_list, name);
|
||||
dbp = (dyn_buffer_t *)dyn_create_object_heap(name,
|
||||
&ch_factory.buf_list,
|
||||
size);
|
||||
if (dbp != NULL) {
|
||||
/* Object exists, error.*/
|
||||
chSysUnlock();
|
||||
return NULL;
|
||||
/* Initializing buffer object data.*/
|
||||
memset((void *)dbp->buffer, 0, size);
|
||||
}
|
||||
|
||||
/* Allocating space for the new buffer object.*/
|
||||
dbp = chHeapAlloc(NULL, size);
|
||||
if (dbp == NULL) {
|
||||
chSysUnlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initializing buffer object data and metadata.*/
|
||||
strncpy(dbp->element.name, name, CH_CFG_FACTORY_MAX_NAMES_LENGHT);
|
||||
dbp->element.refs = 1;
|
||||
dbp->element.next = ch_factory.obj_list.next;
|
||||
memset((void *)dbp->buffer, 0, size);
|
||||
|
||||
/* Updating factory list.*/
|
||||
ch_factory.obj_list.next = (dyn_element_t *)dbp;
|
||||
|
||||
chSysUnlock();
|
||||
|
||||
return dbp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves a generic dynamic buffer object.
|
||||
* @post A reference to the buffer object is returned with the reference
|
||||
* counter increased by one.
|
||||
* @brief Retrieves a dynamic buffer object.
|
||||
* @post A reference to the dynamic buffer object is returned with the
|
||||
* reference counter increased by one.
|
||||
*
|
||||
* @param[in] name name to be assigned to the new buffer object
|
||||
* @param[in] name name of the dynamic buffer object
|
||||
*
|
||||
* @return The reference to the found buffer object.
|
||||
* @retval NULL if a buffer object with the specified name name does
|
||||
* not exist.
|
||||
* @return The reference to the found dynamic buffer object.
|
||||
* @retval NULL if a dynamic buffer object with the specified name
|
||||
* does not exist.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
dyn_buffer_t *chFactoryFindBuffer(const char *name) {
|
||||
dyn_buffer_t *dbp;
|
||||
|
||||
chDbgCheck(name != NULL);
|
||||
|
||||
chSysLock();
|
||||
|
||||
/* Checking if a buffer object with this name has already been created.*/
|
||||
dbp = (dyn_buffer_t *)dyn_list_find(&ch_factory.obj_list, name);
|
||||
if (dbp == NULL) {
|
||||
/* The buffer object does not exists, error.*/
|
||||
chSysUnlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Increasing references counter.*/
|
||||
dbp->element.refs += 1;
|
||||
dbp = (dyn_buffer_t *)dyn_find_object(name, &ch_factory.buf_list);
|
||||
|
||||
chSysUnlock();
|
||||
|
||||
|
@ -220,117 +388,77 @@ dyn_buffer_t *chFactoryFindBuffer(const char *name) {
|
|||
|
||||
/**
|
||||
* @brief Releases a generic dynamic buffer object.
|
||||
* @details The reference counter of the buffer object is decreased by one, if
|
||||
* reaches zero then the buffer object memory is freed.
|
||||
* @details The reference counter of the dynamic buffer object is decreased
|
||||
* by one, if reaches zero then the dynamic buffer object memory
|
||||
* is freed.
|
||||
*
|
||||
* @param[in] dbp generic buffer object reference
|
||||
* @param[in] dbp dynamic buffer object reference
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void chFactoryReleaseBuffer(dyn_buffer_t *dbp) {
|
||||
|
||||
chDbgCheck(dbp != NULL);
|
||||
|
||||
chSysLock();
|
||||
|
||||
chDbgAssert(dbp->element.refs > 0U, "invalid references number");
|
||||
|
||||
dbp = (dyn_buffer_t *)dyn_list_unlink(&ch_factory.obj_list,
|
||||
&dbp->element);
|
||||
|
||||
chDbgAssert(dbp != NULL, "invalid reference passed");
|
||||
|
||||
dbp->element.refs--;
|
||||
if (dbp->element.refs == 0) {
|
||||
chHeapFree((void *)dbp);
|
||||
}
|
||||
dyn_release_object_heap(&dbp->element, &ch_factory.buf_list);
|
||||
|
||||
chSysUnlock();
|
||||
}
|
||||
#endif /* CH_CFG_FACTORY_GENERIC_BUFFER = TRUE */
|
||||
#endif /* CH_CFG_FACTORY_GENERIC_BUFFERS = TRUE */
|
||||
|
||||
#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__)
|
||||
/**
|
||||
* @brief Creates a dynamic semaphore object.
|
||||
* @post A reference to the semaphore object is returned and the reference
|
||||
* counter is initialized to one.
|
||||
* @post The semaphore object is initialized and ready to use.
|
||||
* @post A reference to the dynamic semaphore object is returned and the
|
||||
* reference counter is initialized to one.
|
||||
* @post The dynamic semaphore object is initialized and ready to use.
|
||||
*
|
||||
* @param[in] name name to be assigned to the new semaphore object
|
||||
* @param[in] n semaphore object counter initialization value
|
||||
* @param[in] name name to be assigned to the new dynamic semaphore object
|
||||
* @param[in] n dynamic semaphore object counter initialization value
|
||||
*
|
||||
* @return The reference to the created semaphore object.
|
||||
* @retval NULL if the semaphore object cannot be allocated or a
|
||||
* semaphore with the same name exists.
|
||||
* @return The reference to the created dynamic semaphore object.
|
||||
* @retval NULL if the dynamic semaphore object cannot be allocated or
|
||||
* a dynamic semaphore with the same name exists.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
dyn_semaphore_t *chFactoryCreateSemaphore(const char *name, cnt_t n) {
|
||||
dyn_semaphore_t *dsp;
|
||||
|
||||
chDbgCheck(name != NULL);
|
||||
|
||||
chSysLock();
|
||||
|
||||
/* Checking if a semaphore object with this name has already been created.*/
|
||||
dsp = (dyn_semaphore_t *)dyn_list_find(&ch_factory.sem_list, name);
|
||||
dsp = (dyn_semaphore_t *)dyn_create_object_pool(name,
|
||||
&ch_factory.sem_list,
|
||||
&ch_factory.sem_pool);
|
||||
if (dsp != NULL) {
|
||||
/* The semaphore object exists, error.*/
|
||||
chSysUnlock();
|
||||
return NULL;
|
||||
/* Initializing semaphore object dataa.*/
|
||||
chSemObjectInit(&dsp->sem, n);
|
||||
}
|
||||
|
||||
/* Allocating space for the new semaphore object.*/
|
||||
dsp = chCoreAlloc(sizeof (dyn_semaphore_t));
|
||||
if (dsp == NULL) {
|
||||
chSysUnlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initializing semaphore object data and metadata.*/
|
||||
strncpy(dsp->element.name, name, CH_CFG_FACTORY_MAX_NAMES_LENGHT);
|
||||
dsp->element.refs = 1;
|
||||
dsp->element.next = ch_factory.obj_list.next;
|
||||
chSemObjectInit(&dsp->sem, n);
|
||||
|
||||
/* Updating factory list.*/
|
||||
ch_factory.obj_list.next = (dyn_element_t *)dsp;
|
||||
|
||||
chSysUnlock();
|
||||
|
||||
return dsp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves a generic dynamic semaphore object.
|
||||
* @post A reference to the semaphore object is returned with the reference
|
||||
* counter increased by one.
|
||||
* @brief Retrieves a dynamic semaphore object.
|
||||
* @post A reference to the dynamic semaphore object is returned with the
|
||||
* reference counter increased by one.
|
||||
*
|
||||
* @param[in] name name to be assigned to the new semaphore object
|
||||
* @param[in] name name of the dynamic semaphore object
|
||||
*
|
||||
* @return The reference to the found semaphore object.
|
||||
* @retval NULL if a semaphore object with the specified name name does
|
||||
* not exist.
|
||||
* @return The reference to the found dynamic semaphore object.
|
||||
* @retval NULL if a dynamic semaphore object with the specified name
|
||||
* does not exist.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
dyn_semaphore_t *chFactoryFindSemaphore(const char *name) {
|
||||
dyn_semaphore_t *dsp;
|
||||
|
||||
chDbgCheck(name != NULL);
|
||||
|
||||
chSysLock();
|
||||
|
||||
/* Checking if a semaphore object with this name has already been created.*/
|
||||
dsp = (dyn_semaphore_t *)dyn_list_find(&ch_factory.obj_list, name);
|
||||
if (dsp == NULL) {
|
||||
/* The semaphore object does not exists, error.*/
|
||||
chSysUnlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Increasing references counter.*/
|
||||
dsp->element.refs += 1;
|
||||
dsp = (dyn_semaphore_t *)dyn_find_object(name, &ch_factory.sem_list);
|
||||
|
||||
chSysUnlock();
|
||||
|
||||
|
@ -338,31 +466,22 @@ dyn_semaphore_t *chFactoryFindSemaphore(const char *name) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Releases a semaphore dynamic object.
|
||||
* @details The reference counter of the semaphore object is decreased by one,
|
||||
* if reaches zero then the semaphore object memory is freed.
|
||||
* @brief Releases a dynamic semaphore object.
|
||||
* @details The reference counter of the dynamic semaphore object is decreased
|
||||
* by one, if reaches zero then the dynamic semaphore object memory
|
||||
* is freed.
|
||||
*
|
||||
* @param[in] dsp semaphore object reference
|
||||
* @param[in] dsp dynamic semaphore object reference
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void chFactoryReleaseSemaphore(dyn_semaphore_t *dsp) {
|
||||
|
||||
chDbgCheck(dsp != NULL);
|
||||
|
||||
chSysLock();
|
||||
|
||||
chDbgAssert(dsp->element.refs > 0U, "invalid references number");
|
||||
|
||||
dsp = (dyn_semaphore_t *)dyn_list_unlink(&ch_factory.sem_list,
|
||||
&dsp->element);
|
||||
|
||||
chDbgAssert(dsp != NULL, "invalid reference passed");
|
||||
|
||||
dsp->element.refs--;
|
||||
if (dsp->element.refs == 0) {
|
||||
chPoolFree(&ch_factory.sem_pool, (void *)dsp);
|
||||
}
|
||||
dyn_release_object_pool(&dsp->element,
|
||||
&ch_factory.sem_list,
|
||||
&ch_factory.sem_pool);
|
||||
|
||||
chSysUnlock();
|
||||
}
|
||||
|
|
|
@ -54,6 +54,9 @@ endif
|
|||
ifneq ($(findstring CH_CFG_USE_MEMPOOLS TRUE,$(CHCONF)),)
|
||||
KERNSRC += $(CHIBIOS)/os/common/oslib/src/chmempools.c
|
||||
endif
|
||||
ifneq ($(findstring CH_CFG_USE_FACTORY TRUE,$(CHCONF)),)
|
||||
KERNSRC += $(CHIBIOS)/os/common/oslib/src/chfactory.c
|
||||
endif
|
||||
else
|
||||
KERNSRC := $(CHIBIOS)/os/rt/src/chsys.c \
|
||||
$(CHIBIOS)/os/rt/src/chdebug.c \
|
||||
|
|
Loading…
Reference in New Issue