From db364ffee4efe5de1d2b2a2ff07c416b3caa09ad Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Fri, 23 Aug 2019 07:40:15 +0000 Subject: [PATCH] More cache code, small fix in a comment. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12951 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/oslib/include/chobjcaches.h | 63 ++++++++--- os/oslib/src/chobjcaches.c | 190 +++++++++++++++++++++++++++++++++ os/oslib/src/chpipes.c | 2 +- 3 files changed, 238 insertions(+), 17 deletions(-) create mode 100644 os/oslib/src/chobjcaches.c diff --git a/os/oslib/include/chobjcaches.h b/os/oslib/include/chobjcaches.h index 3dc47c8d9..67f5e9527 100644 --- a/os/oslib/include/chobjcaches.h +++ b/os/oslib/include/chobjcaches.h @@ -1,5 +1,5 @@ /* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + ChibiOS - Copyright (C) 2006..2019 Giovanni Di Sirio. This file is part of ChibiOS. @@ -18,10 +18,10 @@ */ /** - * @file chcaches.h - * @brief Caches macros and structures. + * @file chobjcaches.h + * @brief Objects Caches macros and structures. * - * @addtogroup oslib_chaches + * @addtogroup oslib_objchaches * @{ */ @@ -34,6 +34,20 @@ /* Module constants. */ /*===========================================================================*/ +/** + * @name Cached objects flags + * @{ + */ +#define OC_FLAG_INVALID 0x00000001U +#define OC_FLAG_CACHEHIT 0x00000002U +#define OC_FLAG_ERROR 0x00000004U +/** @} */ + +/** + * @brief Identifier for an invalid group. + */ +#define OC_NO_GROUP 0xFFFFFFFFU + /*===========================================================================*/ /* Module pre-compile time settings. */ /*===========================================================================*/ @@ -149,27 +163,45 @@ struct ch_oc_object { */ oc_flags_t obj_flags; /** - * @brief Data part of the object. + * @brief Pointer to the data part of the object. + * @note This pointer must be initialized outside this module after + * calling @p chCacheObjectInit() which sets it to @p NULL. */ - uint8_t data[]; + void *data; }; /** * @brief Type of a cache object. */ typedef struct { + /** + * @brief Number of elements in the hash table. + */ + size_t hashn; + /** + * @brief Pointer to the hash table. + */ + oc_hash_header_t *hashp; + /** + * @brief Number of elements in the objects table. + */ + size_t objn; + /** + * @brief Pointer to the objects table. + */ + oc_object_t *objp; /** * @brief LRU list header. */ oc_lru_header_t lru; + /** + * @brief Semaphore for cache access. + */ + semaphore_t cache_sem; /** * @brief Semaphore for LRU access. */ semaphore_t lru_sem; - /** - * @brief Size of the cached objects. - */ - size_t obj_size; /** * @brief Reader functions for cached objects. */ @@ -192,16 +224,15 @@ typedef struct { extern "C" { #endif void chCacheObjectInit(objects_cache_t *ocp, - size_t hashn, + ucnt_t hashn, oc_hash_header_t *hashp, - size_t objn, + ucnt_t objn, oc_object_t *objp, oc_readf_t readf, oc_writef_t writef); - msg_t chCacheGetObject(objects_cache_t *ocp, - uint32_t group, - uint32_t key, - oc_object_t **objpp); + oc_object_t *chCacheGetObject(objects_cache_t *ocp, + uint32_t group, + uint32_t key); void chCacheReleaseObject(objects_cache_t *ocp, oc_object_t *objp); #ifdef __cplusplus diff --git a/os/oslib/src/chobjcaches.c b/os/oslib/src/chobjcaches.c new file mode 100644 index 000000000..b6afb491d --- /dev/null +++ b/os/oslib/src/chobjcaches.c @@ -0,0 +1,190 @@ +/* + ChibiOS - Copyright (C) 2006..2019 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 chobjcaches.c + * @brief Objects Caches code. + * @details Byte pipes. + *

Operation mode

+ * A pipe is an asynchronous communication mechanism.
+ * Operations defined for mailboxes: + * - Write: Writes a buffer of data in the pipe in FIFO order. + * - Read: A buffer of data is read from the read and removed. + * - Reset: The pipe is emptied and all the stored data + * is lost. + * . + * @pre In order to use the pipes APIs the @p CH_CFG_USE_PIPES + * option must be enabled in @p chconf.h. + * @note Compatible with RT and NIL. + * + * @addtogroup oslib_objchaches + * @{ + */ + +#include "ch.h" + +#if (CH_CFG_USE_OBJ_CACHES == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/* Default hash function.*/ +#if !defined(OC_HASH_FUNCTION) || defined(__DOXYGEN__) +#define OC_HASH_FUNCTION(ocp, group, key) \ + (((unsigned)(group) + (unsigned)(key)) & ((unsigned)(ocp)->hashn - 1U)) +#endif + +/* Insertion into an hash slot list.*/ +#define HASH_INSERT(ocp, objp, group, key) { \ + oc_hash_header_t *hhp; \ + (hhp) = &(ocp)->hashp[OC_HASH_FUNCTION(ocp, group, key)]; \ + (objp)->hash_next = (hhp)->hash_next; \ + (objp)->hash_prev = (oc_object_t *)(hhp); \ + (hhp)->hash_next->hash_prev = (objp); \ + (hhp)->hash_next = (objp); \ +} + +/* Insertion on LRU head (newer objects).*/ +#define LRU_INSERT_HEAD(ocp, objp) { \ + (objp)->lru_next = (ocp)->lru.lru_next; \ + (objp)->lru_prev = (oc_object_t *)&(ocp)->lru; \ + (ocp)->lru.lru_next->lru_prev = (objp); \ + (ocp)->lru.lru_next = (objp); \ +} + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +static oc_object_t *oc_hash_get(objects_cache_t *ocp, + uint32_t group, + uint32_t key) { + +} + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes a @p objects_cache_t object. + * + * @param[out] ocp pointer to the @p objects_cache_t structure to be + * initialized + * @param[in] hashn number of elements in the hash table array, must be + * a power of two and not lower than @p objn + * @param[in] hashp pointer to the hash table as an array of + * @p oc_hash_header_t + * @param[in] objn number of elements in the objects table array + * @param[in] hashp pointer to the hash objects as an array of + * @p oc_object_t + * @param[in] readf pointer to an object reader function + * @param[in] writef pointer to an object writer function + * + * @init + */ +void chCacheObjectInit(objects_cache_t *ocp, + ucnt_t hashn, + oc_hash_header_t *hashp, + ucnt_t objn, + oc_object_t *objp, + oc_readf_t readf, + oc_writef_t writef) { + unsigned i; + + chDbgCheck((ocp != NULL) && (hashp != NULL) && (objp != NULL) && + (hashn & (hashn - 1U) == 0U) && + (objn > (size_t)0) && (hashn >= objn)); + + chSemObjectInit(&ocp->cache_sem, (cnt_t)1); + chSemObjectInit(&ocp->lru_sem, (cnt_t)objn); + ocp->hashn = hashn; + ocp->hashp = hashp; + ocp->objn = objn; + ocp->objp = objp; + ocp->readf = readf; + ocp->writef = writef; + ocp->lru.hash_next = NULL; + ocp->lru.hash_prev = NULL; + ocp->lru.lru_next = (oc_object_t *)&ocp->lru; + ocp->lru.lru_prev = (oc_object_t *)&ocp->lru; + + /* Hash headers initialization.*/ + while (hashp < &ocp->hashp[ocp->hashn]) { + hashp->hash_next = (oc_object_t *)hashp; + hashp->hash_prev = (oc_object_t *)hashp; + } + + /* Object headers initialization.*/ + while (objp < &ocp->objp[ocp->objn]) { + chSemObjectInit(&objp->obj_sem, (cnt_t)1); + HASH_INSERT(ocp, objp, OC_NO_GROUP, (uint32_t)i); + LRU_INSERT_HEAD(ocp, objp); + objp->obj_group = OC_NO_GROUP; + objp->obj_key = 0U; + objp->obj_flags = OC_FLAG_INVALID; + objp->data = NULL; + } +} + +/** + * @brief Retrieves an object from the cache. + * @note If the object is not in cache then the returned object does + * not specify the flag @p OC_FLAG_CACHEHIT meaning its data contains + * garbage and must be initialized. + * + * @param[in] ocp pointer to the @p objects_cache_t structure + * @param[in] group object group identifier + * @param[in] key object identifier within the group + * @return The pointer to the retrieved object. + * @retval NULL is a reserved value. + */ +oc_object_t *chCacheGetObject(objects_cache_t *ocp, + uint32_t group, + uint32_t key) { + +} + +/** + * @brief Releases an object into the cache. + * + * @param[in] ocp pointer to the @p objects_cache_t structure + * @param[in] objp pointer to the @p oc_object_t structure + */ +void chCacheReleaseObject(objects_cache_t *ocp, + oc_object_t *objp) { + +} + +#endif /* CH_CFG_USE_OBJ_CACHES == TRUE */ + +/** @} */ diff --git a/os/oslib/src/chpipes.c b/os/oslib/src/chpipes.c index 47c9dd892..12b1d3c61 100644 --- a/os/oslib/src/chpipes.c +++ b/os/oslib/src/chpipes.c @@ -383,6 +383,6 @@ size_t chPipeReadTimeout(pipe_t *pp, uint8_t *bp, return max - n; } -#endif /* CH_CFG_USE_MAILBOXES == TRUE */ +#endif /* CH_CFG_USE_PIPES == TRUE */ /** @} */