More factory code.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10714 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
0a24112ccd
commit
9f30d457c0
|
@ -131,7 +131,7 @@ typedef struct ch_dyn_object {
|
|||
/**
|
||||
* @brief List element of the dynamic object.
|
||||
*/
|
||||
dyn_element_t list;
|
||||
dyn_element_t element;
|
||||
/**
|
||||
* @brief Physical objects.
|
||||
* @note This requires C99.
|
||||
|
@ -148,7 +148,7 @@ typedef struct ch_dyn_semaphore {
|
|||
/**
|
||||
* @brief List element of the dynamic semaphore.
|
||||
*/
|
||||
dyn_element_t list;
|
||||
dyn_element_t element;
|
||||
/**
|
||||
* @brief Physical semaphore.
|
||||
*/
|
||||
|
@ -213,6 +213,22 @@ extern "C" {
|
|||
/* Module inline functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Duplicates an object reference.
|
||||
*
|
||||
* @param[in] dep pointer to the element field of the object
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
static inline dyn_element_t *chFactoryDuplicateReferenceI(dyn_element_t *dep) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
|
||||
dep->refs++;
|
||||
|
||||
return dep;
|
||||
}
|
||||
|
||||
#endif /* CH_CFG_USE_FACTORY == TRUE */
|
||||
|
||||
#endif /* CHFACTORY_H */
|
||||
|
|
|
@ -90,6 +90,24 @@ static dyn_element_t *dyn_list_find(dyn_list_t *dlp, const char *name) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static dyn_element_t *dyn_list_unlink(dyn_list_t *dlp, dyn_element_t *element) {
|
||||
dyn_element_t *prev = (dyn_element_t *)dlp;
|
||||
|
||||
/* Scanning the list.*/
|
||||
while (prev->next != (dyn_element_t *)dlp) {
|
||||
if (prev->next == element) {
|
||||
/* Found.*/
|
||||
prev->next = element->next;
|
||||
return element;
|
||||
}
|
||||
|
||||
/* Next element in the list.*/
|
||||
prev = prev->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
@ -114,7 +132,7 @@ void _factory_init(void) {
|
|||
|
||||
#if (CH_CFG_FACTORY_GENERIC == TRUE) || defined(__DOXIGEN__)
|
||||
/**
|
||||
* @brief Allocates a generic dynamic object.
|
||||
* @brief Creates 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.
|
||||
|
@ -125,10 +143,14 @@ void _factory_init(void) {
|
|||
* @return The reference to the created object.
|
||||
* @retval NULL if the object cannot be allocated or an object with
|
||||
* the same name exists.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
dyn_object_t *chFactoryCreateObject(const char *name, size_t size) {
|
||||
dyn_object_t *dop;
|
||||
|
||||
chDbgCheck(name != NULL);
|
||||
|
||||
chSysLock();
|
||||
|
||||
/* Checking if an object with this name has already been created.*/
|
||||
|
@ -139,6 +161,7 @@ dyn_object_t *chFactoryCreateObject(const char *name, size_t size) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocating space for the new object.*/
|
||||
dop = chHeapAlloc(NULL, size);
|
||||
if (dop == NULL) {
|
||||
chSysUnlock();
|
||||
|
@ -146,9 +169,9 @@ dyn_object_t *chFactoryCreateObject(const char *name, size_t size) {
|
|||
}
|
||||
|
||||
/* 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;
|
||||
strncpy(dop->element.name, name, CH_CFG_FACTORY_MAX_NAMES_LENGHT);
|
||||
dop->element.refs = 1;
|
||||
dop->element.next = ch_factory.obj_list.next;
|
||||
memset((void *)dop->obj, 0, size);
|
||||
|
||||
/* Updating factory list.*/
|
||||
|
@ -159,12 +182,70 @@ dyn_object_t *chFactoryCreateObject(const char *name, size_t size) {
|
|||
return dop;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves a generic dynamic object.
|
||||
* @post A reference to the object is returned with the reference counter
|
||||
* increased by one.
|
||||
*
|
||||
* @param[in] name name to be assigned to the new object
|
||||
*
|
||||
* @return The reference to the found object.
|
||||
* @retval NULL if an object with the specified name name does
|
||||
* not exist.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
dyn_object_t *chFactoryFindObject(const char *name) {
|
||||
dyn_object_t *dop;
|
||||
|
||||
chDbgCheck(name != NULL);
|
||||
|
||||
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 does not exists, error.*/
|
||||
chSysUnlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Increasing references counter.*/
|
||||
dop->element.refs += 1;
|
||||
|
||||
chSysUnlock();
|
||||
|
||||
return dop;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Releases a generic dynamic object.
|
||||
* @details The reference counter of the object is decreased by one, if
|
||||
* reaches zero then the object memory is freed.
|
||||
*
|
||||
* @param[in] dop generic object reference
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void chFactoryReleaseObject(dyn_object_t *dop) {
|
||||
|
||||
chDbgCheck(dop != NULL);
|
||||
|
||||
chSysLock();
|
||||
|
||||
chDbgAssert(dop->element.refs > 0U, "invalid references number");
|
||||
|
||||
dop = (dyn_object_t *)dyn_list_unlink(&ch_factory.obj_list,
|
||||
&dop->element);
|
||||
|
||||
chDbgAssert(dop != NULL, "invalid reference passed");
|
||||
|
||||
dop->element.refs--;
|
||||
if (dop->element.refs == 0) {
|
||||
chHeapFree((void *)dop);
|
||||
}
|
||||
|
||||
chSysUnlock();
|
||||
}
|
||||
|
||||
size_t chFactoryGetObjectSize(dyn_object_t *dop) {
|
||||
|
@ -174,16 +255,121 @@ size_t chFactoryGetObjectSize(dyn_object_t *dop) {
|
|||
#endif /* CH_CFG_FACTORY_GENERIC = TRUE */
|
||||
|
||||
#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__)
|
||||
/**
|
||||
* @brief Creates a dynamic semaphore object.
|
||||
* @post A reference to the semaphore is returned and the reference counter
|
||||
* is initialized to one.
|
||||
* @post The semaphore object is initialized and ready to use.
|
||||
*
|
||||
* @param[in] name name to be assigned to the new semaphore object
|
||||
* @param[in] n semaphore counter initialization value
|
||||
*
|
||||
* @return The reference to the created semaphore object.
|
||||
* @retval NULL if the semaphore cannot be allocated or an 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 an object with this name has already been created.*/
|
||||
dsp = (dyn_semaphore_t *)dyn_list_find(&ch_factory.sem_list, name);
|
||||
if (dsp != NULL) {
|
||||
/* Semaphore exists, error.*/
|
||||
chSysUnlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocating space for the new object.*/
|
||||
dsp = chCoreAlloc(sizeof (dyn_semaphore_t));
|
||||
if (dsp == NULL) {
|
||||
chSysUnlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initializing 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 is returned with the reference counter
|
||||
* increased by one.
|
||||
*
|
||||
* @param[in] name name to be assigned to the new semaphore object
|
||||
*
|
||||
* @return The reference to the found semaphore object.
|
||||
* @retval NULL if a semaphore with the specified name name does
|
||||
* not exist.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
dyn_semaphore_t *chFactoryFindSemaphore(const char *name) {
|
||||
dyn_semaphore_t *dsp;
|
||||
|
||||
chDbgCheck(name != NULL);
|
||||
|
||||
chSysLock();
|
||||
|
||||
/* Checking if an object with this name has already been created.*/
|
||||
dsp = (dyn_semaphore_t *)dyn_list_find(&ch_factory.obj_list, name);
|
||||
if (dsp == NULL) {
|
||||
/* Object does not exists, error.*/
|
||||
chSysUnlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Increasing references counter.*/
|
||||
dsp->element.refs += 1;
|
||||
|
||||
chSysUnlock();
|
||||
|
||||
return dsp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Releases a semaphore dynamic object.
|
||||
* @details The reference counter of the semaphore is decreased by one, if
|
||||
* reaches zero then the semaphore memory is freed.
|
||||
*
|
||||
* @param[in] dsp 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);
|
||||
}
|
||||
|
||||
chSysUnlock();
|
||||
}
|
||||
#endif /* CH_CFG_FACTORY_SEMAPHORES = TRUE */
|
||||
|
||||
|
|
Loading…
Reference in New Issue