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
This commit is contained in:
parent
2f5eb6f313
commit
db364ffee4
|
@ -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.
|
This file is part of ChibiOS.
|
||||||
|
|
||||||
|
@ -18,10 +18,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file chcaches.h
|
* @file chobjcaches.h
|
||||||
* @brief Caches macros and structures.
|
* @brief Objects Caches macros and structures.
|
||||||
*
|
*
|
||||||
* @addtogroup oslib_chaches
|
* @addtogroup oslib_objchaches
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -34,6 +34,20 @@
|
||||||
/* Module constants. */
|
/* 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. */
|
/* Module pre-compile time settings. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -149,27 +163,45 @@ struct ch_oc_object {
|
||||||
*/
|
*/
|
||||||
oc_flags_t obj_flags;
|
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.
|
* @brief Type of a cache object.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
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.
|
* @brief LRU list header.
|
||||||
*/
|
*/
|
||||||
oc_lru_header_t lru;
|
oc_lru_header_t lru;
|
||||||
|
/**
|
||||||
|
* @brief Semaphore for cache access.
|
||||||
|
*/
|
||||||
|
semaphore_t cache_sem;
|
||||||
/**
|
/**
|
||||||
* @brief Semaphore for LRU access.
|
* @brief Semaphore for LRU access.
|
||||||
*/
|
*/
|
||||||
semaphore_t lru_sem;
|
semaphore_t lru_sem;
|
||||||
/**
|
|
||||||
* @brief Size of the cached objects.
|
|
||||||
*/
|
|
||||||
size_t obj_size;
|
|
||||||
/**
|
/**
|
||||||
* @brief Reader functions for cached objects.
|
* @brief Reader functions for cached objects.
|
||||||
*/
|
*/
|
||||||
|
@ -192,16 +224,15 @@ typedef struct {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void chCacheObjectInit(objects_cache_t *ocp,
|
void chCacheObjectInit(objects_cache_t *ocp,
|
||||||
size_t hashn,
|
ucnt_t hashn,
|
||||||
oc_hash_header_t *hashp,
|
oc_hash_header_t *hashp,
|
||||||
size_t objn,
|
ucnt_t objn,
|
||||||
oc_object_t *objp,
|
oc_object_t *objp,
|
||||||
oc_readf_t readf,
|
oc_readf_t readf,
|
||||||
oc_writef_t writef);
|
oc_writef_t writef);
|
||||||
msg_t chCacheGetObject(objects_cache_t *ocp,
|
oc_object_t *chCacheGetObject(objects_cache_t *ocp,
|
||||||
uint32_t group,
|
uint32_t group,
|
||||||
uint32_t key,
|
uint32_t key);
|
||||||
oc_object_t **objpp);
|
|
||||||
void chCacheReleaseObject(objects_cache_t *ocp,
|
void chCacheReleaseObject(objects_cache_t *ocp,
|
||||||
oc_object_t *objp);
|
oc_object_t *objp);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file chobjcaches.c
|
||||||
|
* @brief Objects Caches code.
|
||||||
|
* @details Byte pipes.
|
||||||
|
* <h2>Operation mode</h2>
|
||||||
|
* A pipe is an asynchronous communication mechanism.<br>
|
||||||
|
* Operations defined for mailboxes:
|
||||||
|
* - <b>Write</b>: Writes a buffer of data in the pipe in FIFO order.
|
||||||
|
* - <b>Read</b>: A buffer of data is read from the read and removed.
|
||||||
|
* - <b>Reset</b>: 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 */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -383,6 +383,6 @@ size_t chPipeReadTimeout(pipe_t *pp, uint8_t *bp,
|
||||||
return max - n;
|
return max - n;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CH_CFG_USE_MAILBOXES == TRUE */
|
#endif /* CH_CFG_USE_PIPES == TRUE */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
Loading…
Reference in New Issue