#include #include #include #include #include #pragma once #define KCACHE_NAME_LEN 16 struct ma_bufctl { struct ma_bufctl *next; size_t *startaddr; }; // ADD COLORING struct ma_slab { struct ma_cache *cache; struct ma_slab *next; struct ma_slab *prev; uint32_t refcount; // The amount of active (not free) objects in the slabs atomic_flag lock; struct ma_bufctl *free; // Linked list of free buffers in the slab. Is equal to NULL once there are no more free objects }; /* objrefs are used to be able to quickly find out which slab and cache a object belongs to. objrefs belonging to the same slab are kept in one page, there is no mixing. */ struct ma_objref { struct ma_objref *next; struct ma_objref *prev; void *addr; // Addr of the object struct ma_slab *slab; // The slab which the obj belongs to struct ma_cache *kcache; // The cache which the obj belongs to }; struct ma_cache { struct ma_cache *next; struct ma_cache *prev; uint32_t objsize; // Size of the object which the cache stores uint16_t flags; // Not useful yet uint32_t num; // Number of objects per slab uint32_t slabsize; // How many pages does a single slab take up. Useful for objects > PAGE_SIZE struct ma_slab *slabs_free; struct ma_slab *slabs_partial; struct ma_slab *slabs_used; atomic_flag lock; char name[KCACHE_NAME_LEN]; }; void *ma_cache_alloc(struct ma_cache *kcache, uint32_t flags); kstatus ma_cache_dealloc(void *object); struct ma_cache *ma_cache_create(char *name, size_t size, uint32_t flags, void (*constructor)(void *, size_t), void (*destructor)(void *, size_t)); void cache_info(struct ma_cache *cache); void create_base_caches();