feature (proc): implemented file descriptors
This commit is contained in:
parent
af95bd2ba1
commit
c14013efaa
|
@ -0,0 +1,41 @@
|
|||
// This file is part of noxos and licensed under the MIT open source license
|
||||
|
||||
#ifndef NOX_FILE_DESCRIPTOR_H
|
||||
#define NOX_FILE_DESCRIPTOR_H
|
||||
|
||||
#include "utils/stdtypes.h"
|
||||
#include "utils/bitmap.h"
|
||||
#include "drivers/fs/vfs.h"
|
||||
|
||||
#define FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE 2
|
||||
|
||||
typedef int32_t file_descriptor_t;
|
||||
|
||||
typedef enum {
|
||||
FILE_DESCRIPTOR_INVALID = -1
|
||||
} std_file_descriptors_E;
|
||||
|
||||
typedef struct file_descriptor_array_chunk_T file_descriptor_array_chunk_T;
|
||||
struct file_descriptor_array_chunk_T {
|
||||
file_descriptor_array_chunk_T* prev;
|
||||
file_descriptor_array_chunk_T* next;
|
||||
vfs_node_T* lookup [FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE];
|
||||
bitmap_T bitmap;
|
||||
uint32_t amount;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
file_descriptor_array_chunk_T* base_chunk;
|
||||
} file_descriptor_array_T;
|
||||
|
||||
file_descriptor_t file_descriptor_request (file_descriptor_array_T* fd_array, vfs_node_T* node);
|
||||
vfs_node_T* file_descriptor_resolve (file_descriptor_array_T* fd_array, file_descriptor_t fd);
|
||||
void file_descriptor_free (file_descriptor_array_T* fd_array, file_descriptor_t fd);
|
||||
|
||||
file_descriptor_array_T* file_descriptor_array_alloc ();
|
||||
void file_descriptor_array_destruct (file_descriptor_array_T* fd_array);
|
||||
|
||||
file_descriptor_array_chunk_T* file_descriptor_array_chunk_alloc (file_descriptor_array_chunk_T* prev);
|
||||
void file_descriptor_array_chunk_destruct (file_descriptor_array_chunk_T* chunk);
|
||||
|
||||
#endif //NOX_FILE_DESCRIPTOR_H
|
|
@ -0,0 +1,110 @@
|
|||
// This file is part of noxos and licensed under the MIT open source license
|
||||
|
||||
#include "proc/file_descriptor.h"
|
||||
#include "utils/memory.h"
|
||||
|
||||
|
||||
file_descriptor_t file_descriptor_request(file_descriptor_array_T* fd_array, vfs_node_T* node) {
|
||||
file_descriptor_t fd = 0;
|
||||
|
||||
file_descriptor_array_chunk_T* chunk = fd_array->base_chunk;
|
||||
while (chunk->amount == FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE) {
|
||||
if (chunk->next == NULL) file_descriptor_array_chunk_alloc(chunk);
|
||||
chunk = chunk->next;
|
||||
fd +=FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE;
|
||||
}
|
||||
|
||||
for (int i = 0; i < FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE; i++) {
|
||||
if (bitmap_get(&chunk->bitmap, i)) continue;
|
||||
|
||||
bitmap_set(&chunk->bitmap, i, true);
|
||||
chunk->lookup[i] = node;
|
||||
chunk->amount++;
|
||||
fd += i;
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
// this should never happen
|
||||
return FILE_DESCRIPTOR_INVALID;
|
||||
}
|
||||
|
||||
vfs_node_T* file_descriptor_resolve(file_descriptor_array_T* fd_array, file_descriptor_t fd) {
|
||||
if (fd == FILE_DESCRIPTOR_INVALID) return NULL;
|
||||
|
||||
|
||||
uint32_t chunk_selector = fd / FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE;
|
||||
file_descriptor_array_chunk_T* chunk = fd_array->base_chunk;
|
||||
for (int i = 0; i < chunk_selector; i++) {
|
||||
chunk = chunk->next;
|
||||
if (chunk == NULL) return NULL;
|
||||
}
|
||||
|
||||
uint32_t fd_selector = fd % FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE;
|
||||
|
||||
// Check if the file descriptor exists
|
||||
if (!bitmap_get(&chunk->bitmap, fd_selector)) return NULL;
|
||||
|
||||
return chunk->lookup[fd_selector];
|
||||
}
|
||||
|
||||
void file_descriptor_free(file_descriptor_array_T* fd_array, file_descriptor_t fd) {
|
||||
if (fd == FILE_DESCRIPTOR_INVALID) return;
|
||||
|
||||
uint32_t chunk_selector = fd / FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE;
|
||||
file_descriptor_array_chunk_T* chunk = fd_array->base_chunk;
|
||||
for (int i = 0; i < chunk_selector; i++) {
|
||||
chunk = chunk->next;
|
||||
if (chunk == NULL) return;
|
||||
}
|
||||
|
||||
bitmap_set(&chunk->bitmap, fd % FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE, false);
|
||||
|
||||
chunk->amount--;
|
||||
}
|
||||
|
||||
|
||||
file_descriptor_array_T* file_descriptor_array_alloc() {
|
||||
file_descriptor_array_T* fd_array = memory_allocate(sizeof(file_descriptor_array_T));
|
||||
|
||||
fd_array->base_chunk = file_descriptor_array_chunk_alloc(NULL);
|
||||
|
||||
return fd_array;
|
||||
}
|
||||
|
||||
void file_descriptor_array_destruct(file_descriptor_array_T* fd_array) {
|
||||
file_descriptor_array_chunk_T* chunk = fd_array->base_chunk;
|
||||
file_descriptor_array_chunk_T* next_chunk;
|
||||
|
||||
while (chunk != NULL) {
|
||||
next_chunk = chunk->next;
|
||||
file_descriptor_array_chunk_destruct(chunk);
|
||||
chunk = next_chunk;
|
||||
}
|
||||
|
||||
memory_free(fd_array);
|
||||
}
|
||||
|
||||
|
||||
file_descriptor_array_chunk_T* file_descriptor_array_chunk_alloc(file_descriptor_array_chunk_T* prev) {
|
||||
file_descriptor_array_chunk_T* chunk = memory_allocate(sizeof(file_descriptor_array_chunk_T));
|
||||
|
||||
chunk->bitmap = bitmap_init(FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE);
|
||||
chunk->amount = 0;
|
||||
chunk->prev = prev;
|
||||
|
||||
if (chunk->prev != NULL) {
|
||||
chunk->prev->next = chunk;
|
||||
}
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
void file_descriptor_array_chunk_destruct(file_descriptor_array_chunk_T* chunk) {
|
||||
if (chunk->prev != NULL) {
|
||||
chunk->prev->next = NULL;
|
||||
}
|
||||
|
||||
bitmap_destruct(&chunk->bitmap);
|
||||
memory_free(chunk);
|
||||
}
|
Loading…
Reference in New Issue