slab: rewrite slab allocator

This commit is contained in:
Matheus
2025-09-04 22:40:10 -03:00
parent 8cba07f65c
commit 2fa040096c
11 changed files with 500 additions and 261 deletions
+17 -9
View File
@@ -254,6 +254,13 @@ int devfs_maxseek(vnode_t *node, size_t *max) {
return devnode->devops->maxseek ? devnode->devops->maxseek(devnode->attr.rdevminor, max) : ENOTTY;
}
static void destroy_node(devnode_t *node) {
memset(node, 0, sizeof(devnode_t));
VOP_INIT(&node->vnode, &vnops, 0, 0, NULL)
node->attr.inode = ++currentinode;
slab_free(nodecache, node);
}
int devfs_inactive(vnode_t *node) {
INTERNAL_LOCK(node);
devnode_t *devnode = (devnode_t *)node;
@@ -267,7 +274,7 @@ int devfs_inactive(vnode_t *node) {
if (devnode->devops && devnode->devops->inactive)
devnode->devops->inactive(devnode->attr.rdevminor);
slab_free(nodecache, node);
destroy_node(devnode);
return 0;
}
@@ -311,13 +318,13 @@ int devfs_create(vnode_t *parent, char *name, vattr_t *attr, int type, vnode_t *
if (type == V_TYPE_DIR) {
int error = hashtable_init(&node->children, 100);
if (error) {
slab_free(nodecache, node);
destroy_node(node);
INTERNAL_UNLOCK(parent);
return error;
}
if (hashtable_set(&node->children, node, ".", 1, true) || hashtable_set(&node->children, parent, "..", 2, true)) {
hashtable_destroy(&node->children);
slab_free(nodecache, node);
destroy_node(node);
INTERNAL_UNLOCK(parent);
return error;
}
@@ -328,7 +335,7 @@ int devfs_create(vnode_t *parent, char *name, vattr_t *attr, int type, vnode_t *
if (type == V_TYPE_DIR)
hashtable_destroy(&node->children);
INTERNAL_UNLOCK(parent);
slab_free(nodecache, node);
destroy_node(node);
return error;
}
@@ -476,16 +483,17 @@ static vops_t vnops = {
.unlock = devfs_unlock
};
static void ctor(scache_t *cache, void *obj) {
static bool ctor(scache_t *cache, void *obj) {
devnode_t *node = obj;
memset(node, 0, sizeof(devnode_t));
VOP_INIT(&node->vnode, &vnops, 0, 0, NULL)
node->attr.inode = ++currentinode;
return true;
}
void devfs_init() {
__assert(hashtable_init(&devtable, 50) == 0);
nodecache = slab_newcache(sizeof(devnode_t), 0, ctor, ctor);
nodecache = slab_newcache(sizeof(devnode_t), 0, ctor, NULL);
MUTEX_INIT(&tablelock);
__assert(nodecache);
@@ -525,7 +533,7 @@ int devfs_register(devops_t *devops, char *name, int type, int major, int minor,
int error = hashtable_set(&devtable, master, key, sizeof(key), true);
MUTEX_RELEASE(&tablelock);
if (error) {
slab_free(nodecache, master);
destroy_node(master);
return error;
}
@@ -540,7 +548,7 @@ int devfs_register(devops_t *devops, char *name, int type, int major, int minor,
char lastcomp[strlen(name) + 1];
error = vfs_lookup(&dir, (vnode_t *)devfsroot, name, lastcomp, VFS_LOOKUP_PARENT);
if (error) {
slab_free(nodecache, master);
destroy_node(master);
return error;
}
@@ -556,7 +564,7 @@ int devfs_register(devops_t *devops, char *name, int type, int major, int minor,
MUTEX_ACQUIRE(&tablelock);
__assert(hashtable_remove(&devtable, key, sizeof(key) == 0));
MUTEX_RELEASE(&tablelock);
slab_free(nodecache, master);
destroy_node(master);
return error;
}
+11 -3
View File
@@ -13,19 +13,20 @@ static scache_t *filecache;
cleanfile(f); \
}
static void ctor(scache_t *cache, void *obj) {
static bool ctor(scache_t *cache, void *obj) {
file_t *file = obj;
file->vnode = NULL;
MUTEX_INIT(&file->mutex);
file->refcount = 1;
file->offset = 0;
file->flags = 0;
file->mode = 0;
file->refcount = 1;
return true;
}
static file_t* newfile() {
if (filecache == NULL) {
filecache = slab_newcache(sizeof(file_t), 0, ctor, ctor);
filecache = slab_newcache(sizeof(file_t), 0, ctor, NULL);
__assert(filecache);
}
@@ -37,6 +38,13 @@ static void cleanfile(file_t *file) {
vfs_close(file->vnode, fileflagstovnodeflags(file->flags));
VOP_RELEASE(file->vnode);
}
file->vnode = NULL;
file->refcount = 1;
file->offset = 0;
file->flags = 0;
file->mode = 0;
MUTEX_INIT(&file->mutex);
slab_free(filecache, file);
}
+10 -2
View File
@@ -342,6 +342,13 @@ int pipefs_inactive(vnode_t *node) {
pipenode_t *pipenode = (pipenode_t *)node;
INTERNAL_LOCK(node);
ringbuffer_destroy(&pipenode->data);
// TODO write this properly using cache ctor and dtor
memset(node, 0, sizeof(pipenode_t));
VOP_INIT(node, &vnops, 0, V_TYPE_FIFO, NULL);
pipenode->attr.inode = ++currentinode;
POLL_INITHEADER(&pipenode->pollheader);
EVENT_INITHEADER(&pipenode->writeopenevent);
EVENT_INITHEADER(&pipenode->readopenevent);
slab_free(nodecache, node);
return 0;
}
@@ -389,7 +396,7 @@ static vops_t vnops = {
.unlock = pipefs_unlock
};
static void ctor(scache_t *cache, void *obj) {
static bool ctor(scache_t *cache, void *obj) {
pipenode_t *node = obj;
memset(node, 0, sizeof(pipenode_t));
VOP_INIT(&node->vnode, &vnops, 0, V_TYPE_FIFO, NULL);
@@ -397,10 +404,11 @@ static void ctor(scache_t *cache, void *obj) {
POLL_INITHEADER(&node->pollheader);
EVENT_INITHEADER(&node->writeopenevent);
EVENT_INITHEADER(&node->readopenevent);
return true;
}
void pipefs_init() {
nodecache = slab_newcache(sizeof(pipenode_t), 0, ctor, ctor);
nodecache = slab_newcache(sizeof(pipenode_t), 0, ctor, NULL);
__assert(nodecache);
}
+9 -2
View File
@@ -204,10 +204,16 @@ int sockfs_ioctl(vnode_t *node, unsigned long request, void *arg, int *result, c
return 0;
}
static vops_t vnops;
int sockfs_inactive(vnode_t *node) {
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(node);
socketnode_t *socketnode = (socketnode_t *)node;
INTERNAL_LOCK(node);
socket->ops->destroy(socket);
memset(node, 0, sizeof(socketnode_t));
VOP_INIT(&socketnode->vnode, &vnops, 0, V_TYPE_SOCKET, NULL);
//socketnode->attr.inode = ++currentinode;
slab_free(nodecache, node);
return 0;
}
@@ -256,15 +262,16 @@ static vops_t vnops = {
.unlock = sockfs_unlock
};
static void ctor(scache_t *cache, void *obj) {
static bool ctor(scache_t *cache, void *obj) {
socketnode_t *node = obj;
memset(node, 0, sizeof(socketnode_t));
VOP_INIT(&node->vnode, &vnops, 0, V_TYPE_SOCKET, NULL);
node->attr.inode = ++currentinode;
return true;
}
void sockfs_init() {
nodecache = slab_newcache(sizeof(socketnode_t), 0, ctor, ctor);
nodecache = slab_newcache(sizeof(socketnode_t), 0, ctor, NULL);
__assert(nodecache);
}