CS350 COS
COS
Loading...
Searching...
No Matches
slab.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2013-2023 Ali Mashtizadeh
3 * All rights reserved.
4 */
5
6#include <stdbool.h>
7#include <stdint.h>
8#include <string.h>
9
10#include <sys/cdefs.h>
11#include <sys/kassert.h>
12#include <sys/kdebug.h>
13#include <sys/queue.h>
14#include <sys/kmem.h>
15
16#include <machine/pmap.h>
17
18LIST_HEAD(SlabListHead, Slab) slabList = LIST_HEAD_INITIALIZER(slabList);
19
30void
31Slab_Init(Slab *slab, const char *name, uintptr_t objsz, uintptr_t align)
32{
33 ASSERT(objsz >= sizeof(SlabElement));
34
35 slab->objsz = objsz;
36 slab->align = align;
37 slab->xmem = XMem_New();
38 slab->objs = 0;
39 slab->freeObjs = 0;
40 slab->allocs = 0;
41 slab->frees = 0;
42 LIST_INIT(&slab->freeList);
43
44 ASSERT(slab->xmem != NULL);
45
46 strncpy(&slab->name[0], name, SLAB_NAMELEN);
47
49
50 LIST_INSERT_HEAD(&slabList, slab, slabList);
51}
52
62int
64{
67 uintptr_t inc;
68 uintptr_t realObjSz = ROUNDUP(slab->objsz, slab->align);
69
70 inc = ROUNDUP(realObjSz * 64, PGSIZE);
71 if (inc < 4 * PGSIZE) {
72 inc = 4 * PGSIZE;
73 }
74
75 if (!XMem_Allocate(slab->xmem, len + inc)) {
76 kprintf("Slab: Cannot grow XMem region!\n");
77 return -1;
78 }
79
80 // Add empty objects to linked list
81 uintptr_t i;
82 uintptr_t objs = inc / realObjSz;
83 for (i = 0; i < objs; i++) {
84 SlabElement *elem = (SlabElement *)(base + len + i * realObjSz);
85
86 LIST_INSERT_HEAD(&slab->freeList, elem, free);
87 }
88
89 slab->objs += objs;
90 slab->freeObjs += objs;
91
92 return 0;
93}
94
104void *
106{
107 SlabElement *elem;
108
109 Spinlock_Lock(&slab->lock);
110
111 if (slab->freeObjs == 0)
112 SlabExtend(slab);
113
114 elem = LIST_FIRST(&slab->freeList);
115 if (elem != NULL) {
116 LIST_REMOVE(elem, free);
117 slab->allocs++;
118 slab->freeObjs--;
119 }
120
121 Spinlock_Unlock(&slab->lock);
122
123 return (void *)elem;
124}
125
134void
135Slab_Free(Slab *slab, void *region)
136{
137 Spinlock_Lock(&slab->lock);
138
139 SlabElement *elem = (SlabElement *)region;
140 LIST_INSERT_HEAD(&slab->freeList, elem, free);
141 slab->frees++;
142 slab->freeObjs++;
143
144 Spinlock_Unlock(&slab->lock);
145}
146
147static void
148Debug_Slabs(int argc, const char *argv[])
149{
150 Slab *slab;
151
152 kprintf("%-36s %-10s %-10s %-10s\n", "Slab Name", "Alloc", "Free", "Total");
153 LIST_FOREACH(slab, &slabList, slabList) {
154 kprintf("%-36s %-10lld %-10lld %-10lld\n", slab->name,
155 slab->objs - slab->freeObjs, slab->freeObjs, slab->objs);
156 }
157}
158
159REGISTER_DBGCMD(slabs, "Display list of slabs", Debug_Slabs);
160
#define ASSERT(_x)
Definition: kassert.h:8
int kprintf(const char *fmt,...)
Definition: printf.c:210
#define REGISTER_DBGCMD(_NAME, _DESC, _FUNC)
Definition: kdebug.h:11
#define SLAB_NAMELEN
Definition: kmem.h:40
void Slab_Init(Slab *slab, const char *name, uintptr_t objsz, uintptr_t align)
#define ROUNDUP(_x, _n)
Definition: malloc.c:32
#define PGSIZE
Definition: malloc.c:21
uint64_t len
Definition: multiboot.h:2
#define LIST_INIT(head)
Definition: queue.h:430
#define LIST_REMOVE(elm, field)
Definition: queue.h:465
#define LIST_HEAD_INITIALIZER(head)
Definition: queue.h:368
#define LIST_FIRST(head)
Definition: queue.h:408
#define LIST_FOREACH(var, head, field)
Definition: queue.h:410
#define LIST_INSERT_HEAD(head, elm, field)
Definition: queue.h:451
#define LIST_HEAD(name, type)
Definition: queue.h:363
static uint16_t base
Definition: sercons.c:37
void Slab_Free(Slab *slab, void *region)
Definition: slab.c:135
void * Slab_Alloc(Slab *slab)
Definition: slab.c:105
static void Debug_Slabs(int argc, const char *argv[])
Definition: slab.c:148
int SlabExtend(Slab *slab)
Definition: slab.c:63
void Spinlock_Unlock(Spinlock *lock) __UNLOCK_EX(*lock)
Definition: spinlock.c:109
#define SPINLOCK_TYPE_NORMAL
Definition: spinlock.h:12
void Spinlock_Lock(Spinlock *lock) __LOCK_EX(*lock)
Definition: spinlock.c:75
void Spinlock_Init(Spinlock *lock, const char *name, uint64_t type)
Definition: spinlock.c:43
#define NULL
Definition: stddef.h:6
void free(void *buf)
Definition: malloc.c:169
char * strncpy(char *to, const char *from, size_t len)
Definition: string.c:34
Definition: kmem.h:46
uintptr_t align
Definition: kmem.h:48
uintptr_t objsz
Definition: kmem.h:47
Spinlock lock
Definition: kmem.h:50
uint64_t freeObjs
Definition: kmem.h:52
uint64_t frees
Definition: kmem.h:56
char name[SLAB_NAMELEN]
Definition: kmem.h:57
XMem * xmem
Definition: kmem.h:49
uint64_t allocs
Definition: kmem.h:55
uint64_t objs
Definition: kmem.h:51
uint64_t uintptr_t
Definition: types.h:16
uintptr_t XMem_GetLength(XMem *xmem)
Definition: xmem.c:86
XMem * XMem_New()
Definition: xmem.c:47
bool XMem_Allocate(XMem *xmem, uintptr_t length)
Definition: xmem.c:92
uintptr_t XMem_GetBase(XMem *xmem)
Definition: xmem.c:80