From 32407e728971006ed3d0885e01c22fb66c8adc57 Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Fri, 15 Jul 2016 23:12:14 +0200 Subject: Move stuff around, again --- src/bin/bam.lua | 6 +- src/common/bam.lua | 1 - src/common/include/algo.h | 37 ---- src/common/include/btree.h | 33 --- src/common/include/debug.h | 18 -- src/common/include/hashtbl.h | 35 ---- src/common/include/kogata/algo.h | 37 ++++ src/common/include/kogata/btree.h | 33 +++ src/common/include/kogata/debug.h | 18 ++ src/common/include/kogata/hashtbl.h | 35 ++++ src/common/include/kogata/malloc.h | 13 ++ src/common/include/kogata/mutex.h | 22 ++ src/common/include/kogata/printf.h | 10 + src/common/include/kogata/region_alloc.h | 32 +++ src/common/include/kogata/slab_alloc.h | 45 ++++ src/common/include/malloc.h | 13 -- src/common/include/mutex.h | 22 -- src/common/include/printf.h | 10 - src/common/include/region_alloc.h | 32 --- src/common/include/slab_alloc.h | 45 ---- src/common/libalgo/btree.c | 343 ------------------------------- src/common/libalgo/hashtbl.c | 177 ---------------- src/common/libalgo/keyval.c | 51 ----- src/common/libc/printf.c | 3 +- src/common/libc/string.c | 2 +- src/common/libkogata/btree.c | 343 +++++++++++++++++++++++++++++++ src/common/libkogata/hashtbl.c | 177 ++++++++++++++++ src/common/libkogata/keyval.c | 51 +++++ src/common/libkogata/mutex.c | 2 +- src/common/libkogata/region_alloc.c | 6 +- src/common/libkogata/slab_alloc.c | 2 +- src/kernel/bam.lua | 6 +- src/lib/bam.lua | 6 +- src/lib/include/draw.h | 64 ------ src/lib/include/gip.h | 56 ----- src/lib/include/keyboard.h | 39 ---- src/lib/include/kogata/draw.h | 64 ++++++ src/lib/include/kogata/gip.h | 56 +++++ src/lib/include/kogata/keyboard.h | 39 ++++ src/lib/include/kogata/mainloop.h | 47 +++++ src/lib/include/kogata/syscall.h | 63 ++++++ src/lib/include/mainloop.h | 47 ----- src/lib/include/proto/gip.h | 2 +- src/lib/include/stdio.h | 2 +- src/lib/include/stdlib.h | 2 +- src/lib/include/syscall.h | 63 ------ src/lib/libc/debug.c | 18 ++ src/lib/libc/malloc.c | 70 +++++++ src/lib/libc/start.c | 17 ++ src/lib/libc/stdio.c | 63 ++++++ src/lib/libc/syscall.c | 204 ++++++++++++++++++ src/lib/libc/unistd.c | 66 ++++++ src/lib/libkogata/debug.c | 19 -- src/lib/libkogata/draw.c | 10 +- src/lib/libkogata/gip.c | 4 +- src/lib/libkogata/keyboard.c | 11 +- src/lib/libkogata/mainloop.c | 4 +- src/lib/libkogata/malloc.c | 70 ------- src/lib/libkogata/start.c | 17 -- src/lib/libkogata/stdio.c | 63 ------ src/lib/libkogata/syscall.c | 203 ------------------ src/lib/libkogata/unistd.c | 67 ------ src/sysbin/bam.lua | 15 +- src/sysbin/giosrv/main.c | 10 +- src/sysbin/init/main.c | 12 +- src/sysbin/login/main.c | 6 +- src/sysbin/shell/main.c | 6 +- src/sysbin/terminal/main.c | 13 +- 68 files changed, 1589 insertions(+), 1589 deletions(-) delete mode 100644 src/common/include/algo.h delete mode 100644 src/common/include/btree.h delete mode 100644 src/common/include/debug.h delete mode 100644 src/common/include/hashtbl.h create mode 100644 src/common/include/kogata/algo.h create mode 100644 src/common/include/kogata/btree.h create mode 100644 src/common/include/kogata/debug.h create mode 100644 src/common/include/kogata/hashtbl.h create mode 100644 src/common/include/kogata/malloc.h create mode 100644 src/common/include/kogata/mutex.h create mode 100644 src/common/include/kogata/printf.h create mode 100644 src/common/include/kogata/region_alloc.h create mode 100644 src/common/include/kogata/slab_alloc.h delete mode 100644 src/common/include/malloc.h delete mode 100644 src/common/include/mutex.h delete mode 100644 src/common/include/printf.h delete mode 100644 src/common/include/region_alloc.h delete mode 100644 src/common/include/slab_alloc.h delete mode 100644 src/common/libalgo/btree.c delete mode 100644 src/common/libalgo/hashtbl.c delete mode 100644 src/common/libalgo/keyval.c create mode 100644 src/common/libkogata/btree.c create mode 100644 src/common/libkogata/hashtbl.c create mode 100644 src/common/libkogata/keyval.c delete mode 100644 src/lib/include/draw.h delete mode 100644 src/lib/include/gip.h delete mode 100644 src/lib/include/keyboard.h create mode 100644 src/lib/include/kogata/draw.h create mode 100644 src/lib/include/kogata/gip.h create mode 100644 src/lib/include/kogata/keyboard.h create mode 100644 src/lib/include/kogata/mainloop.h create mode 100644 src/lib/include/kogata/syscall.h delete mode 100644 src/lib/include/mainloop.h delete mode 100644 src/lib/include/syscall.h create mode 100644 src/lib/libc/debug.c create mode 100644 src/lib/libc/malloc.c create mode 100644 src/lib/libc/start.c create mode 100644 src/lib/libc/stdio.c create mode 100644 src/lib/libc/syscall.c create mode 100644 src/lib/libc/unistd.c delete mode 100644 src/lib/libkogata/debug.c delete mode 100644 src/lib/libkogata/malloc.c delete mode 100644 src/lib/libkogata/start.c delete mode 100644 src/lib/libkogata/stdio.c delete mode 100644 src/lib/libkogata/syscall.c delete mode 100644 src/lib/libkogata/unistd.c diff --git a/src/bin/bam.lua b/src/bin/bam.lua index 1a2d3a7..4026bce 100644 --- a/src/bin/bam.lua +++ b/src/bin/bam.lua @@ -8,16 +8,16 @@ local function bin_settings(name) return s end -local function bin_exe(name, moredeps) +local function bin_exe(name, deps) local s = bin_settings(name) local src = Collect('src/bin/' .. name .. '/*.c') local obj = Compile(s, src) - return Link(s, 'bin/' .. name .. ".bin", {obj, libkogata, moredeps}) + return Link(s, 'bin/' .. name .. ".bin", {obj, deps}) end bin = { - bin_exe('lua', {liblua}), + -- bin_exe('lua', {liblua}), -- bin_exe('luac', {liblua}), } diff --git a/src/common/bam.lua b/src/common/bam.lua index 8b302fa..6d4a29c 100644 --- a/src/common/bam.lua +++ b/src/common/bam.lua @@ -3,6 +3,5 @@ local function lib(name) return Compile(common_settings, source) end -common_libalgo = lib('libalgo') common_libc = lib('libc') common_libkogata = lib('libkogata') diff --git a/src/common/include/algo.h b/src/common/include/algo.h deleted file mode 100644 index 80af052..0000000 --- a/src/common/include/algo.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include -#include -#include - -#define MIN(a, b) ((a)<(b)?(a):(b)) -#define MAX(a, b) ((a)>(b)?(a):(b)) -#define ABS(a) ((a)<0?-(a):(a)) - -// ============================================================= // -// FUNCTION TYPES FOR KEY-VALUE DATA STRUCTURES (HASHTBL, BTREE) // - -typedef uint32_t hash_t; -typedef hash_t (*hash_fun_t)(const void*); - -typedef int (*key_cmp_fun_t)(const void*, const void*); -typedef bool (*key_eq_fun_t)(const void*, const void*); - -typedef void (*kv_iter_fun_t)(void* key, void* value); - -// void* is considered as an unsigned integer (and not a pointer) -hash_t id_hash_fun(const void* v); -bool id_key_eq_fun(const void* a, const void* b); -int id_key_cmp_fun(const void* a, const void* b); - -// void* considered as char* -hash_t str_hash_fun(const void* v); -bool str_key_eq_fun(const void* a, const void* b); -int str_key_cmp_fun(const void* a, const void* b); - -// Freeing functions (they are of type kv_iter_fun_t) -void free_key(void* key, void* val); -void free_val(void* key, void* val); -void free_key_val(void* key, void* val); - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/include/btree.h b/src/common/include/btree.h deleted file mode 100644 index a645d66..0000000 --- a/src/common/include/btree.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include - -// A btree may contain several bindings for the same key (in that case they are not ordered) -// - btree_find returns any item with matching key, or null if none exists -// - btree_lower returns any item with matching key, or if none returns last item with smaller key -// - btree_upper returns any item with matching key, or if none returns first item with bigger key -// - btree_remove removes *all bindings* with matching key -// - btree_remove_v removes bindings with matching *key and value* -// - btree_iter_on calls iterator function on all bindings with matching key - -// Memory management is same as for hashtbl (a kv_iter_fun_t is called when an item is released) - -struct btree; -typedef struct btree btree_t; - -btree_t* create_btree(key_cmp_fun_t cf, kv_iter_fun_t on_release); -void delete_btree(btree_t *t); - -bool btree_add(btree_t *t, void* key, void* val); -void btree_remove(btree_t *t, const void* key); -void btree_remove_v(btree_t *t, const void* key, const void* value); - -void* btree_find(btree_t *i, const void* key); -void* btree_lower(btree_t *i, const void* key, void** actual_key); -void* btree_upper(btree_t *i, const void* key, void** actual_key); -void btree_iter(btree_t *i, kv_iter_fun_t f); -void btree_iter_on(btree_t *i, const void* key, kv_iter_fun_t f); - -size_t btree_count(btree_t *i); - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/include/debug.h b/src/common/include/debug.h deleted file mode 100644 index 2db5a80..0000000 --- a/src/common/include/debug.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include -#include - -void sys_panic(const char* message, const char* file, int line) -__attribute__((__noreturn__)); - -void sys_panic_assert(const char* assertion, const char* file, int line) -__attribute__((__noreturn__)); - -#define PANIC(s) sys_panic(s, __FILE__, __LINE__); -#define ASSERT(s) { if (!(s)) sys_panic_assert(#s, __FILE__, __LINE__); } - -void dbg_print(const char* str); -void dbg_printf(const char* format, ...); - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/include/hashtbl.h b/src/common/include/hashtbl.h deleted file mode 100644 index b9c7178..0000000 --- a/src/common/include/hashtbl.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include - -// Simple hashtable structure (key -> void*) -// Supports adding, seeking, removing, iterating -// When adding a binding to the table, the previous binding for same key (if exists) is removed - -// The hashtbl is allocated with malloc/free -// The keys/values are not copied by the hastbl, but when a key/value pair is removed from the -// table some operations may be required (freeing memory), so a kv_iter_fun_t is passed when the -// table is created which will be called whenever a k/v is released (on hashtbl_remove and delete_hashtbl) - -// A hashtbl may have only one binding for a given key (on add, previous binding is removed if necessary) - -struct hashtbl; -typedef struct hashtbl hashtbl_t; - -hashtbl_t* create_hashtbl(key_eq_fun_t ef, hash_fun_t hf, kv_iter_fun_t on_release); -void delete_hashtbl(hashtbl_t* ht); - -bool hashtbl_add(hashtbl_t* ht, void* key, void* v); // true = ok, false on error (OOM for instance) -void hashtbl_remove(hashtbl_t* ht, const void* key); - -void* hashtbl_find(hashtbl_t* ht, const void* key); // null when not found -void hashtbl_iter(hashtbl_t* ht, kv_iter_fun_t f); - -// hashtbl_change is particular : -// - it does NOT call malloc and uses the existing hashtbl cell -// - it does NOT call the on_release fun on the previous element -bool hashtbl_change(hashtbl_t* ht, void* key, void* v); - -size_t hashtbl_count(hashtbl_t* ht); - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/include/kogata/algo.h b/src/common/include/kogata/algo.h new file mode 100644 index 0000000..80af052 --- /dev/null +++ b/src/common/include/kogata/algo.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include + +#define MIN(a, b) ((a)<(b)?(a):(b)) +#define MAX(a, b) ((a)>(b)?(a):(b)) +#define ABS(a) ((a)<0?-(a):(a)) + +// ============================================================= // +// FUNCTION TYPES FOR KEY-VALUE DATA STRUCTURES (HASHTBL, BTREE) // + +typedef uint32_t hash_t; +typedef hash_t (*hash_fun_t)(const void*); + +typedef int (*key_cmp_fun_t)(const void*, const void*); +typedef bool (*key_eq_fun_t)(const void*, const void*); + +typedef void (*kv_iter_fun_t)(void* key, void* value); + +// void* is considered as an unsigned integer (and not a pointer) +hash_t id_hash_fun(const void* v); +bool id_key_eq_fun(const void* a, const void* b); +int id_key_cmp_fun(const void* a, const void* b); + +// void* considered as char* +hash_t str_hash_fun(const void* v); +bool str_key_eq_fun(const void* a, const void* b); +int str_key_cmp_fun(const void* a, const void* b); + +// Freeing functions (they are of type kv_iter_fun_t) +void free_key(void* key, void* val); +void free_val(void* key, void* val); +void free_key_val(void* key, void* val); + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/include/kogata/btree.h b/src/common/include/kogata/btree.h new file mode 100644 index 0000000..e796a2d --- /dev/null +++ b/src/common/include/kogata/btree.h @@ -0,0 +1,33 @@ +#pragma once + +#include + +// A btree may contain several bindings for the same key (in that case they are not ordered) +// - btree_find returns any item with matching key, or null if none exists +// - btree_lower returns any item with matching key, or if none returns last item with smaller key +// - btree_upper returns any item with matching key, or if none returns first item with bigger key +// - btree_remove removes *all bindings* with matching key +// - btree_remove_v removes bindings with matching *key and value* +// - btree_iter_on calls iterator function on all bindings with matching key + +// Memory management is same as for hashtbl (a kv_iter_fun_t is called when an item is released) + +struct btree; +typedef struct btree btree_t; + +btree_t* create_btree(key_cmp_fun_t cf, kv_iter_fun_t on_release); +void delete_btree(btree_t *t); + +bool btree_add(btree_t *t, void* key, void* val); +void btree_remove(btree_t *t, const void* key); +void btree_remove_v(btree_t *t, const void* key, const void* value); + +void* btree_find(btree_t *i, const void* key); +void* btree_lower(btree_t *i, const void* key, void** actual_key); +void* btree_upper(btree_t *i, const void* key, void** actual_key); +void btree_iter(btree_t *i, kv_iter_fun_t f); +void btree_iter_on(btree_t *i, const void* key, kv_iter_fun_t f); + +size_t btree_count(btree_t *i); + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/include/kogata/debug.h b/src/common/include/kogata/debug.h new file mode 100644 index 0000000..2db5a80 --- /dev/null +++ b/src/common/include/kogata/debug.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +void sys_panic(const char* message, const char* file, int line) +__attribute__((__noreturn__)); + +void sys_panic_assert(const char* assertion, const char* file, int line) +__attribute__((__noreturn__)); + +#define PANIC(s) sys_panic(s, __FILE__, __LINE__); +#define ASSERT(s) { if (!(s)) sys_panic_assert(#s, __FILE__, __LINE__); } + +void dbg_print(const char* str); +void dbg_printf(const char* format, ...); + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/include/kogata/hashtbl.h b/src/common/include/kogata/hashtbl.h new file mode 100644 index 0000000..e8f327c --- /dev/null +++ b/src/common/include/kogata/hashtbl.h @@ -0,0 +1,35 @@ +#pragma once + +#include + +// Simple hashtable structure (key -> void*) +// Supports adding, seeking, removing, iterating +// When adding a binding to the table, the previous binding for same key (if exists) is removed + +// The hashtbl is allocated with malloc/free +// The keys/values are not copied by the hastbl, but when a key/value pair is removed from the +// table some operations may be required (freeing memory), so a kv_iter_fun_t is passed when the +// table is created which will be called whenever a k/v is released (on hashtbl_remove and delete_hashtbl) + +// A hashtbl may have only one binding for a given key (on add, previous binding is removed if necessary) + +struct hashtbl; +typedef struct hashtbl hashtbl_t; + +hashtbl_t* create_hashtbl(key_eq_fun_t ef, hash_fun_t hf, kv_iter_fun_t on_release); +void delete_hashtbl(hashtbl_t* ht); + +bool hashtbl_add(hashtbl_t* ht, void* key, void* v); // true = ok, false on error (OOM for instance) +void hashtbl_remove(hashtbl_t* ht, const void* key); + +void* hashtbl_find(hashtbl_t* ht, const void* key); // null when not found +void hashtbl_iter(hashtbl_t* ht, kv_iter_fun_t f); + +// hashtbl_change is particular : +// - it does NOT call malloc and uses the existing hashtbl cell +// - it does NOT call the on_release fun on the previous element +bool hashtbl_change(hashtbl_t* ht, void* key, void* v); + +size_t hashtbl_count(hashtbl_t* ht); + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/include/kogata/malloc.h b/src/common/include/kogata/malloc.h new file mode 100644 index 0000000..e55c25e --- /dev/null +++ b/src/common/include/kogata/malloc.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include + +// Header is in common/, but implementation is not. + +void* malloc(size_t sz); +void free(void* ptr); +void* calloc(size_t nmemb, size_t sz); +void* realloc(void* ptr, size_t sz); + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/include/kogata/mutex.h b/src/common/include/kogata/mutex.h new file mode 100644 index 0000000..88c077e --- /dev/null +++ b/src/common/include/kogata/mutex.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +#define MUTEX_LOCKED 1 +#define MUTEX_UNLOCKED 0 + + +typedef uint32_t mutex_t; + +void mutex_lock(mutex_t* mutex); //wait for mutex to be free +bool mutex_try_lock(mutex_t* mutex); //lock mutex only if free, returns true when locked, false when was busy +void mutex_unlock(mutex_t* mutex); + +// the mutex code assumes a yield() function is defined somewhere +void yield(); + +#define STATIC_MUTEX(name) static mutex_t name __attribute__((section("locks"))) = MUTEX_UNLOCKED; + + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/include/kogata/printf.h b/src/common/include/kogata/printf.h new file mode 100644 index 0000000..b4e1c1b --- /dev/null +++ b/src/common/include/kogata/printf.h @@ -0,0 +1,10 @@ +#pragma once + +#include +#include +#include + +int snprintf(char* s, size_t n, const char* format, ...); +int vsnprintf(char* s, size_t n, const char* format, va_list arg); + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/include/kogata/region_alloc.h b/src/common/include/kogata/region_alloc.h new file mode 100644 index 0000000..d314bd5 --- /dev/null +++ b/src/common/include/kogata/region_alloc.h @@ -0,0 +1,32 @@ +#pragma once + +// Virtual memory region allocator + +// This is entirely thread-safe + +#include +#include +#include + +struct region_info; + +typedef bool (*map_page_fun_t)(void* addr); // map a single page (used by region allocator) + +typedef struct region_info { + void* addr; + size_t size; + char* type; +} region_info_t; + +// rsvd_end : when used for kernel memory region management, a reserved region +// exists between begin (=K_HIGHHALF_ADDR) and the end of kernel static data +// for user processes, use rsvd_end = begin (no reserved region) +void region_allocator_init(void* begin, void* rsvd_end, void* end, map_page_fun_t map); + +void* region_alloc(size_t size, char* type); // returns 0 on error +region_info_t *find_region(void* addr); +void region_free(void* addr); + +void dbg_print_region_info(); + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/include/kogata/slab_alloc.h b/src/common/include/kogata/slab_alloc.h new file mode 100644 index 0000000..1191057 --- /dev/null +++ b/src/common/include/kogata/slab_alloc.h @@ -0,0 +1,45 @@ +#pragma once + +// Self-contained piece of library : a slab allocator... +// Depends on page_alloc_fun_t and page_free_fun_t : a couple of functions +// that can allocate/free multiples of one page at a time + +#include +#include +#include + + +#if defined(__linux__) +//redefine necessary stuff +#include // standard linux assert.h +#define ASSERT assert +#include +#define dbg_printf printf +#else +#include +#endif + +#define PAGE_SIZE 0x1000 + +// expected format for the array of slab_type_t given to slab_create : +// an array of slab_type descriptors, with last descriptor full of zeroes +// and with obj_size increasing (strictly) in the array +typedef struct slab_type { + const char *descr; + size_t obj_size; + size_t pages_per_cache; +} slab_type_t; + +struct mem_allocator; +typedef struct mem_allocator mem_allocator_t; + +typedef void* (*page_alloc_fun_t)(size_t bytes); +typedef void (*page_free_fun_t)(void* ptr); + +mem_allocator_t* create_slab_allocator(const slab_type_t *types, page_alloc_fun_t af, page_free_fun_t ff); +void destroy_slab_allocator(mem_allocator_t*); + +void* slab_alloc(mem_allocator_t* a, size_t sz); +void slab_free(mem_allocator_t* a, void* ptr); + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/include/malloc.h b/src/common/include/malloc.h deleted file mode 100644 index e55c25e..0000000 --- a/src/common/include/malloc.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include -#include - -// Header is in common/, but implementation is not. - -void* malloc(size_t sz); -void free(void* ptr); -void* calloc(size_t nmemb, size_t sz); -void* realloc(void* ptr, size_t sz); - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/include/mutex.h b/src/common/include/mutex.h deleted file mode 100644 index 88c077e..0000000 --- a/src/common/include/mutex.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include -#include - -#define MUTEX_LOCKED 1 -#define MUTEX_UNLOCKED 0 - - -typedef uint32_t mutex_t; - -void mutex_lock(mutex_t* mutex); //wait for mutex to be free -bool mutex_try_lock(mutex_t* mutex); //lock mutex only if free, returns true when locked, false when was busy -void mutex_unlock(mutex_t* mutex); - -// the mutex code assumes a yield() function is defined somewhere -void yield(); - -#define STATIC_MUTEX(name) static mutex_t name __attribute__((section("locks"))) = MUTEX_UNLOCKED; - - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/include/printf.h b/src/common/include/printf.h deleted file mode 100644 index b4e1c1b..0000000 --- a/src/common/include/printf.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include -#include -#include - -int snprintf(char* s, size_t n, const char* format, ...); -int vsnprintf(char* s, size_t n, const char* format, va_list arg); - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/include/region_alloc.h b/src/common/include/region_alloc.h deleted file mode 100644 index d314bd5..0000000 --- a/src/common/include/region_alloc.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -// Virtual memory region allocator - -// This is entirely thread-safe - -#include -#include -#include - -struct region_info; - -typedef bool (*map_page_fun_t)(void* addr); // map a single page (used by region allocator) - -typedef struct region_info { - void* addr; - size_t size; - char* type; -} region_info_t; - -// rsvd_end : when used for kernel memory region management, a reserved region -// exists between begin (=K_HIGHHALF_ADDR) and the end of kernel static data -// for user processes, use rsvd_end = begin (no reserved region) -void region_allocator_init(void* begin, void* rsvd_end, void* end, map_page_fun_t map); - -void* region_alloc(size_t size, char* type); // returns 0 on error -region_info_t *find_region(void* addr); -void region_free(void* addr); - -void dbg_print_region_info(); - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/include/slab_alloc.h b/src/common/include/slab_alloc.h deleted file mode 100644 index c8d5d6c..0000000 --- a/src/common/include/slab_alloc.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -// Self-contained piece of library : a slab allocator... -// Depends on page_alloc_fun_t and page_free_fun_t : a couple of functions -// that can allocate/free multiples of one page at a time - -#include -#include -#include - - -#if defined(__linux__) -//redefine necessary stuff -#include // standard linux assert.h -#define ASSERT assert -#include -#define dbg_printf printf -#else -#include -#endif - -#define PAGE_SIZE 0x1000 - -// expected format for the array of slab_type_t given to slab_create : -// an array of slab_type descriptors, with last descriptor full of zeroes -// and with obj_size increasing (strictly) in the array -typedef struct slab_type { - const char *descr; - size_t obj_size; - size_t pages_per_cache; -} slab_type_t; - -struct mem_allocator; -typedef struct mem_allocator mem_allocator_t; - -typedef void* (*page_alloc_fun_t)(size_t bytes); -typedef void (*page_free_fun_t)(void* ptr); - -mem_allocator_t* create_slab_allocator(const slab_type_t *types, page_alloc_fun_t af, page_free_fun_t ff); -void destroy_slab_allocator(mem_allocator_t*); - -void* slab_alloc(mem_allocator_t* a, size_t sz); -void slab_free(mem_allocator_t* a, void* ptr); - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/libalgo/btree.c b/src/common/libalgo/btree.c deleted file mode 100644 index d1bfd18..0000000 --- a/src/common/libalgo/btree.c +++ /dev/null @@ -1,343 +0,0 @@ -#include -#include - -#include - -typedef struct btree_item { - void *key, *val; - - int height; - struct btree_item *left, *right; -} btree_item_t; - -struct btree { - key_cmp_fun_t cf; - kv_iter_fun_t releasef; - - btree_item_t *root; - int nitems; -}; - -btree_t* create_btree(key_cmp_fun_t cf, kv_iter_fun_t relf) { - btree_t* t = (btree_t*)malloc(sizeof(btree_t)); - - if (t == 0) return 0; - - t->cf = cf; - t->releasef = relf; - - t->root = 0; - t->nitems = 0; - - return t; -} - -void _btree_delete_item_rec(btree_item_t *i,kv_iter_fun_t relf) { - if (i == 0) return; - - _btree_delete_item_rec(i->left, relf); - _btree_delete_item_rec(i->right, relf); - - if (relf) relf(i->key, i->val); - free(i); -} -void delete_btree(btree_t *t) { - _btree_delete_item_rec(t->root, t->releasef); - - free(t); -} - -size_t btree_count(btree_t *i) { - return i->nitems; -} - -// ============== // -// TREE ROTATIONS // -// ============== // - -static inline int height(btree_item_t *i) { - if (i == 0) return 0; - return i->height; -} - -void btree_recalc_height(btree_item_t *i) { - if (i == 0) return; - - i->height = MAX(height(i->left), height(i->right)) + 1; -} - -btree_item_t* btree_rotate_left(btree_item_t *i) { - // I(X(a, b), Y) -> a X b I Y -> X(a, I(b, Y)) - - btree_item_t *x = i->left; - if (x == 0) return i; - btree_item_t *b = x->right; - - x->right = i; - i->left = b; - - btree_recalc_height(i); - btree_recalc_height(x); - - return x; -} - -btree_item_t* btree_rotate_right(btree_item_t *i) { - // I(X, Y(a,b)) -> X I a Y b -> Y(I(X, a), b) - - btree_item_t *y = i->right; - if (y == 0) return i; - btree_item_t *a = y->left; - - y->left = i; - i->right = a; - - btree_recalc_height(i); - btree_recalc_height(y); - - return y; -} - -btree_item_t* btree_equilibrate(btree_item_t *i) { - if (i == 0) return 0; - - while (height(i->left) - height(i->right) >= 2) - i = btree_rotate_left(i); - - while (height(i->right) - height(i->left) >= 2) - i = btree_rotate_right(i); - - return i; -} - -// =================== // -// ADDING AND DELETING // -// =================== // - -btree_item_t* _btree_insert(btree_t *t, btree_item_t *root, btree_item_t *i) { - if (root == 0) return i; - - if (t->cf(i->key, root->key) <= 0) { - root->left = _btree_insert(t, root->left, i); - } else { - root->right = _btree_insert(t, root->right, i); - } - btree_recalc_height(root); - - return btree_equilibrate(root); -} -bool btree_add(btree_t *t, void* key, void* val) { - btree_item_t *x = (btree_item_t*)malloc(sizeof(btree_item_t)); - if (x == 0) return false; - - x->key = key; - x->val = val; - x->left = x->right = 0; - btree_recalc_height(x); - - t->root = _btree_insert(t, t->root, x); - t->nitems++; - - return true; -} - -btree_item_t *_btree_extract_smallest(btree_item_t *i, btree_item_t **out_smallest) { - ASSERT(i != 0); - if (i->left == 0) { - *out_smallest = i; - return i->right; - } else { - i->left = _btree_extract_smallest(i->left, out_smallest); - btree_recalc_height(i); - return btree_equilibrate(i); - } -} -btree_item_t *_btree_remove_aux(btree_t *t, btree_item_t *i, const void* key) { - if (i == 0) return 0; - - int c = t->cf(key, i->key); - if (c < 0) { - i->left = _btree_remove_aux(t, i->left, key); - return btree_equilibrate(i); - } else if (c > 0) { - i->right = _btree_remove_aux(t, i->right, key); - return btree_equilibrate(i); - } else { - // remove item i - - btree_item_t *new_i; - if (i->right == 0 || i->left == 0) { - new_i = (i->right == 0 ? i->left : i->right); - } else { - btree_item_t *new_i_right = _btree_extract_smallest(i->right, &new_i); - - new_i->left = i->left; - new_i->right = new_i_right; - - btree_recalc_height(new_i); - new_i = btree_equilibrate(new_i); - } - - if (t->releasef) t->releasef(i->key, i->val); - free(i); - t->nitems--; - - return _btree_remove_aux(t, new_i, key); // loop because several elements may correspond - } -} -void btree_remove(btree_t *t, const void* key) { - t->root = _btree_remove_aux(t, t->root, key); -} - -btree_item_t *_btree_extract_smallest_v(btree_item_t *i, btree_item_t **out_smallest) { - ASSERT(i != 0); - if (i->left == 0) { - *out_smallest = i; - return i->right; - } else { - i->left = _btree_extract_smallest_v(i->left, out_smallest); - btree_recalc_height(i); - return btree_equilibrate(i); - } -} -btree_item_t *_btree_remove_aux_v(btree_t *t, btree_item_t *i, const void* key, const void* val) { - if (i == 0) return 0; - - int c = t->cf(key, i->key); - if (c < 0) { - i->left = _btree_remove_aux_v(t, i->left, key, val); - return btree_equilibrate(i); - } else if (c > 0) { - i->right = _btree_remove_aux_v(t, i->right, key, val); - return btree_equilibrate(i); - } else if (i->val == val) { - // remove item i - - btree_item_t *new_i; - if (i->right == 0 || i->left == 0) { - new_i = (i->right == 0 ? i->left : i->right); - } else { - btree_item_t *new_i_right = _btree_extract_smallest_v(i->right, &new_i); - - new_i->left = i->left; - new_i->right = new_i_right; - - btree_recalc_height(new_i); - new_i = btree_equilibrate(new_i); - } - - if (t->releasef) t->releasef(i->key, i->val); - free(i); - t->nitems--; - - return _btree_remove_aux_v(t, new_i, key, val); // loop because several elements may correspond - } else { - i->left = _btree_remove_aux_v(t, i->left, key, val); - i->right = _btree_remove_aux_v(t, i->right, key, val); - btree_recalc_height(i); - return btree_equilibrate(i); - } -} -void btree_remove_v(btree_t *t, const void* key, const void* val) { - t->root = _btree_remove_aux_v(t, t->root, key, val); -} - -// ======================== // -// LOOKING UP AND ITERATING // -// ======================== // - -btree_item_t *_btree_find_aux(btree_t *t, btree_item_t *i, const void* key) { - if (i == 0) return 0; - - int c = t->cf(key, i->key); - if (c == 0) { - return i; - } else if (c < 0) { - return _btree_find_aux(t, i->left, key); - } else { - return _btree_find_aux(t, i->right, key); - } -} -void* btree_find(btree_t *t, const void* key) { - - btree_item_t *i = _btree_find_aux(t, t->root, key); - - if (i == 0) return 0; - return i->val; -} - -btree_item_t *_btree_lower_aux(btree_t *t, btree_item_t *i, const void* key) { - if (i == 0) return 0; - - int c = t->cf(key, i->key); - if (c == 0) { - return i; - } else if (c < 0) { - return _btree_lower_aux(t, i->left, key); - } else { - btree_item_t *r = _btree_lower_aux(t, i->right, key); - if (r == 0) r = i; - return r; - } -} -void* btree_lower(btree_t *t, const void* key, void** actual_key) { - btree_item_t *i = _btree_lower_aux(t, t->root, key); - - if (i == 0) return 0; - if (actual_key != 0) *actual_key = i->key; - return i->val; -} - -btree_item_t *_btree_upper_aux(btree_t *t, btree_item_t *i, const void* key) { - if (i == 0) return 0; - - int c = t->cf(key, i->key); - if (c == 0) { - return i; - } else if (c < 0) { - btree_item_t *r = _btree_upper_aux(t, i->left, key); - if (r == 0) r = i; - return r; - } else { - return _btree_upper_aux(t, i->right, key); - } -} -void* btree_upper(btree_t *t, const void* key, void** actual_key) { - btree_item_t *i = _btree_upper_aux(t, t->root, key); - - if (i == 0) return 0; - if (actual_key != 0) *actual_key = i->key; - return i->val; -} - - -void _btree_iter_aux(btree_item_t *i, kv_iter_fun_t f) { - if (i == 0) return; - - _btree_iter_aux(i->left, f); - f(i->key, i->val); - _btree_iter_aux(i->right, f); -} -void btree_iter(btree_t *t, kv_iter_fun_t f) { - _btree_iter_aux(t->root, f); -} - -void _btree_iter_on_aux(btree_t *t, btree_item_t *i, const void* key, kv_iter_fun_t f) { - if (i == 0) return; - - int c = t->cf(key, i->key); - if (c == 0) { - _btree_iter_on_aux(t, i->left, key, f); - f(i->key, i->val); - _btree_iter_on_aux(t, i->right, key, f); - } else if (c < 0) { - _btree_iter_on_aux(t, i->left, key, f); - } else { - _btree_iter_on_aux(t, i->right, key, f); - } -} -void btree_iter_on(btree_t *t, const void* key, kv_iter_fun_t f) { - _btree_iter_on_aux(t, t->root, key, f); -} - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/libalgo/hashtbl.c b/src/common/libalgo/hashtbl.c deleted file mode 100644 index 0284d75..0000000 --- a/src/common/libalgo/hashtbl.c +++ /dev/null @@ -1,177 +0,0 @@ -#include -#include - -#include - -#define DEFAULT_HT_INIT_SIZE 16 -#define SLOT_OF_HASH(k, nslots) (((size_t)(k)*21179)%(size_t)(nslots)) - -typedef struct hashtbl_item { - void* key; - void* val; - struct hashtbl_item *next; -} hashtbl_item_t; - -// When nitems > size * 3/4, size is multiplied by two -// When nitems < size * 1/4, size is divided by two -struct hashtbl { - key_eq_fun_t ef; - hash_fun_t hf; - kv_iter_fun_t releasef; - size_t size, nitems; - hashtbl_item_t **items; -}; - -hashtbl_t *create_hashtbl(key_eq_fun_t ef, hash_fun_t hf, kv_iter_fun_t on_release) { - hashtbl_t *ht = (hashtbl_t*)malloc(sizeof(hashtbl_t)); - if (ht == 0) return 0; - - ht->ef = ef; - ht->hf = hf; - ht->releasef = on_release; - - ht->size = DEFAULT_HT_INIT_SIZE; - ht->nitems = 0; - - ht->items = (hashtbl_item_t**)malloc(ht->size * sizeof(hashtbl_item_t*)); - if (ht->items == 0) { - free(ht); - return 0; - } - - for (size_t i = 0; i < ht->size; i++) ht->items[i] = 0; - - return ht; -} - -void delete_hashtbl(hashtbl_t *ht) { - // Free items - for (size_t i = 0; i < ht->size; i++) { - while (ht->items[i] != 0) { - hashtbl_item_t *x = ht->items[i]; - ht->items[i] = x->next; - - if (ht->releasef) ht->releasef(x->key, x->val); - - free(x); - } - } - - // Free table - free(ht->items); - free(ht); -} - -void hashtbl_check_size(hashtbl_t *ht) { - size_t nsize = 0; - if (4 * ht->nitems < ht->size) nsize = ht->size / 2; - if (4 * ht->nitems > 3 * ht->size) nsize = ht->size * 2; - - if (nsize != 0 && nsize >= DEFAULT_HT_INIT_SIZE) { - hashtbl_item_t **nitems = (hashtbl_item_t**)malloc(nsize * sizeof(hashtbl_item_t*)); - if (nitems == 0) return; // if we can't realloc, too bad, we just lose space/efficienty - - for (size_t i = 0; i < nsize; i++) nitems[i] = 0; - - // rehash - for (size_t i = 0; i < ht->size; i++) { - while (ht->items[i] != 0) { - hashtbl_item_t *x = ht->items[i]; - ht->items[i] = x->next; - - size_t slot = SLOT_OF_HASH(ht->hf(x->key), nsize); - x->next = nitems[slot]; - nitems[slot] = x; - } - } - free(ht->items); - ht->size = nsize; - ht->items = nitems; - } -} - -bool hashtbl_add(hashtbl_t *ht, void* key, void* v) { - hashtbl_item_t *i = (hashtbl_item_t*)malloc(sizeof(hashtbl_item_t)); - if (i == 0) return false; // OOM - - // make sure item is not already present - hashtbl_remove(ht, key); - - size_t slot = SLOT_OF_HASH(ht->hf(key), ht->size); - - i->key = key; - i->val = v; - i->next = ht->items[slot]; - ht->items[slot] = i; - ht->nitems++; - - hashtbl_check_size(ht); - - return true; -} - -void hashtbl_remove(hashtbl_t* ht, const void* key) { - size_t slot = SLOT_OF_HASH(ht->hf(key), ht->size); - - if (ht->items[slot] == 0) return; - - hashtbl_item_t *x = 0; - - if (ht->ef(ht->items[slot]->key, key)) { - x = ht->items[slot]; - ht->items[slot] = x->next; - } else { - for (hashtbl_item_t *i = ht->items[slot]; i->next != 0; i = i->next) { - if (ht->ef(i->next->key, key)) { - x = i->next; - i->next = x->next; - break; - } - } - } - - if (x != 0) { - ht->nitems--; - if (ht->releasef) ht->releasef(x->key, x->val); - free(x); - } - - hashtbl_check_size(ht); -} - -void* hashtbl_find(hashtbl_t* ht, const void* key) { - size_t slot = SLOT_OF_HASH(ht->hf(key), ht->size); - - for (hashtbl_item_t *i = ht->items[slot]; i != 0; i = i->next) { - if (ht->ef(i->key, key)) return i->val; - } - - return 0; -} - -void hashtbl_iter(hashtbl_t *ht, kv_iter_fun_t f) { - for (size_t s = 0; s < ht->size; s++) { - for (hashtbl_item_t *i = ht->items[s]; i != 0; i = i->next) { - f(i->key, i->val); - } - } -} - -size_t hashtbl_count(hashtbl_t* ht) { - return ht->nitems; -} - -bool hashtbl_change(hashtbl_t* ht, void* key, void* newval) { - size_t slot = SLOT_OF_HASH(ht->hf(key), ht->size); - - for (hashtbl_item_t *i = ht->items[slot]; i != 0; i = i->next) { - if (ht->ef(i->key, key)) { - i->val = newval; - return true; - } - } - - return false; -} - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/libalgo/keyval.c b/src/common/libalgo/keyval.c deleted file mode 100644 index 528fa90..0000000 --- a/src/common/libalgo/keyval.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include - -#include - -// Hashing and comparing - -hash_t id_hash_fun(const void* v) { - return (hash_t)v; -} - -hash_t str_hash_fun(const void* v) { - hash_t h = 712; - for (char* s = (char*)v; *s != 0; s++) { - h = h * 101 + *s; - } - return h; -} - -bool id_key_eq_fun(const void* a, const void* b) { - return a == b; -} - -bool str_key_eq_fun(const void* a, const void* b) { - return strcmp((const char*)a, (const char*)b) == 0; -} - -int id_key_cmp_fun(const void* a, const void* b) { - return (a == b ? 0 : (a < b ? -1 : 1)); -} - -int str_key_cmp_fun(const void* a, const void* b) { - return strcmp((const char*)a, (const char*)b); -} - -// Freeing functions - -void free_key(void* key, void* val) { - free(key); -} - -void free_val(void* key, void* val) { - free(val); -} - -void free_key_val(void* key, void* val) { - free(key); - free(val); -} - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/libc/printf.c b/src/common/libc/printf.c index 8618741..d1671c3 100644 --- a/src/common/libc/printf.c +++ b/src/common/libc/printf.c @@ -1,6 +1,7 @@ -#include #include +#include + int snprintf(char * buff, size_t len, const char *format, ...) { va_list ap; diff --git a/src/common/libc/string.c b/src/common/libc/string.c index 90cea34..e1ed21e 100644 --- a/src/common/libc/string.c +++ b/src/common/libc/string.c @@ -1,6 +1,6 @@ #include -#include +#include size_t strlen(const char* str) { size_t ret = 0; diff --git a/src/common/libkogata/btree.c b/src/common/libkogata/btree.c new file mode 100644 index 0000000..dc5f11f --- /dev/null +++ b/src/common/libkogata/btree.c @@ -0,0 +1,343 @@ +#include +#include + +#include + +typedef struct btree_item { + void *key, *val; + + int height; + struct btree_item *left, *right; +} btree_item_t; + +struct btree { + key_cmp_fun_t cf; + kv_iter_fun_t releasef; + + btree_item_t *root; + int nitems; +}; + +btree_t* create_btree(key_cmp_fun_t cf, kv_iter_fun_t relf) { + btree_t* t = (btree_t*)malloc(sizeof(btree_t)); + + if (t == 0) return 0; + + t->cf = cf; + t->releasef = relf; + + t->root = 0; + t->nitems = 0; + + return t; +} + +void _btree_delete_item_rec(btree_item_t *i,kv_iter_fun_t relf) { + if (i == 0) return; + + _btree_delete_item_rec(i->left, relf); + _btree_delete_item_rec(i->right, relf); + + if (relf) relf(i->key, i->val); + free(i); +} +void delete_btree(btree_t *t) { + _btree_delete_item_rec(t->root, t->releasef); + + free(t); +} + +size_t btree_count(btree_t *i) { + return i->nitems; +} + +// ============== // +// TREE ROTATIONS // +// ============== // + +static inline int height(btree_item_t *i) { + if (i == 0) return 0; + return i->height; +} + +void btree_recalc_height(btree_item_t *i) { + if (i == 0) return; + + i->height = MAX(height(i->left), height(i->right)) + 1; +} + +btree_item_t* btree_rotate_left(btree_item_t *i) { + // I(X(a, b), Y) -> a X b I Y -> X(a, I(b, Y)) + + btree_item_t *x = i->left; + if (x == 0) return i; + btree_item_t *b = x->right; + + x->right = i; + i->left = b; + + btree_recalc_height(i); + btree_recalc_height(x); + + return x; +} + +btree_item_t* btree_rotate_right(btree_item_t *i) { + // I(X, Y(a,b)) -> X I a Y b -> Y(I(X, a), b) + + btree_item_t *y = i->right; + if (y == 0) return i; + btree_item_t *a = y->left; + + y->left = i; + i->right = a; + + btree_recalc_height(i); + btree_recalc_height(y); + + return y; +} + +btree_item_t* btree_equilibrate(btree_item_t *i) { + if (i == 0) return 0; + + while (height(i->left) - height(i->right) >= 2) + i = btree_rotate_left(i); + + while (height(i->right) - height(i->left) >= 2) + i = btree_rotate_right(i); + + return i; +} + +// =================== // +// ADDING AND DELETING // +// =================== // + +btree_item_t* _btree_insert(btree_t *t, btree_item_t *root, btree_item_t *i) { + if (root == 0) return i; + + if (t->cf(i->key, root->key) <= 0) { + root->left = _btree_insert(t, root->left, i); + } else { + root->right = _btree_insert(t, root->right, i); + } + btree_recalc_height(root); + + return btree_equilibrate(root); +} +bool btree_add(btree_t *t, void* key, void* val) { + btree_item_t *x = (btree_item_t*)malloc(sizeof(btree_item_t)); + if (x == 0) return false; + + x->key = key; + x->val = val; + x->left = x->right = 0; + btree_recalc_height(x); + + t->root = _btree_insert(t, t->root, x); + t->nitems++; + + return true; +} + +btree_item_t *_btree_extract_smallest(btree_item_t *i, btree_item_t **out_smallest) { + ASSERT(i != 0); + if (i->left == 0) { + *out_smallest = i; + return i->right; + } else { + i->left = _btree_extract_smallest(i->left, out_smallest); + btree_recalc_height(i); + return btree_equilibrate(i); + } +} +btree_item_t *_btree_remove_aux(btree_t *t, btree_item_t *i, const void* key) { + if (i == 0) return 0; + + int c = t->cf(key, i->key); + if (c < 0) { + i->left = _btree_remove_aux(t, i->left, key); + return btree_equilibrate(i); + } else if (c > 0) { + i->right = _btree_remove_aux(t, i->right, key); + return btree_equilibrate(i); + } else { + // remove item i + + btree_item_t *new_i; + if (i->right == 0 || i->left == 0) { + new_i = (i->right == 0 ? i->left : i->right); + } else { + btree_item_t *new_i_right = _btree_extract_smallest(i->right, &new_i); + + new_i->left = i->left; + new_i->right = new_i_right; + + btree_recalc_height(new_i); + new_i = btree_equilibrate(new_i); + } + + if (t->releasef) t->releasef(i->key, i->val); + free(i); + t->nitems--; + + return _btree_remove_aux(t, new_i, key); // loop because several elements may correspond + } +} +void btree_remove(btree_t *t, const void* key) { + t->root = _btree_remove_aux(t, t->root, key); +} + +btree_item_t *_btree_extract_smallest_v(btree_item_t *i, btree_item_t **out_smallest) { + ASSERT(i != 0); + if (i->left == 0) { + *out_smallest = i; + return i->right; + } else { + i->left = _btree_extract_smallest_v(i->left, out_smallest); + btree_recalc_height(i); + return btree_equilibrate(i); + } +} +btree_item_t *_btree_remove_aux_v(btree_t *t, btree_item_t *i, const void* key, const void* val) { + if (i == 0) return 0; + + int c = t->cf(key, i->key); + if (c < 0) { + i->left = _btree_remove_aux_v(t, i->left, key, val); + return btree_equilibrate(i); + } else if (c > 0) { + i->right = _btree_remove_aux_v(t, i->right, key, val); + return btree_equilibrate(i); + } else if (i->val == val) { + // remove item i + + btree_item_t *new_i; + if (i->right == 0 || i->left == 0) { + new_i = (i->right == 0 ? i->left : i->right); + } else { + btree_item_t *new_i_right = _btree_extract_smallest_v(i->right, &new_i); + + new_i->left = i->left; + new_i->right = new_i_right; + + btree_recalc_height(new_i); + new_i = btree_equilibrate(new_i); + } + + if (t->releasef) t->releasef(i->key, i->val); + free(i); + t->nitems--; + + return _btree_remove_aux_v(t, new_i, key, val); // loop because several elements may correspond + } else { + i->left = _btree_remove_aux_v(t, i->left, key, val); + i->right = _btree_remove_aux_v(t, i->right, key, val); + btree_recalc_height(i); + return btree_equilibrate(i); + } +} +void btree_remove_v(btree_t *t, const void* key, const void* val) { + t->root = _btree_remove_aux_v(t, t->root, key, val); +} + +// ======================== // +// LOOKING UP AND ITERATING // +// ======================== // + +btree_item_t *_btree_find_aux(btree_t *t, btree_item_t *i, const void* key) { + if (i == 0) return 0; + + int c = t->cf(key, i->key); + if (c == 0) { + return i; + } else if (c < 0) { + return _btree_find_aux(t, i->left, key); + } else { + return _btree_find_aux(t, i->right, key); + } +} +void* btree_find(btree_t *t, const void* key) { + + btree_item_t *i = _btree_find_aux(t, t->root, key); + + if (i == 0) return 0; + return i->val; +} + +btree_item_t *_btree_lower_aux(btree_t *t, btree_item_t *i, const void* key) { + if (i == 0) return 0; + + int c = t->cf(key, i->key); + if (c == 0) { + return i; + } else if (c < 0) { + return _btree_lower_aux(t, i->left, key); + } else { + btree_item_t *r = _btree_lower_aux(t, i->right, key); + if (r == 0) r = i; + return r; + } +} +void* btree_lower(btree_t *t, const void* key, void** actual_key) { + btree_item_t *i = _btree_lower_aux(t, t->root, key); + + if (i == 0) return 0; + if (actual_key != 0) *actual_key = i->key; + return i->val; +} + +btree_item_t *_btree_upper_aux(btree_t *t, btree_item_t *i, const void* key) { + if (i == 0) return 0; + + int c = t->cf(key, i->key); + if (c == 0) { + return i; + } else if (c < 0) { + btree_item_t *r = _btree_upper_aux(t, i->left, key); + if (r == 0) r = i; + return r; + } else { + return _btree_upper_aux(t, i->right, key); + } +} +void* btree_upper(btree_t *t, const void* key, void** actual_key) { + btree_item_t *i = _btree_upper_aux(t, t->root, key); + + if (i == 0) return 0; + if (actual_key != 0) *actual_key = i->key; + return i->val; +} + + +void _btree_iter_aux(btree_item_t *i, kv_iter_fun_t f) { + if (i == 0) return; + + _btree_iter_aux(i->left, f); + f(i->key, i->val); + _btree_iter_aux(i->right, f); +} +void btree_iter(btree_t *t, kv_iter_fun_t f) { + _btree_iter_aux(t->root, f); +} + +void _btree_iter_on_aux(btree_t *t, btree_item_t *i, const void* key, kv_iter_fun_t f) { + if (i == 0) return; + + int c = t->cf(key, i->key); + if (c == 0) { + _btree_iter_on_aux(t, i->left, key, f); + f(i->key, i->val); + _btree_iter_on_aux(t, i->right, key, f); + } else if (c < 0) { + _btree_iter_on_aux(t, i->left, key, f); + } else { + _btree_iter_on_aux(t, i->right, key, f); + } +} +void btree_iter_on(btree_t *t, const void* key, kv_iter_fun_t f) { + _btree_iter_on_aux(t, t->root, key, f); +} + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/libkogata/hashtbl.c b/src/common/libkogata/hashtbl.c new file mode 100644 index 0000000..b0097cd --- /dev/null +++ b/src/common/libkogata/hashtbl.c @@ -0,0 +1,177 @@ +#include +#include + +#include + +#define DEFAULT_HT_INIT_SIZE 16 +#define SLOT_OF_HASH(k, nslots) (((size_t)(k)*21179)%(size_t)(nslots)) + +typedef struct hashtbl_item { + void* key; + void* val; + struct hashtbl_item *next; +} hashtbl_item_t; + +// When nitems > size * 3/4, size is multiplied by two +// When nitems < size * 1/4, size is divided by two +struct hashtbl { + key_eq_fun_t ef; + hash_fun_t hf; + kv_iter_fun_t releasef; + size_t size, nitems; + hashtbl_item_t **items; +}; + +hashtbl_t *create_hashtbl(key_eq_fun_t ef, hash_fun_t hf, kv_iter_fun_t on_release) { + hashtbl_t *ht = (hashtbl_t*)malloc(sizeof(hashtbl_t)); + if (ht == 0) return 0; + + ht->ef = ef; + ht->hf = hf; + ht->releasef = on_release; + + ht->size = DEFAULT_HT_INIT_SIZE; + ht->nitems = 0; + + ht->items = (hashtbl_item_t**)malloc(ht->size * sizeof(hashtbl_item_t*)); + if (ht->items == 0) { + free(ht); + return 0; + } + + for (size_t i = 0; i < ht->size; i++) ht->items[i] = 0; + + return ht; +} + +void delete_hashtbl(hashtbl_t *ht) { + // Free items + for (size_t i = 0; i < ht->size; i++) { + while (ht->items[i] != 0) { + hashtbl_item_t *x = ht->items[i]; + ht->items[i] = x->next; + + if (ht->releasef) ht->releasef(x->key, x->val); + + free(x); + } + } + + // Free table + free(ht->items); + free(ht); +} + +void hashtbl_check_size(hashtbl_t *ht) { + size_t nsize = 0; + if (4 * ht->nitems < ht->size) nsize = ht->size / 2; + if (4 * ht->nitems > 3 * ht->size) nsize = ht->size * 2; + + if (nsize != 0 && nsize >= DEFAULT_HT_INIT_SIZE) { + hashtbl_item_t **nitems = (hashtbl_item_t**)malloc(nsize * sizeof(hashtbl_item_t*)); + if (nitems == 0) return; // if we can't realloc, too bad, we just lose space/efficienty + + for (size_t i = 0; i < nsize; i++) nitems[i] = 0; + + // rehash + for (size_t i = 0; i < ht->size; i++) { + while (ht->items[i] != 0) { + hashtbl_item_t *x = ht->items[i]; + ht->items[i] = x->next; + + size_t slot = SLOT_OF_HASH(ht->hf(x->key), nsize); + x->next = nitems[slot]; + nitems[slot] = x; + } + } + free(ht->items); + ht->size = nsize; + ht->items = nitems; + } +} + +bool hashtbl_add(hashtbl_t *ht, void* key, void* v) { + hashtbl_item_t *i = (hashtbl_item_t*)malloc(sizeof(hashtbl_item_t)); + if (i == 0) return false; // OOM + + // make sure item is not already present + hashtbl_remove(ht, key); + + size_t slot = SLOT_OF_HASH(ht->hf(key), ht->size); + + i->key = key; + i->val = v; + i->next = ht->items[slot]; + ht->items[slot] = i; + ht->nitems++; + + hashtbl_check_size(ht); + + return true; +} + +void hashtbl_remove(hashtbl_t* ht, const void* key) { + size_t slot = SLOT_OF_HASH(ht->hf(key), ht->size); + + if (ht->items[slot] == 0) return; + + hashtbl_item_t *x = 0; + + if (ht->ef(ht->items[slot]->key, key)) { + x = ht->items[slot]; + ht->items[slot] = x->next; + } else { + for (hashtbl_item_t *i = ht->items[slot]; i->next != 0; i = i->next) { + if (ht->ef(i->next->key, key)) { + x = i->next; + i->next = x->next; + break; + } + } + } + + if (x != 0) { + ht->nitems--; + if (ht->releasef) ht->releasef(x->key, x->val); + free(x); + } + + hashtbl_check_size(ht); +} + +void* hashtbl_find(hashtbl_t* ht, const void* key) { + size_t slot = SLOT_OF_HASH(ht->hf(key), ht->size); + + for (hashtbl_item_t *i = ht->items[slot]; i != 0; i = i->next) { + if (ht->ef(i->key, key)) return i->val; + } + + return 0; +} + +void hashtbl_iter(hashtbl_t *ht, kv_iter_fun_t f) { + for (size_t s = 0; s < ht->size; s++) { + for (hashtbl_item_t *i = ht->items[s]; i != 0; i = i->next) { + f(i->key, i->val); + } + } +} + +size_t hashtbl_count(hashtbl_t* ht) { + return ht->nitems; +} + +bool hashtbl_change(hashtbl_t* ht, void* key, void* newval) { + size_t slot = SLOT_OF_HASH(ht->hf(key), ht->size); + + for (hashtbl_item_t *i = ht->items[slot]; i != 0; i = i->next) { + if (ht->ef(i->key, key)) { + i->val = newval; + return true; + } + } + + return false; +} + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/libkogata/keyval.c b/src/common/libkogata/keyval.c new file mode 100644 index 0000000..9541c72 --- /dev/null +++ b/src/common/libkogata/keyval.c @@ -0,0 +1,51 @@ +#include + +#include +#include + +// Hashing and comparing + +hash_t id_hash_fun(const void* v) { + return (hash_t)v; +} + +hash_t str_hash_fun(const void* v) { + hash_t h = 712; + for (char* s = (char*)v; *s != 0; s++) { + h = h * 101 + *s; + } + return h; +} + +bool id_key_eq_fun(const void* a, const void* b) { + return a == b; +} + +bool str_key_eq_fun(const void* a, const void* b) { + return strcmp((const char*)a, (const char*)b) == 0; +} + +int id_key_cmp_fun(const void* a, const void* b) { + return (a == b ? 0 : (a < b ? -1 : 1)); +} + +int str_key_cmp_fun(const void* a, const void* b) { + return strcmp((const char*)a, (const char*)b); +} + +// Freeing functions + +void free_key(void* key, void* val) { + free(key); +} + +void free_val(void* key, void* val) { + free(val); +} + +void free_key_val(void* key, void* val) { + free(key); + free(val); +} + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/libkogata/mutex.c b/src/common/libkogata/mutex.c index b345ee5..e521330 100644 --- a/src/common/libkogata/mutex.c +++ b/src/common/libkogata/mutex.c @@ -1,4 +1,4 @@ -#include +#include /* Internal use only. This function is atomic, meaning it cannot be interrupted by a system task switch. */ static uint32_t atomic_exchange(uint32_t* ptr, uint32_t newval) { diff --git a/src/common/libkogata/region_alloc.c b/src/common/libkogata/region_alloc.c index 1f2fe0f..85c437a 100644 --- a/src/common/libkogata/region_alloc.c +++ b/src/common/libkogata/region_alloc.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include // we cannot include sys... diff --git a/src/common/libkogata/slab_alloc.c b/src/common/libkogata/slab_alloc.c index 0736655..6362207 100644 --- a/src/common/libkogata/slab_alloc.c +++ b/src/common/libkogata/slab_alloc.c @@ -1,4 +1,4 @@ -#include +#include typedef struct object { struct object *next; diff --git a/src/kernel/bam.lua b/src/kernel/bam.lua index 1588315..4a82f49 100644 --- a/src/kernel/bam.lua +++ b/src/kernel/bam.lua @@ -1,6 +1,7 @@ local kernel_settings = TableDeepCopy(common_settings) -kernel_settings.cc.includes:Add("src/kernel/include") +kernel_settings.cc.includes:Add("src/common/include/kogata", + "src/kernel/include") kernel_settings.link.flags:Add("-T src/kernel/linker.ld", "-Xlinker -Map=build/kernel.map") @@ -15,6 +16,5 @@ kernel_source = { } kernel_obj = Compile(kernel_settings, kernel_source) -kernel = Link(kernel_settings, "kernel", {kernel_obj, common_libkogata, - common_libc, common_libalgo}) +kernel = Link(kernel_settings, "kernel", {kernel_obj, common_libc, common_libkogata}) diff --git a/src/lib/bam.lua b/src/lib/bam.lua index b8e51e4..cef678e 100644 --- a/src/lib/bam.lua +++ b/src/lib/bam.lua @@ -3,6 +3,8 @@ local function lib(name) return Compile(user_settings, source) end -libkogata = {lib('libkogata'), common_libc, common_libalgo, common_libkogata} +libc = {lib('libc'), common_libc, common_libkogata} -liblua = lib('lua') +libkogata = {lib('libkogata'), libc} + +liblua = {lib('lua'), libc} diff --git a/src/lib/include/draw.h b/src/lib/include/draw.h deleted file mode 100644 index 5296b92..0000000 --- a/src/lib/include/draw.h +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include -#include - -// ---- Generic drawing functions - -// ---- Data structures - -typedef struct { - fb_info_t geom; - - fd_t fd; - uint8_t* data; -} fb_t; - -typedef struct font font_t; - -typedef uint32_t color_t; // a color is always linked to a FB on which it is to be applied - -// ---- Buffer creation - -fb_t *g_fb_from_file(fd_t file, fb_info_t *geom); -fb_t *g_fb_from_mem(uint8_t* region, fb_info_t *geom); - -void g_delete_fb(fb_t *fb); - -// ---- Color manipulation - -color_t g_color_rgb(fb_t *f, uint8_t r, uint8_t g, uint8_t b); - -// ---- Drawing primitives - -void g_plot(fb_t *fb, int x, int y, color_t c); - -void g_hline(fb_t *fb, int x, int y, int w, color_t c); // horizontal line -void g_vline(fb_t *fb, int x, int y, int h, color_t c); // vertical line -void g_line(fb_t *fb, int x1, int y1, int x2, int y2, color_t c); - -void g_rect(fb_t *fb, int x, int y, int w, int h, color_t c); -void g_fillrect(fb_t *fb, int x, int y, int w, int h, color_t c); -void g_rect_r(fb_t *fb, fb_region_t reg, color_t c); -void g_fillrect_r(fb_t *fb, fb_region_t reg, color_t c); - -void g_circle(fb_t *fb, int cx, int cy, int r, color_t c); -void g_fillcircle(fb_t *fb, int cx, int cy, int r, color_t c); - -void g_blit(fb_t *dst, int x, int y, fb_t *src); -void g_blit_region(fb_t *dst, int x, int y, fb_t *src, fb_region_t reg); - -void g_scroll_up(fb_t *fb, int l); - -// ---- Text manipulation - -font_t *g_load_font(const char* fontname); -void g_free_font(font_t *f); - -int g_text_width(font_t *f, const char* text); -int g_text_height(font_t *f, const char* text); - -void g_write(fb_t *fb, int x, int y, const char* text, font_t *font, color_t c); - - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/include/gip.h b/src/lib/include/gip.h deleted file mode 100644 index 9c66091..0000000 --- a/src/lib/include/gip.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -// Not thread safe - -#include - -#include -#include - -typedef struct gip_handler gip_handler_t; - -typedef void (*noarg_gip_callback_t)(gip_handler_t *s, gip_msg_header *m); -typedef void (*gip_reply_callback_t)(gip_handler_t *s, gip_msg_header *m, void* msg_data, void* cb_data); - -typedef struct { - noarg_gip_callback_t - reset, initiate, ok, failure, - enable_features, disable_features, - query_mode, set_mode, switch_buffer, - key_down, key_up; - void (*buffer_info)(gip_handler_t *s, gip_msg_header *m, gip_buffer_info_msg *i); - void (*mode_info)(gip_handler_t *s, gip_msg_header *m, gip_mode_info_msg *i); - void (*buffer_damage)(gip_handler_t *s, gip_msg_header *m, gip_buffer_damage_msg *i); - void (*unknown_msg)(gip_handler_t *s, gip_msg_header *m); - void (*fd_error)(gip_handler_t *s); -} gip_handler_callbacks_t; - -typedef struct gip_handler { - gip_handler_callbacks_t* cb; - void* data; - - gip_msg_header msg_buf; - gip_buffer_info_msg buffer_info_msg_buf; - gip_mode_info_msg mode_info_msg_buf; - gip_buffer_damage_msg buffer_damage_msg_buf; - - hashtbl_t *requests_in_progress; - uint32_t next_req_id; - - mainloop_fd_t mainloop_item; -} gip_handler_t; - -gip_handler_t *new_gip_handler(gip_handler_callbacks_t *cb, void* data); -void delete_gip_handler(gip_handler_t *h); - -// GIP send messages - -bool gip_cmd(gip_handler_t *h, gip_msg_header *msg, void* msg_data, gip_reply_callback_t cb, void* cb_data); - -bool gip_reply(gip_handler_t *h, gip_msg_header *orig_request, gip_msg_header *msg, void* msg_data); -bool gip_reply_fail(gip_handler_t *h, gip_msg_header *o); -bool gip_reply_ok(gip_handler_t *h, gip_msg_header *o); - -bool gip_notify(gip_handler_t *h, gip_msg_header *msg, void* msg_data); - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/include/keyboard.h b/src/lib/include/keyboard.h deleted file mode 100644 index 63c6c2c..0000000 --- a/src/lib/include/keyboard.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include - -#include - -#define KBD_CHAR 0x01 -#define KBD_ALT 0x02 -#define KBD_CTRL 0x04 -#define KBD_SUPER 0x08 -#define KBD_SHIFT 0x10 -#define KBD_CAPS 0x20 -#define KBD_MOD 0x40 - -typedef struct { - union { - int chr; // if flags & KBD_CHAR, chr is a character number - int key; // if !(flags & KBD_CHAR), key is one of KBD_CODE_* defined in - }; - uint32_t flags; // one of kbd_* -} key_t; - -typedef struct { - keymap_t km; - int key_char[256]; - uint32_t status; // mask of alt/ctrl/super -} keyboard_t; - -keyboard_t *init_keyboard(); -void free_keyboard(keyboard_t *t); - -bool load_keymap(keyboard_t *kb, const char* kmname); - -key_t keyboard_press(keyboard_t *t, int scancode); // what key is pressed? -key_t keyboard_release(keyboard_t *t, int scancode); // what key is released? - - - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/include/kogata/draw.h b/src/lib/include/kogata/draw.h new file mode 100644 index 0000000..fb9fe05 --- /dev/null +++ b/src/lib/include/kogata/draw.h @@ -0,0 +1,64 @@ +#pragma once + +#include +#include + +// ---- Generic drawing functions + +// ---- Data structures + +typedef struct { + fb_info_t geom; + + fd_t fd; + uint8_t* data; +} fb_t; + +typedef struct font font_t; + +typedef uint32_t color_t; // a color is always linked to a FB on which it is to be applied + +// ---- Buffer creation + +fb_t *g_fb_from_file(fd_t file, fb_info_t *geom); +fb_t *g_fb_from_mem(uint8_t* region, fb_info_t *geom); + +void g_delete_fb(fb_t *fb); + +// ---- Color manipulation + +color_t g_color_rgb(fb_t *f, uint8_t r, uint8_t g, uint8_t b); + +// ---- Drawing primitives + +void g_plot(fb_t *fb, int x, int y, color_t c); + +void g_hline(fb_t *fb, int x, int y, int w, color_t c); // horizontal line +void g_vline(fb_t *fb, int x, int y, int h, color_t c); // vertical line +void g_line(fb_t *fb, int x1, int y1, int x2, int y2, color_t c); + +void g_rect(fb_t *fb, int x, int y, int w, int h, color_t c); +void g_fillrect(fb_t *fb, int x, int y, int w, int h, color_t c); +void g_rect_r(fb_t *fb, fb_region_t reg, color_t c); +void g_fillrect_r(fb_t *fb, fb_region_t reg, color_t c); + +void g_circle(fb_t *fb, int cx, int cy, int r, color_t c); +void g_fillcircle(fb_t *fb, int cx, int cy, int r, color_t c); + +void g_blit(fb_t *dst, int x, int y, fb_t *src); +void g_blit_region(fb_t *dst, int x, int y, fb_t *src, fb_region_t reg); + +void g_scroll_up(fb_t *fb, int l); + +// ---- Text manipulation + +font_t *g_load_font(const char* fontname); +void g_free_font(font_t *f); + +int g_text_width(font_t *f, const char* text); +int g_text_height(font_t *f, const char* text); + +void g_write(fb_t *fb, int x, int y, const char* text, font_t *font, color_t c); + + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/include/kogata/gip.h b/src/lib/include/kogata/gip.h new file mode 100644 index 0000000..1d1725a --- /dev/null +++ b/src/lib/include/kogata/gip.h @@ -0,0 +1,56 @@ +#pragma once + +// Not thread safe + +#include +#include + +#include + +typedef struct gip_handler gip_handler_t; + +typedef void (*noarg_gip_callback_t)(gip_handler_t *s, gip_msg_header *m); +typedef void (*gip_reply_callback_t)(gip_handler_t *s, gip_msg_header *m, void* msg_data, void* cb_data); + +typedef struct { + noarg_gip_callback_t + reset, initiate, ok, failure, + enable_features, disable_features, + query_mode, set_mode, switch_buffer, + key_down, key_up; + void (*buffer_info)(gip_handler_t *s, gip_msg_header *m, gip_buffer_info_msg *i); + void (*mode_info)(gip_handler_t *s, gip_msg_header *m, gip_mode_info_msg *i); + void (*buffer_damage)(gip_handler_t *s, gip_msg_header *m, gip_buffer_damage_msg *i); + void (*unknown_msg)(gip_handler_t *s, gip_msg_header *m); + void (*fd_error)(gip_handler_t *s); +} gip_handler_callbacks_t; + +typedef struct gip_handler { + gip_handler_callbacks_t* cb; + void* data; + + gip_msg_header msg_buf; + gip_buffer_info_msg buffer_info_msg_buf; + gip_mode_info_msg mode_info_msg_buf; + gip_buffer_damage_msg buffer_damage_msg_buf; + + hashtbl_t *requests_in_progress; + uint32_t next_req_id; + + mainloop_fd_t mainloop_item; +} gip_handler_t; + +gip_handler_t *new_gip_handler(gip_handler_callbacks_t *cb, void* data); +void delete_gip_handler(gip_handler_t *h); + +// GIP send messages + +bool gip_cmd(gip_handler_t *h, gip_msg_header *msg, void* msg_data, gip_reply_callback_t cb, void* cb_data); + +bool gip_reply(gip_handler_t *h, gip_msg_header *orig_request, gip_msg_header *msg, void* msg_data); +bool gip_reply_fail(gip_handler_t *h, gip_msg_header *o); +bool gip_reply_ok(gip_handler_t *h, gip_msg_header *o); + +bool gip_notify(gip_handler_t *h, gip_msg_header *msg, void* msg_data); + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/include/kogata/keyboard.h b/src/lib/include/kogata/keyboard.h new file mode 100644 index 0000000..63c6c2c --- /dev/null +++ b/src/lib/include/kogata/keyboard.h @@ -0,0 +1,39 @@ +#pragma once + +#include + +#include + +#define KBD_CHAR 0x01 +#define KBD_ALT 0x02 +#define KBD_CTRL 0x04 +#define KBD_SUPER 0x08 +#define KBD_SHIFT 0x10 +#define KBD_CAPS 0x20 +#define KBD_MOD 0x40 + +typedef struct { + union { + int chr; // if flags & KBD_CHAR, chr is a character number + int key; // if !(flags & KBD_CHAR), key is one of KBD_CODE_* defined in + }; + uint32_t flags; // one of kbd_* +} key_t; + +typedef struct { + keymap_t km; + int key_char[256]; + uint32_t status; // mask of alt/ctrl/super +} keyboard_t; + +keyboard_t *init_keyboard(); +void free_keyboard(keyboard_t *t); + +bool load_keymap(keyboard_t *kb, const char* kmname); + +key_t keyboard_press(keyboard_t *t, int scancode); // what key is pressed? +key_t keyboard_release(keyboard_t *t, int scancode); // what key is released? + + + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/include/kogata/mainloop.h b/src/lib/include/kogata/mainloop.h new file mode 100644 index 0000000..2b447ef --- /dev/null +++ b/src/lib/include/kogata/mainloop.h @@ -0,0 +1,47 @@ +#pragma once + +// These functions are not thread safe, their purpose +// is to multiplex several IO operations on a +// single thread. + +#include + +#define MAINLOOP_MAX_WR_BUFS 4 + +typedef struct mainloop_fd mainloop_fd_t; + +typedef void (*buf_full_callback_t)(mainloop_fd_t *fd); +typedef void (*fd_error_callback_t)(mainloop_fd_t *fd); + +typedef struct { + size_t size, written; + void* buf; + bool must_free; +} mainloop_wr_buf_t; + +typedef struct mainloop_fd { + fd_t fd; + + size_t rd_buf_expect_size, rd_buf_filled; + void* rd_buf; + + mainloop_wr_buf_t wr_bufs[MAINLOOP_MAX_WR_BUFS]; + + void* data; + + buf_full_callback_t rd_on_full; + fd_error_callback_t on_error; + + mainloop_fd_t *next; +} mainloop_fd_t; + +void mainloop_add_fd(mainloop_fd_t* fd); +void mainloop_rm_fd(mainloop_fd_t* fd); + +void mainloop_expect(mainloop_fd_t *fd, void* buf, size_t size, buf_full_callback_t cb); +bool mainloop_nonblocking_write(mainloop_fd_t *fd, void* buf, size_t size, bool must_free_buf); + +void mainloop_run(); +void mainloop_exit(); + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/include/kogata/syscall.h b/src/lib/include/kogata/syscall.h new file mode 100644 index 0000000..378dda2 --- /dev/null +++ b/src/lib/include/kogata/syscall.h @@ -0,0 +1,63 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include +#include + +#include + +typedef void (*entry_t)(void*); + +void dbg_print(const char* str); +void yield(); +void exit(int code); +void usleep(int usecs); +bool sys_new_thread(void* eip, void* esp); +void exit_thread(); + +bool mmap(void* addr, size_t size, int mode); +bool mmap_file(fd_t file, size_t offset, void* addr, size_t size, int mode); +bool mchmap(void* addr, int mode); +bool munmap(void* addr); + +bool create(const char* name, int type); +bool delete(const char* name); +bool move(const char* oldname, const char* newname); +bool stat(const char* name, stat_t *s); + +fd_t open(const char* name, int mode); +void close(fd_t file); +size_t read(fd_t file, size_t offset, size_t len, char *buf); +size_t write(fd_t file, size_t offset, size_t len, const char* buf); +bool readdir(fd_t file, size_t ent_no, dirent_t *d); +bool stat_open(fd_t file, stat_t *s); +int ioctl(fd_t file, int command, void* data); +int fctl(fd_t file, int command, void* data); +bool select(sel_fd_t* fds, size_t nfds, int timeout); + +fd_pair_t make_channel(bool blocking); +fd_t make_shm(size_t size); +bool gen_token(fd_t file, token_t *tok); +fd_t use_token(token_t *tok); + +bool make_fs(const char* name, const char* driver, fd_t source, const char* options); +bool fs_add_source(const char* fs, fd_t source, const char* options); +bool fs_subfs(const char* name, const char* orig_fs, const char* root, int ok_modes); +void fs_remove(const char* name); + +pid_t new_proc(); +bool bind_fs(pid_t pid, const char* new_name, const char* fs); +bool bind_subfs(pid_t pid, const char* new_name, const char* fs, const char* root, int ok_modes); +bool bind_make_fs(pid_t pid, const char* name, const char* driver, fd_t source, const char* options); +bool bind_fd(pid_t pid, fd_t new_fd, fd_t fd); +bool proc_exec(pid_t pid, const char* file); +bool proc_status(pid_t pid, proc_status_t *s); +bool proc_kill(pid_t pid, proc_status_t *s); +void proc_wait(pid_t pid, bool wait, proc_status_t *s); + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/include/mainloop.h b/src/lib/include/mainloop.h deleted file mode 100644 index 1e71ffb..0000000 --- a/src/lib/include/mainloop.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -// These functions are not thread safe, their purpose -// is to multiplex several IO operations on a -// single thread. - -#include - -#define MAINLOOP_MAX_WR_BUFS 4 - -typedef struct mainloop_fd mainloop_fd_t; - -typedef void (*buf_full_callback_t)(mainloop_fd_t *fd); -typedef void (*fd_error_callback_t)(mainloop_fd_t *fd); - -typedef struct { - size_t size, written; - void* buf; - bool must_free; -} mainloop_wr_buf_t; - -typedef struct mainloop_fd { - fd_t fd; - - size_t rd_buf_expect_size, rd_buf_filled; - void* rd_buf; - - mainloop_wr_buf_t wr_bufs[MAINLOOP_MAX_WR_BUFS]; - - void* data; - - buf_full_callback_t rd_on_full; - fd_error_callback_t on_error; - - mainloop_fd_t *next; -} mainloop_fd_t; - -void mainloop_add_fd(mainloop_fd_t* fd); -void mainloop_rm_fd(mainloop_fd_t* fd); - -void mainloop_expect(mainloop_fd_t *fd, void* buf, size_t size, buf_full_callback_t cb); -bool mainloop_nonblocking_write(mainloop_fd_t *fd, void* buf, size_t size, bool must_free_buf); - -void mainloop_run(); -void mainloop_exit(); - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/include/proto/gip.h b/src/lib/include/proto/gip.h index ca8b868..5cf0166 100644 --- a/src/lib/include/proto/gip.h +++ b/src/lib/include/proto/gip.h @@ -2,7 +2,7 @@ #include -#include +#include /* Definition of the GIP protocol (Graphics Initiation Protocol). diff --git a/src/lib/include/stdio.h b/src/lib/include/stdio.h index f46add4..1e75270 100644 --- a/src/lib/include/stdio.h +++ b/src/lib/include/stdio.h @@ -2,7 +2,7 @@ #include -#include +#include extern fd_t stdio; diff --git a/src/lib/include/stdlib.h b/src/lib/include/stdlib.h index 29d8661..30da9a6 100644 --- a/src/lib/include/stdlib.h +++ b/src/lib/include/stdlib.h @@ -1,6 +1,6 @@ #pragma once -#include "malloc.h" +#include #define EXIT_SUCCESS 0 #define EXIT_FAILURE 255 diff --git a/src/lib/include/syscall.h b/src/lib/include/syscall.h deleted file mode 100644 index 07defdb..0000000 --- a/src/lib/include/syscall.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include -#include -#include - -#include - -typedef void (*entry_t)(void*); - -void dbg_print(const char* str); -void yield(); -void exit(int code); -void usleep(int usecs); -bool sys_new_thread(void* eip, void* esp); -void exit_thread(); - -bool mmap(void* addr, size_t size, int mode); -bool mmap_file(fd_t file, size_t offset, void* addr, size_t size, int mode); -bool mchmap(void* addr, int mode); -bool munmap(void* addr); - -bool create(const char* name, int type); -bool delete(const char* name); -bool move(const char* oldname, const char* newname); -bool stat(const char* name, stat_t *s); - -fd_t open(const char* name, int mode); -void close(fd_t file); -size_t read(fd_t file, size_t offset, size_t len, char *buf); -size_t write(fd_t file, size_t offset, size_t len, const char* buf); -bool readdir(fd_t file, size_t ent_no, dirent_t *d); -bool stat_open(fd_t file, stat_t *s); -int ioctl(fd_t file, int command, void* data); -int fctl(fd_t file, int command, void* data); -bool select(sel_fd_t* fds, size_t nfds, int timeout); - -fd_pair_t make_channel(bool blocking); -fd_t make_shm(size_t size); -bool gen_token(fd_t file, token_t *tok); -fd_t use_token(token_t *tok); - -bool make_fs(const char* name, const char* driver, fd_t source, const char* options); -bool fs_add_source(const char* fs, fd_t source, const char* options); -bool fs_subfs(const char* name, const char* orig_fs, const char* root, int ok_modes); -void fs_remove(const char* name); - -pid_t new_proc(); -bool bind_fs(pid_t pid, const char* new_name, const char* fs); -bool bind_subfs(pid_t pid, const char* new_name, const char* fs, const char* root, int ok_modes); -bool bind_make_fs(pid_t pid, const char* name, const char* driver, fd_t source, const char* options); -bool bind_fd(pid_t pid, fd_t new_fd, fd_t fd); -bool proc_exec(pid_t pid, const char* file); -bool proc_status(pid_t pid, proc_status_t *s); -bool proc_kill(pid_t pid, proc_status_t *s); -void proc_wait(pid_t pid, bool wait, proc_status_t *s); - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/libc/debug.c b/src/lib/libc/debug.c new file mode 100644 index 0000000..dc04fd3 --- /dev/null +++ b/src/lib/libc/debug.c @@ -0,0 +1,18 @@ +#include + +#include +#include + +void sys_panic(const char* msg, const char* file, int line) { + dbg_printf("PANIC in user process\n %s\n at %s:%d\n", msg, file, line); + exit(-1); + while(true); +} + +void sys_panic_assert(const char* assert, const char* file, int line) { + dbg_printf("ASSERT FAILED in user process\n %s\n at %s:%d\n", assert, file, line); + exit(-1); + while(true); +} + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/libc/malloc.c b/src/lib/libc/malloc.c new file mode 100644 index 0000000..cb983fd --- /dev/null +++ b/src/lib/libc/malloc.c @@ -0,0 +1,70 @@ +#include +#include + +#include +#include + +#include + +static void* heap_alloc_pages(size_t s) { + void* addr = region_alloc(s, "Heap"); + if (addr == 0) return 0; + + bool map_ok = mmap(addr, s, FM_READ | FM_WRITE); + if (!map_ok) { + region_free(addr); + return 0; + } + + return addr; +} + +static void heap_free_pages(void* addr) { + munmap(addr); + region_free(addr); +} + +static mem_allocator_t *mem_allocator; +static slab_type_t slab_sizes[] = { + { "8B malloc objects", 8, 2 }, + { "16B malloc objects", 16, 2 }, + { "32B malloc objects", 32, 2 }, + { "64B malloc objects", 64, 4 }, + { "128B malloc objects", 128, 4 }, + { "256B malloc objects", 256, 4 }, + { "512B malloc objects", 512, 8 }, + { "1KB malloc objects", 1024, 8 }, + { "2KB malloc objects", 2048, 16 }, + { "4KB malloc objects", 4096, 16 }, + { 0, 0, 0 } +}; + +bool mmap_single_page(void* addr) { + return mmap(addr, PAGE_SIZE, MM_READ | MM_WRITE); +} + +void malloc_setup() { + region_allocator_init((void*)0x40000000, (void*)0x40000000, (void*)0xB0000000, mmap_single_page); + + mem_allocator = create_slab_allocator(slab_sizes, heap_alloc_pages, heap_free_pages); + + ASSERT(mem_allocator != 0); +} + +void* malloc(size_t size) { + if (size == 0) return 0; + + return slab_alloc(mem_allocator, size); +} + +void* calloc(size_t nmemb, size_t sz) { + void* r = malloc(nmemb * sz); + if (r != 0) memset(r, 0, nmemb * sz); + return r; +} + +void free(void* ptr) { + slab_free(mem_allocator, ptr); +} + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/libc/start.c b/src/lib/libc/start.c new file mode 100644 index 0000000..49a6ca1 --- /dev/null +++ b/src/lib/libc/start.c @@ -0,0 +1,17 @@ +#include + +void malloc_setup(); + +int main(int, char**); + +void __libkogata_start() { + malloc_setup(); + + // TODO : more setup ? + + int ret = main(0, 0); + + exit(ret); +} + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/libc/stdio.c b/src/lib/libc/stdio.c new file mode 100644 index 0000000..22be78e --- /dev/null +++ b/src/lib/libc/stdio.c @@ -0,0 +1,63 @@ +#include +#include + +#include +#include + + +fd_t stdio = 1; + +int getchar() { + char chr; + size_t sz = read(stdio, 0, 1, &chr); + ASSERT(sz == 1); + return chr; +} + + +int putchar(int c) { + char chr = c; + write(stdio, 0, 1, &chr); + return 0; //TODO what? +} + +int puts(const char* s) { + // TODO return EOF on error + return write(stdio, 0, strlen(s), s); +} + +void getline(char* buf, size_t l) { + size_t i = 0; + while (true) { + int c = getchar(); + if (c == '\n') { + putchar('\n'); + buf[i] = 0; + break; + } else if (c == '\b') { + if (i > 0) { + i--; + putchar('\b'); + } + } else if (c >= ' ') { + buf[i] = c; + if (i < l-1) { + i++; + putchar(c); + } + } + } +} + +int printf(const char* fmt, ...) { + va_list ap; + char buffer[256]; + + va_start(ap, fmt); + vsnprintf(buffer, 256, fmt, ap); + va_end(ap); + + return puts(buffer); +} + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/libc/syscall.c b/src/lib/libc/syscall.c new file mode 100644 index 0000000..61b3471 --- /dev/null +++ b/src/lib/libc/syscall.c @@ -0,0 +1,204 @@ +#include +#include + +#include + +#include + +static inline uint32_t call(uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t ss, uint32_t dd) { + uint32_t ret; + asm volatile("int $0x40" + :"=a"(ret) + :"a"(a),"b"(b),"c"(c),"d"(d),"S"(ss),"D"(dd)); + return ret; +} + +void dbg_print(const char* str) { + call(SC_DBG_PRINT, (uint32_t)str, strlen(str), 0, 0, 0); +} + +void dbg_printf(const char* fmt, ...) { + va_list ap; + char buffer[256]; + + va_start(ap, fmt); + vsnprintf(buffer, 256, fmt, ap); + va_end(ap); + + dbg_print(buffer); +} + +void yield() { + call(SC_YIELD, 0, 0, 0, 0, 0); +} + +void exit(int code) { + call(SC_EXIT, code, 0, 0, 0, 0); +} + +void usleep(int usecs) { + call(SC_USLEEP, usecs, 0, 0, 0, 0); +} + +bool sys_new_thread(void* eip, void* esp) { + return call(SC_NEW_THREAD, (uint32_t)eip, (uint32_t)esp, 0, 0, 0); +} + +void exit_thread() { + call(SC_EXIT_THREAD, 0, 0, 0, 0, 0); +} + +bool mmap(void* addr, size_t size, int mode) { + return call(SC_MMAP, (uint32_t)addr, size, mode, 0, 0); +} +bool mmap_file(fd_t file, size_t offset, void* addr, size_t size, int mode) { + return call(SC_MMAP_FILE, file, offset, (uint32_t)addr, size, mode); +} +bool mchmap(void* addr, int mode) { + return call(SC_MCHMAP, (uint32_t)addr, mode, 0, 0, 0); +} +bool munmap(void* addr) { + return call(SC_MUNMAP, (uint32_t)addr, 0, 0, 0, 0); +} + +bool create(const char* name, int type) { + return call(SC_CREATE, (uint32_t)name, strlen(name), type, 0, 0); +} +bool delete(const char* name) { + return call(SC_CREATE, (uint32_t)name, strlen(name), 0, 0, 0); +} +bool move(const char* oldname, const char* newname) { + return call(SC_MOVE, (uint32_t)oldname, strlen(oldname), (uint32_t)newname, strlen(newname), 0); +} +bool stat(const char* name, stat_t *s) { + return call(SC_STAT, (uint32_t)name, strlen(name), (uint32_t)s, 0, 0); +} + +fd_t open(const char* name, int mode) { + return call(SC_OPEN, (uint32_t)name, strlen(name), mode, 0, 0); +} +void close(fd_t file) { + call(SC_CLOSE, file, 0, 0, 0, 0); +} +size_t read(fd_t file, size_t offset, size_t len, char *buf) { + return call(SC_READ, file, offset, len, (uint32_t)buf, 0); +} +size_t write(fd_t file, size_t offset, size_t len, const char* buf) { + return call(SC_WRITE, file, offset, len, (uint32_t)buf, 0); +} +bool readdir(fd_t file, size_t ent_no, dirent_t *d) { + return call(SC_READDIR, file, ent_no, (uint32_t)d, 0, 0); +} +bool stat_open(fd_t file, stat_t *s) { + return call(SC_STAT_OPEN, file, (uint32_t)s, 0, 0, 0); +} +int ioctl(fd_t file, int command, void* data) { + return call(SC_IOCTL, file, command, (uint32_t)data, 0, 0); +} +int fctl(fd_t file, int command, void *data) { + return call(SC_FCTL, file, command, (uint32_t)data, 0, 0); +} +bool select(sel_fd_t* fds, size_t nfds, int timeout) { + return call(SC_SELECT, (uint32_t)fds, nfds, timeout, 0, 0); +} + +fd_pair_t make_channel(bool blocking) { + fd_pair_t ret; + call(SC_MK_CHANNEL, blocking, (uint32_t)&ret, 0, 0, 0); + return ret; +} +fd_t make_shm(size_t s) { + return call(SC_MK_SHM, s, 0, 0, 0, 0); +} +bool gen_token(fd_t file, token_t *tok) { + return call(SC_GEN_TOKEN, file, (uint32_t)tok, 0, 0, 0); +} +fd_t use_token(token_t *tok) { + return call(SC_USE_TOKEN, (uint32_t)tok, 0, 0, 0, 0); +} + +bool make_fs(const char* name, const char* driver, fd_t source, const char* options) { + volatile sc_make_fs_args_t args = { + .driver = driver, + .driver_strlen = strlen(driver), + .fs_name = name, + .fs_name_strlen = strlen(name), + .source_fd = source, + .opts = options, + .opts_strlen = strlen(options), + .bind_to_pid = 0, + }; + return call(SC_MAKE_FS, (uint32_t)&args, 0, 0, 0, 0); +} +bool fs_add_source(const char* fs, fd_t source, const char* options) { + return call(SC_FS_ADD_SRC, (uint32_t)fs, strlen(fs), source, (uint32_t)options, strlen(options)); +} +bool fs_subfs(const char* name, const char* orig_fs, const char* root, int ok_modes) { + volatile sc_subfs_args_t args = { + .new_name = name, + .new_name_strlen = strlen(name), + .from_fs = orig_fs, + .from_fs_strlen = strlen(orig_fs), + .root = root, + .root_strlen = strlen(root), + .ok_modes = ok_modes, + .bind_to_pid = 0 + }; + return call(SC_SUBFS, (uint32_t)(&args), 0, 0, 0, 0); +} +void fs_remove(const char* name) { + call(SC_RM_FS, (uint32_t)name, strlen(name), 0, 0, 0); +} + +pid_t new_proc() { + return call(SC_NEW_PROC, 0, 0, 0, 0, 0); +} +bool bind_fs(pid_t pid, const char* new_name, const char* fs) { + return call(SC_BIND_FS, pid, (uint32_t)new_name, strlen(new_name), (uint32_t)fs, strlen(fs)); +} +bool bind_subfs(pid_t pid, const char* new_name, const char* orig_fs, const char* root, int ok_modes) { + sc_subfs_args_t args = { + .new_name = new_name, + .new_name_strlen = strlen(new_name), + .from_fs = orig_fs, + .from_fs_strlen = strlen(orig_fs), + .root = root, + .root_strlen = strlen(root), + .ok_modes = ok_modes, + .bind_to_pid = pid + }; + return call(SC_BIND_SUBFS, (uint32_t)&args, 0, 0, 0, 0); +} +bool bind_make_fs(pid_t pid, const char* name, const char* driver, fd_t source, const char* options) { + sc_make_fs_args_t args = { + .driver = driver, + .driver_strlen = strlen(driver), + .fs_name = name, + .fs_name_strlen = strlen(name), + .source_fd = source, + .opts = options, + .opts_strlen = strlen(options), + .bind_to_pid = pid, + }; + return call(SC_BIND_MAKE_FS, (uint32_t)&args, 0, 0, 0, 0); +} +bool bind_fd(pid_t pid, fd_t new_fd, fd_t fd) { + return call(SC_BIND_FD, pid, new_fd, fd, 0, 0); +} +bool proc_exec(pid_t pid, const char* file) { + return call(SC_PROC_EXEC, pid, (uint32_t)file, strlen(file), 0, 0); +} +bool proc_status(pid_t pid, proc_status_t *s) { + return call(SC_PROC_STATUS, pid, (uint32_t)s, 0, 0, 0); +} +bool proc_kill(pid_t pid, proc_status_t *s) { + return call(SC_PROC_KILL, pid, (uint32_t)s, 0, 0, 0); +} +void proc_wait(pid_t pid, bool block, proc_status_t *s) { + call(SC_PROC_WAIT, pid, block, (uint32_t)s, 0, 0); +} + + + + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/libc/unistd.c b/src/lib/libc/unistd.c new file mode 100644 index 0000000..5ae1735 --- /dev/null +++ b/src/lib/libc/unistd.c @@ -0,0 +1,66 @@ +#include +#include + +#include + + +char cwd_buf[256]; + +char* getcwd(char* buf, size_t buf_len) { + if (buf_len > strlen(cwd_buf)) { + strcpy(buf, cwd_buf); + return buf; + } else { + return 0; + } +} + +int chdir(const char* path) { + char cwd_buf2[256]; + strcpy(cwd_buf2, cwd_buf); + + if (!pathncat(cwd_buf2, path, 256)) return -1; + + stat_t st; + if (!stat(cwd_buf2, &st)) return -1; + if (!(st.type & FT_DIR)) return -1; + + strcpy(cwd_buf, cwd_buf2); + return 0; +} + +char* pathncat(char* buf, const char* add, size_t buf_len) { + if (strchr(add, ':')) { + if (strlen(add) < buf_len) { + strcpy(buf, add); + return buf; + } else { + return 0; + } + } else { + char* sep_init = strchr(buf, ':'); + if (add[0] == '/') { + if (strlen(add) + (sep_init + 1 - buf) < buf_len) { + strcpy(sep_init + 1, add); + return buf; + } else { + return 0; + } + } else { + //TODO: simplify '..' + char* end = buf + strlen(buf) - 1; + if (*end != '/') end++; + if (end + 1 - buf + strlen(add) < buf_len) { + *end = '/'; + strcpy(end + 1, add); + return buf; + } else { + return 0; + } + } + return 0; + } +} + + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/libkogata/debug.c b/src/lib/libkogata/debug.c deleted file mode 100644 index 847ecca..0000000 --- a/src/lib/libkogata/debug.c +++ /dev/null @@ -1,19 +0,0 @@ -#include - -#include - -#include - -void sys_panic(const char* msg, const char* file, int line) { - dbg_printf("PANIC in user process\n %s\n at %s:%d\n", msg, file, line); - exit(-1); - while(true); -} - -void sys_panic_assert(const char* assert, const char* file, int line) { - dbg_printf("ASSERT FAILED in user process\n %s\n at %s:%d\n", assert, file, line); - exit(-1); - while(true); -} - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/libkogata/draw.c b/src/lib/libkogata/draw.c index 2806df4..d988cb9 100644 --- a/src/lib/libkogata/draw.c +++ b/src/lib/libkogata/draw.c @@ -1,13 +1,13 @@ -#include -#include +#include #include -#include #include -#include +#include +#include -#include +#include +#include fb_t *g_fb_from_file(fd_t file, fb_info_t *geom) { fb_t *ret = (fb_t*)malloc(sizeof(fb_t)); diff --git a/src/lib/libkogata/gip.c b/src/lib/libkogata/gip.c index cdfeb71..5b1e44d 100644 --- a/src/lib/libkogata/gip.c +++ b/src/lib/libkogata/gip.c @@ -1,7 +1,7 @@ #include -#include +#include -#include +#include typedef struct { gip_reply_callback_t cb; diff --git a/src/lib/libkogata/keyboard.c b/src/lib/libkogata/keyboard.c index 505c048..e7fb08b 100644 --- a/src/lib/libkogata/keyboard.c +++ b/src/lib/libkogata/keyboard.c @@ -1,11 +1,12 @@ -#include +#include #include -#include - -#include #include -#include + +#include +#include + +#include // ---- Control keys that are not KBD_CHAR-able diff --git a/src/lib/libkogata/mainloop.c b/src/lib/libkogata/mainloop.c index 58966dd..bce1174 100644 --- a/src/lib/libkogata/mainloop.c +++ b/src/lib/libkogata/mainloop.c @@ -1,7 +1,7 @@ -#include +#include #include -#include +#include mainloop_fd_t *mainloop_fds = 0; bool mainloop_fds_change = false; diff --git a/src/lib/libkogata/malloc.c b/src/lib/libkogata/malloc.c deleted file mode 100644 index 3777123..0000000 --- a/src/lib/libkogata/malloc.c +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include - -#include - -#include -#include - -static void* heap_alloc_pages(size_t s) { - void* addr = region_alloc(s, "Heap"); - if (addr == 0) return 0; - - bool map_ok = mmap(addr, s, FM_READ | FM_WRITE); - if (!map_ok) { - region_free(addr); - return 0; - } - - return addr; -} - -static void heap_free_pages(void* addr) { - munmap(addr); - region_free(addr); -} - -static mem_allocator_t *mem_allocator; -static slab_type_t slab_sizes[] = { - { "8B malloc objects", 8, 2 }, - { "16B malloc objects", 16, 2 }, - { "32B malloc objects", 32, 2 }, - { "64B malloc objects", 64, 4 }, - { "128B malloc objects", 128, 4 }, - { "256B malloc objects", 256, 4 }, - { "512B malloc objects", 512, 8 }, - { "1KB malloc objects", 1024, 8 }, - { "2KB malloc objects", 2048, 16 }, - { "4KB malloc objects", 4096, 16 }, - { 0, 0, 0 } -}; - -bool mmap_single_page(void* addr) { - return mmap(addr, PAGE_SIZE, MM_READ | MM_WRITE); -} - -void malloc_setup() { - region_allocator_init((void*)0x40000000, (void*)0x40000000, (void*)0xB0000000, mmap_single_page); - - mem_allocator = create_slab_allocator(slab_sizes, heap_alloc_pages, heap_free_pages); - - ASSERT(mem_allocator != 0); -} - -void* malloc(size_t size) { - if (size == 0) return 0; - - return slab_alloc(mem_allocator, size); -} - -void* calloc(size_t nmemb, size_t sz) { - void* r = malloc(nmemb * sz); - if (r != 0) memset(r, 0, nmemb * sz); - return r; -} - -void free(void* ptr) { - slab_free(mem_allocator, ptr); -} - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/libkogata/start.c b/src/lib/libkogata/start.c deleted file mode 100644 index bd22d7a..0000000 --- a/src/lib/libkogata/start.c +++ /dev/null @@ -1,17 +0,0 @@ -#include - -void malloc_setup(); - -int main(int, char**); - -void __libkogata_start() { - malloc_setup(); - - // TODO : more setup ? - - int ret = main(0, 0); - - exit(ret); -} - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/libkogata/stdio.c b/src/lib/libkogata/stdio.c deleted file mode 100644 index 94dec22..0000000 --- a/src/lib/libkogata/stdio.c +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include - -#include -#include - - -fd_t stdio = 1; - -int getchar() { - char chr; - size_t sz = read(stdio, 0, 1, &chr); - ASSERT(sz == 1); - return chr; -} - - -int putchar(int c) { - char chr = c; - write(stdio, 0, 1, &chr); - return 0; //TODO what? -} - -int puts(const char* s) { - // TODO return EOF on error - return write(stdio, 0, strlen(s), s); -} - -void getline(char* buf, size_t l) { - size_t i = 0; - while (true) { - int c = getchar(); - if (c == '\n') { - putchar('\n'); - buf[i] = 0; - break; - } else if (c == '\b') { - if (i > 0) { - i--; - putchar('\b'); - } - } else if (c >= ' ') { - buf[i] = c; - if (i < l-1) { - i++; - putchar(c); - } - } - } -} - -int printf(const char* fmt, ...) { - va_list ap; - char buffer[256]; - - va_start(ap, fmt); - vsnprintf(buffer, 256, fmt, ap); - va_end(ap); - - return puts(buffer); -} - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/libkogata/syscall.c b/src/lib/libkogata/syscall.c deleted file mode 100644 index bf0b35e..0000000 --- a/src/lib/libkogata/syscall.c +++ /dev/null @@ -1,203 +0,0 @@ -#include -#include - -#include -#include - -static inline uint32_t call(uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t ss, uint32_t dd) { - uint32_t ret; - asm volatile("int $0x40" - :"=a"(ret) - :"a"(a),"b"(b),"c"(c),"d"(d),"S"(ss),"D"(dd)); - return ret; -} - -void dbg_print(const char* str) { - call(SC_DBG_PRINT, (uint32_t)str, strlen(str), 0, 0, 0); -} - -void dbg_printf(const char* fmt, ...) { - va_list ap; - char buffer[256]; - - va_start(ap, fmt); - vsnprintf(buffer, 256, fmt, ap); - va_end(ap); - - dbg_print(buffer); -} - -void yield() { - call(SC_YIELD, 0, 0, 0, 0, 0); -} - -void exit(int code) { - call(SC_EXIT, code, 0, 0, 0, 0); -} - -void usleep(int usecs) { - call(SC_USLEEP, usecs, 0, 0, 0, 0); -} - -bool sys_new_thread(void* eip, void* esp) { - return call(SC_NEW_THREAD, (uint32_t)eip, (uint32_t)esp, 0, 0, 0); -} - -void exit_thread() { - call(SC_EXIT_THREAD, 0, 0, 0, 0, 0); -} - -bool mmap(void* addr, size_t size, int mode) { - return call(SC_MMAP, (uint32_t)addr, size, mode, 0, 0); -} -bool mmap_file(fd_t file, size_t offset, void* addr, size_t size, int mode) { - return call(SC_MMAP_FILE, file, offset, (uint32_t)addr, size, mode); -} -bool mchmap(void* addr, int mode) { - return call(SC_MCHMAP, (uint32_t)addr, mode, 0, 0, 0); -} -bool munmap(void* addr) { - return call(SC_MUNMAP, (uint32_t)addr, 0, 0, 0, 0); -} - -bool create(const char* name, int type) { - return call(SC_CREATE, (uint32_t)name, strlen(name), type, 0, 0); -} -bool delete(const char* name) { - return call(SC_CREATE, (uint32_t)name, strlen(name), 0, 0, 0); -} -bool move(const char* oldname, const char* newname) { - return call(SC_MOVE, (uint32_t)oldname, strlen(oldname), (uint32_t)newname, strlen(newname), 0); -} -bool stat(const char* name, stat_t *s) { - return call(SC_STAT, (uint32_t)name, strlen(name), (uint32_t)s, 0, 0); -} - -fd_t open(const char* name, int mode) { - return call(SC_OPEN, (uint32_t)name, strlen(name), mode, 0, 0); -} -void close(fd_t file) { - call(SC_CLOSE, file, 0, 0, 0, 0); -} -size_t read(fd_t file, size_t offset, size_t len, char *buf) { - return call(SC_READ, file, offset, len, (uint32_t)buf, 0); -} -size_t write(fd_t file, size_t offset, size_t len, const char* buf) { - return call(SC_WRITE, file, offset, len, (uint32_t)buf, 0); -} -bool readdir(fd_t file, size_t ent_no, dirent_t *d) { - return call(SC_READDIR, file, ent_no, (uint32_t)d, 0, 0); -} -bool stat_open(fd_t file, stat_t *s) { - return call(SC_STAT_OPEN, file, (uint32_t)s, 0, 0, 0); -} -int ioctl(fd_t file, int command, void* data) { - return call(SC_IOCTL, file, command, (uint32_t)data, 0, 0); -} -int fctl(fd_t file, int command, void *data) { - return call(SC_FCTL, file, command, (uint32_t)data, 0, 0); -} -bool select(sel_fd_t* fds, size_t nfds, int timeout) { - return call(SC_SELECT, (uint32_t)fds, nfds, timeout, 0, 0); -} - -fd_pair_t make_channel(bool blocking) { - fd_pair_t ret; - call(SC_MK_CHANNEL, blocking, (uint32_t)&ret, 0, 0, 0); - return ret; -} -fd_t make_shm(size_t s) { - return call(SC_MK_SHM, s, 0, 0, 0, 0); -} -bool gen_token(fd_t file, token_t *tok) { - return call(SC_GEN_TOKEN, file, (uint32_t)tok, 0, 0, 0); -} -fd_t use_token(token_t *tok) { - return call(SC_USE_TOKEN, (uint32_t)tok, 0, 0, 0, 0); -} - -bool make_fs(const char* name, const char* driver, fd_t source, const char* options) { - volatile sc_make_fs_args_t args = { - .driver = driver, - .driver_strlen = strlen(driver), - .fs_name = name, - .fs_name_strlen = strlen(name), - .source_fd = source, - .opts = options, - .opts_strlen = strlen(options), - .bind_to_pid = 0, - }; - return call(SC_MAKE_FS, (uint32_t)&args, 0, 0, 0, 0); -} -bool fs_add_source(const char* fs, fd_t source, const char* options) { - return call(SC_FS_ADD_SRC, (uint32_t)fs, strlen(fs), source, (uint32_t)options, strlen(options)); -} -bool fs_subfs(const char* name, const char* orig_fs, const char* root, int ok_modes) { - volatile sc_subfs_args_t args = { - .new_name = name, - .new_name_strlen = strlen(name), - .from_fs = orig_fs, - .from_fs_strlen = strlen(orig_fs), - .root = root, - .root_strlen = strlen(root), - .ok_modes = ok_modes, - .bind_to_pid = 0 - }; - return call(SC_SUBFS, (uint32_t)(&args), 0, 0, 0, 0); -} -void fs_remove(const char* name) { - call(SC_RM_FS, (uint32_t)name, strlen(name), 0, 0, 0); -} - -pid_t new_proc() { - return call(SC_NEW_PROC, 0, 0, 0, 0, 0); -} -bool bind_fs(pid_t pid, const char* new_name, const char* fs) { - return call(SC_BIND_FS, pid, (uint32_t)new_name, strlen(new_name), (uint32_t)fs, strlen(fs)); -} -bool bind_subfs(pid_t pid, const char* new_name, const char* orig_fs, const char* root, int ok_modes) { - sc_subfs_args_t args = { - .new_name = new_name, - .new_name_strlen = strlen(new_name), - .from_fs = orig_fs, - .from_fs_strlen = strlen(orig_fs), - .root = root, - .root_strlen = strlen(root), - .ok_modes = ok_modes, - .bind_to_pid = pid - }; - return call(SC_BIND_SUBFS, (uint32_t)&args, 0, 0, 0, 0); -} -bool bind_make_fs(pid_t pid, const char* name, const char* driver, fd_t source, const char* options) { - sc_make_fs_args_t args = { - .driver = driver, - .driver_strlen = strlen(driver), - .fs_name = name, - .fs_name_strlen = strlen(name), - .source_fd = source, - .opts = options, - .opts_strlen = strlen(options), - .bind_to_pid = pid, - }; - return call(SC_BIND_MAKE_FS, (uint32_t)&args, 0, 0, 0, 0); -} -bool bind_fd(pid_t pid, fd_t new_fd, fd_t fd) { - return call(SC_BIND_FD, pid, new_fd, fd, 0, 0); -} -bool proc_exec(pid_t pid, const char* file) { - return call(SC_PROC_EXEC, pid, (uint32_t)file, strlen(file), 0, 0); -} -bool proc_status(pid_t pid, proc_status_t *s) { - return call(SC_PROC_STATUS, pid, (uint32_t)s, 0, 0, 0); -} -bool proc_kill(pid_t pid, proc_status_t *s) { - return call(SC_PROC_KILL, pid, (uint32_t)s, 0, 0, 0); -} -void proc_wait(pid_t pid, bool block, proc_status_t *s) { - call(SC_PROC_WAIT, pid, block, (uint32_t)s, 0, 0); -} - - - - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/libkogata/unistd.c b/src/lib/libkogata/unistd.c deleted file mode 100644 index 101e02e..0000000 --- a/src/lib/libkogata/unistd.c +++ /dev/null @@ -1,67 +0,0 @@ -#include - -#include - -#include - - -char cwd_buf[256]; - -char* getcwd(char* buf, size_t buf_len) { - if (buf_len > strlen(cwd_buf)) { - strcpy(buf, cwd_buf); - return buf; - } else { - return 0; - } -} - -int chdir(const char* path) { - char cwd_buf2[256]; - strcpy(cwd_buf2, cwd_buf); - - if (!pathncat(cwd_buf2, path, 256)) return -1; - - stat_t st; - if (!stat(cwd_buf2, &st)) return -1; - if (!(st.type & FT_DIR)) return -1; - - strcpy(cwd_buf, cwd_buf2); - return 0; -} - -char* pathncat(char* buf, const char* add, size_t buf_len) { - if (strchr(add, ':')) { - if (strlen(add) < buf_len) { - strcpy(buf, add); - return buf; - } else { - return 0; - } - } else { - char* sep_init = strchr(buf, ':'); - if (add[0] == '/') { - if (strlen(add) + (sep_init + 1 - buf) < buf_len) { - strcpy(sep_init + 1, add); - return buf; - } else { - return 0; - } - } else { - //TODO: simplify '..' - char* end = buf + strlen(buf) - 1; - if (*end != '/') end++; - if (end + 1 - buf + strlen(add) < buf_len) { - *end = '/'; - strcpy(end + 1, add); - return buf; - } else { - return 0; - } - } - return 0; - } -} - - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/sysbin/bam.lua b/src/sysbin/bam.lua index d223beb..d9d5846 100644 --- a/src/sysbin/bam.lua +++ b/src/sysbin/bam.lua @@ -5,20 +5,19 @@ local function sysbin_settings(name) return s end -local function sysbin_exe(name, moredeps) +local function sysbin_exe(name, deps) local s = sysbin_settings(name) local src = Collect('src/sysbin/' .. name .. '/*.c') local obj = Compile(s, src) - return Link(s, 'sysbin/' .. name .. ".bin", {obj, libkogata, moredeps}) + return Link(s, 'sysbin/' .. name .. ".bin", {obj, deps}) end sysbin = { - sysbin_exe('init'), - sysbin_exe('giosrv'), - sysbin_exe('login'), - sysbin_exe('terminal'), - --sysbin_exe('shell', {liblua, liblualib}), - sysbin_exe('shell'), + sysbin_exe('init', {libkogata}), + sysbin_exe('giosrv', {libkogata}), + sysbin_exe('login', {libkogata}), + sysbin_exe('terminal', {libkogata}), + sysbin_exe('shell', {libkogata}), } diff --git a/src/sysbin/giosrv/main.c b/src/sysbin/giosrv/main.c index e0b76f5..37f0f3c 100644 --- a/src/sysbin/giosrv/main.c +++ b/src/sysbin/giosrv/main.c @@ -1,14 +1,14 @@ #include -#include +#include -#include -#include -#include +#include +#include +#include #include -#include +#include // ---- GIP server diff --git a/src/sysbin/init/main.c b/src/sysbin/init/main.c index 6be0a87..da51223 100644 --- a/src/sysbin/init/main.c +++ b/src/sysbin/init/main.c @@ -1,13 +1,11 @@ #include -#include +#include -#include +#include +#include +#include -#include -#include -#include - -#include +#include pid_t giosrv_pid = 0, login_pid = 0; fd_pair_t root_gip_chan; diff --git a/src/sysbin/login/main.c b/src/sysbin/login/main.c index dfc5dfa..c9d2455 100644 --- a/src/sysbin/login/main.c +++ b/src/sysbin/login/main.c @@ -1,8 +1,8 @@ #include -#include -#include +#include -#include +#include +#include int main(int argc, char **argv) { dbg_print("[login] Starting up.\n"); diff --git a/src/sysbin/shell/main.c b/src/sysbin/shell/main.c index 3f37ff8..81ecdfa 100644 --- a/src/sysbin/shell/main.c +++ b/src/sysbin/shell/main.c @@ -1,11 +1,11 @@ #include -#include -#include +#include #include #include -#include +#include +#include void ls(char* dir) { fd_t f = open(dir, FM_READDIR); diff --git a/src/sysbin/terminal/main.c b/src/sysbin/terminal/main.c index a0d8855..fe2376f 100644 --- a/src/sysbin/terminal/main.c +++ b/src/sysbin/terminal/main.c @@ -1,11 +1,12 @@ #include -#include -#include -#include +#include -#include -#include -#include +#include +#include + +#include +#include +#include #define NCOLORS 16 -- cgit v1.2.3