stos: ob: Add object cache groundwork
Signed-off-by: Chloe M. <chloe@mensia.org>
This commit is contained in:
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2026, Chloe M.
|
||||||
|
* Provided under the BSD-3 clause.
|
||||||
|
*
|
||||||
|
* Description: Object manager cache
|
||||||
|
* Author: Chloe M.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _OB_CACHE_H_
|
||||||
|
#define _OB_CACHE_H_ 1
|
||||||
|
|
||||||
|
#include <stdef.h>
|
||||||
|
#include <ob/object.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* An object cache allows deallocated objects to be recycled without
|
||||||
|
* the overhead of true deallocation and reallocation.
|
||||||
|
*
|
||||||
|
* @First: First cache entry
|
||||||
|
* @Last: Last cache entry
|
||||||
|
* @EntryCount: Number of entires in the cache
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
ST_OBJECT *First;
|
||||||
|
ST_OBJECT *Last;
|
||||||
|
USIZE EntryCount;
|
||||||
|
} OBJECT_CACHE;
|
||||||
|
|
||||||
|
extern OBJECT_CACHE gObCache;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize object cache
|
||||||
|
*
|
||||||
|
* @Cache: Object cache to initialize
|
||||||
|
*/
|
||||||
|
VOID ObInitCache(OBJECT_CACHE *Cache);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reclaim object to cache if the reference count is
|
||||||
|
* zero.
|
||||||
|
*
|
||||||
|
* @Cache: Cache to reclaim to
|
||||||
|
* @Object: Object to reclaim
|
||||||
|
*/
|
||||||
|
VOID ObReclaimToCache(OBJECT_CACHE *Cache, ST_OBJECT *Object);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pop an entry for a zeroed object from the cache
|
||||||
|
*
|
||||||
|
* @Cache: Cache to pop from
|
||||||
|
*
|
||||||
|
* Returns an entry on success, otherwise NULL on
|
||||||
|
* failure
|
||||||
|
*/
|
||||||
|
ST_OBJECT *ObPopFromCache(OBJECT_CACHE *Cache);
|
||||||
|
|
||||||
|
#endif /* !_OB_CACHE_H_ */
|
||||||
@@ -34,12 +34,14 @@ typedef enum {
|
|||||||
* @RefCount: Object reference count
|
* @RefCount: Object reference count
|
||||||
* @Type: Object type
|
* @Type: Object type
|
||||||
* @Data: Object data
|
* @Data: Object data
|
||||||
|
* @CacheNext: Used when reclaiming object
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct _ST_OBJECT {
|
||||||
CHAR Name[OBJECT_NAMESZ];
|
CHAR Name[OBJECT_NAMESZ];
|
||||||
ULONG RefCount;
|
ULONG RefCount;
|
||||||
OBJECT_TYPE Type;
|
OBJECT_TYPE Type;
|
||||||
VOID *Data;
|
VOID *Data;
|
||||||
|
struct _ST_OBJECT *CacheNext;
|
||||||
} ST_OBJECT;
|
} ST_OBJECT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -82,4 +84,12 @@ ST_STATUS ObCreateObject(
|
|||||||
*/
|
*/
|
||||||
VOID ObInitManager(VOID);
|
VOID ObInitManager(VOID);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reclaim an object after use, if its reference count is > 1, simply
|
||||||
|
* bump it down. Once it hits zero, the object is returned to the cache.
|
||||||
|
*
|
||||||
|
* @Object: Object to reclaim
|
||||||
|
*/
|
||||||
|
VOID ObReclaimObject(ST_OBJECT *Object);
|
||||||
|
|
||||||
#endif /* !_OB_OBJECT_H_ */
|
#endif /* !_OB_OBJECT_H_ */
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2026, Chloe M.
|
||||||
|
* Provided under the BSD-3 clause.
|
||||||
|
*
|
||||||
|
* Description: Object manager cache
|
||||||
|
* Author: Chloe M.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ob/cache.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ObReclaimToCache(OBJECT_CACHE *Cache, ST_OBJECT *Object)
|
||||||
|
{
|
||||||
|
ST_OBJECT *Last;
|
||||||
|
|
||||||
|
if (Cache == NULL || Object == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Can only reclaim when refcount hits zero */
|
||||||
|
if (Object->RefCount != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insert the object */
|
||||||
|
Object->CacheNext = NULL;
|
||||||
|
if (Cache->First == NULL || Cache->Last == NULL) {
|
||||||
|
Cache->First = Object;
|
||||||
|
Cache->Last = Object;
|
||||||
|
} else {
|
||||||
|
Last = Cache->Last;
|
||||||
|
Last->CacheNext = Object;
|
||||||
|
Cache->Last = Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
++Cache->EntryCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ObInitCache(OBJECT_CACHE *Cache)
|
||||||
|
{
|
||||||
|
if (Cache == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cache->EntryCount = 0;
|
||||||
|
Cache->First = NULL;
|
||||||
|
Cache->Last = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ST_OBJECT *
|
||||||
|
ObPopFromCache(OBJECT_CACHE *Cache)
|
||||||
|
{
|
||||||
|
ST_OBJECT *First;
|
||||||
|
|
||||||
|
if (Cache == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
First = Cache->First;
|
||||||
|
if (First == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cache->First = First->CacheNext;
|
||||||
|
RtlMemSet(First, 0, sizeof(*First));
|
||||||
|
return First;
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ob/object.h>
|
#include <ob/object.h>
|
||||||
|
#include <ob/cache.h>
|
||||||
#include <ex/trace.h>
|
#include <ex/trace.h>
|
||||||
#include <ke/knot.h>
|
#include <ke/knot.h>
|
||||||
|
|
||||||
@@ -15,12 +16,14 @@
|
|||||||
|
|
||||||
/* Globals */
|
/* Globals */
|
||||||
static ST_OBJECT *RootDirectory;
|
static ST_OBJECT *RootDirectory;
|
||||||
|
OBJECT_CACHE gObCache;
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
ObInitManager(VOID)
|
ObInitManager(VOID)
|
||||||
{
|
{
|
||||||
ST_STATUS Status;
|
ST_STATUS Status;
|
||||||
|
|
||||||
|
ObInitCache(&gObCache);
|
||||||
Status = ObCreateDirectory(
|
Status = ObCreateDirectory(
|
||||||
"/",
|
"/",
|
||||||
&RootDirectory
|
&RootDirectory
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <ob/object.h>
|
#include <ob/object.h>
|
||||||
#include <ex/pool.h>
|
#include <ex/pool.h>
|
||||||
|
#include <ob/cache.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
ST_STATUS
|
ST_STATUS
|
||||||
@@ -84,3 +85,17 @@ ObCreateObject(const CHAR *Name, OBJECT_TYPE Type, VOID *Data, ST_OBJECT **Resul
|
|||||||
*Result = Object;
|
*Result = Object;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ObReclaimObject(ST_OBJECT *Object)
|
||||||
|
{
|
||||||
|
if (Object == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Decrement this atomically */
|
||||||
|
Object->RefCount -= 1;
|
||||||
|
if (Object->RefCount == 0) {
|
||||||
|
ObReclaimToCache(&gObCache, Object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user