diff options
-rw-r--r-- | kernel/Makefile | 2 | ||||
-rw-r--r-- | kernel/drivers/mouse.c | 2 | ||||
-rw-r--r-- | kernel/fs/ext2.c | 2 | ||||
-rw-r--r-- | kernel/fs/vfs.c | 10 | ||||
-rw-r--r-- | kernel/lib/relist.c | 120 | ||||
-rw-r--r-- | kernel/lib/relist.h | 19 | ||||
-rw-r--r-- | kernel/sched/scheduler.c | 8 | ||||
-rw-r--r-- | kernel/sched/scheduler.h | 3 | ||||
-rw-r--r-- | kernel/socket.c | 2 |
9 files changed, 154 insertions, 14 deletions
diff --git a/kernel/Makefile b/kernel/Makefile index ffa835a..240f7df 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,6 +1,6 @@ CC="i686-sb-gcc" AS="i686-sb-as" -OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o syscalls/ppoll.o syscalls/ftruncate.o kubsan.o syscalls/mmap.o drivers/serial.o syscalls/accept.o syscalls/bind.o syscalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o syscalls/shm.o elf.o ksbrk.o sched/scheduler.o syscalls/fstat.o libc/string/copy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o syscalls/msleep.o syscalls/uptime.o syscalls/mkdir.o drivers/pci.o drivers/rtl8139.o network/ethernet.o network/arp.o network/bytes.o network/ipv4.o network/udp.o syscalls/recvfrom.o math.o syscalls/sendto.o signal.o syscalls/kill.o syscalls/sigaction.o network/tcp.o drivers/ahci.o crypto/xoshiro256plusplus/xoshiro256plusplus.o syscalls/chdir.o syscalls/getcwd.o syscalls/isatty.o syscalls/randomfill.o syscalls/open.o syscalls/write.o syscalls/pwrite.o syscalls/port.o syscalls/map_frames.o syscalls/virtual_to_physical.o syscalls/install_irq.o arch/i386/interrupts.o cpu/isr.o lib/stack.o lib/buffered_write.o lib/list.o cpu/arch_inst.o cpu/int_syscall.o queue.o syscalls/queue.o syscalls/munmap.o syscalls/open_process.o syscalls/lseek.o lib/ringbuffer.o +OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o syscalls/ppoll.o syscalls/ftruncate.o kubsan.o syscalls/mmap.o drivers/serial.o syscalls/accept.o syscalls/bind.o syscalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o syscalls/shm.o elf.o ksbrk.o sched/scheduler.o syscalls/fstat.o libc/string/copy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o syscalls/msleep.o syscalls/uptime.o syscalls/mkdir.o drivers/pci.o drivers/rtl8139.o network/ethernet.o network/arp.o network/bytes.o network/ipv4.o network/udp.o syscalls/recvfrom.o math.o syscalls/sendto.o signal.o syscalls/kill.o syscalls/sigaction.o network/tcp.o drivers/ahci.o crypto/xoshiro256plusplus/xoshiro256plusplus.o syscalls/chdir.o syscalls/getcwd.o syscalls/isatty.o syscalls/randomfill.o syscalls/open.o syscalls/write.o syscalls/pwrite.o syscalls/port.o syscalls/map_frames.o syscalls/virtual_to_physical.o syscalls/install_irq.o arch/i386/interrupts.o cpu/isr.o lib/stack.o lib/buffered_write.o lib/list.o cpu/arch_inst.o cpu/int_syscall.o queue.o syscalls/queue.o syscalls/munmap.o syscalls/open_process.o syscalls/lseek.o lib/ringbuffer.o lib/relist.o CFLAGS = -std=c99 -O0 -fsanitize=vla-bound,shift-exponent,pointer-overflow,shift,signed-integer-overflow,bounds -ggdb -ffreestanding -Wall -Wextra -Wno-int-conversion -Wno-unused-parameter -Werror -mgeneral-regs-only -Wimplicit-fallthrough -I./libc/include/ -I. -Wno-pointer-sign -DKERNEL LDFLAGS= INCLUDE=-I./includes/ -I../include/ -I./libc/include/ diff --git a/kernel/drivers/mouse.c b/kernel/drivers/mouse.c index 93e3be6..af13b44 100644 --- a/kernel/drivers/mouse.c +++ b/kernel/drivers/mouse.c @@ -42,7 +42,7 @@ void add_mouse(void) { // Don't look at this int fd = vfs_open("/dev/mouse", O_RDWR, 0); mouse_fd = get_vfs_fd(fd, NULL); - list_set(¤t_task->file_descriptors, fd, NULL); + relist_remove(¤t_task->file_descriptors, fd); } void what(registers_t *r) { diff --git a/kernel/fs/ext2.c b/kernel/fs/ext2.c index db947c0..613cf53 100644 --- a/kernel/fs/ext2.c +++ b/kernel/fs/ext2.c @@ -814,7 +814,7 @@ vfs_inode_t *ext2_mount(void) { mount_fd = get_vfs_fd(fd, NULL); // Remove the FD from the current task // FIXME: This is a hacky solution - list_set(¤t_task->file_descriptors, fd, NULL); + relist_remove(¤t_task->file_descriptors, fd); parse_superblock(); return vfs_create_inode( 0 /*inode_num*/, 0 /*type*/, 0 /*has_data*/, 0 /*can_write*/, diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c index 63db938..16f9186 100644 --- a/kernel/fs/vfs.c +++ b/kernel/fs/vfs.c @@ -18,7 +18,7 @@ vfs_fd_t *get_vfs_fd(int fd, process_t *p) { } vfs_fd_t *r; - if (!list_get(&p->file_descriptors, fd, (void **)&r)) { + if (!relist_get(&p->file_descriptors, fd, (void **)&r)) { return NULL; } return r; @@ -73,7 +73,7 @@ int vfs_create_fd(int flags, int mode, int is_tty, vfs_inode_t *inode, *fd = r; } int index; - list_add(¤t_task->file_descriptors, r, &index); + relist_add(¤t_task->file_descriptors, r, &index); return index; } @@ -294,7 +294,7 @@ int vfs_close_process(process_t *p, int fd) { assert(0 < fd_ptr->reference_count); // Remove process reference fd_ptr->reference_count--; - list_set(&p->file_descriptors, fd, NULL); + assert(relist_remove(&p->file_descriptors, fd)); // If no references left then free the contents if (0 == fd_ptr->reference_count) { if (fd_ptr->inode->close) { @@ -411,12 +411,12 @@ vfs_vm_object_t *vfs_get_vm_object(int fd, u64 length, u64 offset) { int vfs_dup2(int org_fd, int new_fd) { vfs_fd_t *orig; - if (!list_get(¤t_task->file_descriptors, org_fd, (void **)&orig)) { + if (!relist_get(¤t_task->file_descriptors, org_fd, (void **)&orig)) { assert(0); return -1; } assert(1 <= orig->reference_count); - if (!list_set(¤t_task->file_descriptors, new_fd, orig)) { + if (!relist_set(¤t_task->file_descriptors, new_fd, orig)) { assert(0); return -1; } diff --git a/kernel/lib/relist.c b/kernel/lib/relist.c new file mode 100644 index 0000000..6ad30d2 --- /dev/null +++ b/kernel/lib/relist.c @@ -0,0 +1,120 @@ +#include <assert.h> +#include <kmalloc.h> +#include <lib/relist.h> + +void relist_init(struct relist *list) { + list->bitmap_capacity = 100; + list->bitmap = kcalloc(sizeof(u64), list->bitmap_capacity); + if (!list->bitmap) { + goto relist_init_error; + } + list->entries = kallocarray(sizeof(void *), (sizeof(u64) * 8)); + if (!list->entries) { + goto relist_init_error; + } + return; + +// Can't allocate now but future appends can try to allocate anyways so +// there is no reason to "fail" the init. +relist_init_error: + list->bitmap_capacity = 0; + list->entries = NULL; + list->bitmap = NULL; + return; +} + +void relist_reset(struct relist *list) { + memset(list->bitmap, 0, list->bitmap_capacity * sizeof(u64)); +} + +int relist_clone(struct relist *in, struct relist *out) { + relist_init(out); + for (int i = 0;; i++) { + void *output; + if (!relist_get(in, i, &output)) { + break; + } + if (!relist_add(out, output, NULL)) { + relist_free(out); + return 0; + } + } + return 1; +} + +static int relist_find_free_entry(struct relist *list, u32 *entry) { + for (u32 i = 0; i < list->bitmap_capacity; i++) { + if (0 == ~(list->bitmap[i])) { + continue; + } + + for (int c = 0; c < 64; c++) { + if (!(list->bitmap[i] & ((u64)1 << c))) { + *entry = i * 64 + c; + return 1; + } + } + } + *entry = 0; + return 0; +} + +int relist_add(struct relist *list, void *value, u32 *index) { + u32 entry; + if (!relist_find_free_entry(list, &entry)) { + assert(0); + } + list->entries[entry] = value; + if (index) { + *index = entry; + } + list->bitmap[entry / 64] |= ((u64)1 << (entry % 64)); + return 1; +} + +int relist_remove(struct relist *list, u32 index) { + if ((index / 64) > list->bitmap_capacity) { + assert(0); + return 0; + } + int is_used = (list->bitmap[index / 64] & ((u64)1 << (index % 64))); + if (!is_used) { + assert(0); + return 0; + } + list->bitmap[index / 64] &= ~((u64)1 << (index % 64)); + return 1; +} + +int relist_set(struct relist *list, u32 index, void *value) { + assert(value); + if ((index / 64) > list->bitmap_capacity) { + assert(0); + return 0; + } + int is_used = (list->bitmap[index / 64] & ((u64)1 << (index % 64))); + assert(is_used); + list->entries[index] = value; + return 1; +} + +int relist_get(const struct relist *list, u32 index, void **out) { + if ((index / 64) > list->bitmap_capacity) { + assert(0); + return 0; + } + int is_used = (list->bitmap[index / 64] & ((u64)1 << (index % 64))); + if (!is_used) { + return 0; + } + *out = list->entries[index]; + return 1; +} + +void relist_free(struct relist *list) { + list->bitmap_capacity = 0; + kfree(list->entries); + kfree(list->bitmap); + list->entries = NULL; + list->bitmap = NULL; +} diff --git a/kernel/lib/relist.h b/kernel/lib/relist.h new file mode 100644 index 0000000..96625ba --- /dev/null +++ b/kernel/lib/relist.h @@ -0,0 +1,19 @@ +#ifndef RELIST_H +#define RELIST_H +#include <typedefs.h> + +struct relist { + void **entries; + u32 bitmap_capacity; + u64 *bitmap; +}; + +void relist_init(struct relist *list); +void relist_reset(struct relist *list); +void relist_free(struct relist *list); +int relist_clone(struct relist *in, struct relist *out); +int relist_add(struct relist *list, void *value, u32 *index); +int relist_set(struct relist *list, u32 index, void *value); +int relist_get(const struct relist *list, u32 index, void **out); +int relist_remove(struct relist *list, u32 index); +#endif diff --git a/kernel/sched/scheduler.c b/kernel/sched/scheduler.c index 6454775..42d4dc7 100644 --- a/kernel/sched/scheduler.c +++ b/kernel/sched/scheduler.c @@ -120,14 +120,14 @@ process_t *create_process(process_t *p, u32 esp, u32 eip) { } if (p) { - if (!list_clone(&p->file_descriptors, &r->file_descriptors)) { + if (!relist_clone(&p->file_descriptors, &r->file_descriptors)) { kfree(r->tcb); kfree(r); return NULL; } for (int i = 0;; i++) { vfs_fd_t *out; - if (!list_get(&p->file_descriptors, i, (void **)&out)) { + if (!relist_get(&r->file_descriptors, i, (void **)&out)) { break; } if (out) { @@ -135,7 +135,7 @@ process_t *create_process(process_t *p, u32 esp, u32 eip) { } } } else { - list_init(&r->file_descriptors); + relist_init(&r->file_descriptors); } if (p) { @@ -208,7 +208,7 @@ void free_process(process_t *p) { list_free(&p->tcp_sockets); list_free(&p->tcp_listen); list_free(&p->event_queue); - list_free(&p->file_descriptors); + relist_free(&p->file_descriptors); kfree(p->tcb); mmu_free_pagedirectory(p->cr3); diff --git a/kernel/sched/scheduler.h b/kernel/sched/scheduler.h index 7e42cc7..feb6aa5 100644 --- a/kernel/sched/scheduler.h +++ b/kernel/sched/scheduler.h @@ -5,6 +5,7 @@ typedef struct Process process_t; #include <fs/vfs.h> #include <lib/list.h> #include <lib/stack.h> +#include <lib/relist.h> #include <mmu.h> #include <signal.h> #include <stdbool.h> @@ -61,7 +62,7 @@ struct Process { void *interrupt_handler; PageDirectory *cr3; - struct list file_descriptors; + struct relist file_descriptors; struct list read_list; struct list write_list; diff --git a/kernel/socket.c b/kernel/socket.c index 53dd71e..d3dfd1a 100644 --- a/kernel/socket.c +++ b/kernel/socket.c @@ -261,7 +261,7 @@ int accept(int socket, struct sockaddr *address, socklen_t *address_len) { } int index; - assert(list_add(¤t_task->file_descriptors, s->incoming_fd, &index)); + assert(relist_add(¤t_task->file_descriptors, s->incoming_fd, &index)); assert(1 <= s->incoming_fd->reference_count); s->incoming_fd = NULL; // for (char c; 0 < vfs_pread(s->fifo_fd, &c, 1, 0);) |