slab: Add an arena pointer to the interface
[akaros.git] / kern / include / slab.h
index 7e5189c..7f1e7d0 100644 (file)
@@ -8,7 +8,7 @@
  *
  * There is a list of kmem_cache, which are the caches of objects of a given
  * size.  This list is sorted in order of size.  Each kmem_cache has three
- * lists of slabs: full, partial, and empty.  
+ * lists of slabs: full, partial, and empty.
  *
  * For large objects, the kmem_slabs point to bufctls, which have the address
  * of their large buffers.  These slabs can consist of more than one contiguous
  * address.  This also might fuck with alignment.
  */
 
-#ifndef ROS_KERN_SLAB_H
-#define ROS_KERN_SLAB_H
+#pragma once
 
 #include <ros/common.h>
 #include <arch/mmu.h>
 #include <sys/queue.h>
 #include <atomic.h>
+#include <hash_helper.h>
+#include <arena.h>
 
 /* Back in the day, their cutoff for "large objects" was 512B, based on
  * measurements and on not wanting more than 1/8 of internal fragmentation. */
@@ -43,11 +44,11 @@ struct kmem_slab;
 
 /* Control block for buffers for large-object slabs */
 struct kmem_bufctl {
-       TAILQ_ENTRY(kmem_bufctl) link;
+       BSD_LIST_ENTRY(kmem_bufctl) link;
        void *buf_addr;
        struct kmem_slab *my_slab;
 };
-TAILQ_HEAD(kmem_bufctl_list, kmem_bufctl);
+BSD_LIST_HEAD(kmem_bufctl_list, kmem_bufctl);
 
 /* Slabs contain the objects.  Can be either full, partial, or empty,
  * determined by checking the number of objects busy vs total.  For large
@@ -59,10 +60,8 @@ struct kmem_slab {
        size_t num_busy_obj;
        size_t num_total_obj;
        union {
-               struct kmem_bufctl_list bufctl_freelist
-                   WHEN(obj_size > SLAB_LARGE_CUTOFF);
-               void *free_small_obj
-                   WHEN(obj_size <= SLAB_LARGE_CUTOFF);
+               struct kmem_bufctl_list bufctl_freelist;
+               void *free_small_obj;
        };
 };
 TAILQ_HEAD(kmem_slab_list, kmem_slab);
@@ -71,16 +70,20 @@ TAILQ_HEAD(kmem_slab_list, kmem_slab);
 struct kmem_cache {
        SLIST_ENTRY(kmem_cache) link;
        spinlock_t cache_lock;
-       const char *NTS name;
+       const char *name;
        size_t obj_size;
        int align;
        int flags;
+       struct arena *source;
        struct kmem_slab_list full_slab_list;
        struct kmem_slab_list partial_slab_list;
        struct kmem_slab_list empty_slab_list;
        void (*ctor)(void *, size_t);
        void (*dtor)(void *, size_t);
        unsigned long nr_cur_alloc;
+       struct hash_helper hh;
+       struct kmem_bufctl_list *alloc_hash;
+       struct kmem_bufctl_list static_hash[HASH_INIT_SZ];
 };
 
 /* List of all kmem_caches, sorted in order of size */
@@ -88,8 +91,9 @@ SLIST_HEAD(kmem_cache_list, kmem_cache);
 extern struct kmem_cache_list kmem_caches;
 
 /* Cache management */
-struct kmem_cache *kmem_cache_create(const char *NTS name, size_t obj_size,
+struct kmem_cache *kmem_cache_create(const char *name, size_t obj_size,
                                      int align, int flags,
+                                     struct arena *source,
                                      void (*ctor)(void *, size_t),
                                      void (*dtor)(void *, size_t));
 void kmem_cache_destroy(struct kmem_cache *cp);
@@ -99,8 +103,13 @@ void kmem_cache_free(struct kmem_cache *cp, void *buf);
 /* Back end: internal functions */
 void kmem_cache_init(void);
 void kmem_cache_reap(struct kmem_cache *cp);
+/* Low-level interface for initializing a cache. */
+void __kmem_cache_create(struct kmem_cache *kc, const char *name,
+                         size_t obj_size, int align, int flags,
+                         struct arena *source,
+                         void (*ctor)(void *, size_t),
+                         void (*dtor)(void *, size_t));
 
 /* Debug */
 void print_kmem_cache(struct kmem_cache *kc);
 void print_kmem_slab(struct kmem_slab *slab);
-#endif // !ROS_KERN_SLAB_H