diff options
Diffstat (limited to 'lib/libjove/object')
-rw-r--r-- | lib/libjove/object/directory.c | 187 | ||||
-rw-r--r-- | lib/libjove/object/untyped.c | 127 |
2 files changed, 314 insertions, 0 deletions
diff --git a/lib/libjove/object/directory.c b/lib/libjove/object/directory.c index a9487e8..9c12d5b 100644 --- a/lib/libjove/object/directory.c +++ b/lib/libjove/object/directory.c @@ -1,4 +1,191 @@ +#include "object-dir.h" #include <object.h> +#include <jove.h> #include <syscall.h> KernelObjectDirectory __rootdir; + +KernelObjectDirectory* +jove_object_as_objdir(KernelObjectTyped *typed) +{ + if(typed->type == KO_OBJECT_DIRECTORY) return (KernelObjectDirectory*)typed; + return NULL; +} + +void +_jove_alloc_objdir_inplace( + KernelObjectDirectory *dir, + KernelObjectDirectory *parent, + uint8_t memb) +{ + *dir = (KernelObjectDirectory) { + .typed = (KernelObjectTyped) { + .parent = parent, + .membi = memb, + .type = KO_OBJECT_DIRECTORY + }, + .lastmemb = 0, + .firstfree = 0, + .children = { 0 } + }; + + parent->children[memb] = JOVE_OBJECT_TYPED(dir); +} + +KernelObjectDirectory* +_jove_alloc_objdir( + KernelObjectDirectory *parent, + uint8_t memb) +{ + if(!_jove_alloc) { + jove_errno = EJOVE_NOALLOC; + return NULL; + } + if(parent->children[memb]) { + jove_errno = EJOVE_FULL; + return NULL; + } + + KernelObjectDirectory *dir = _jove_alloc(sizeof(KernelObjectDirectory)); + if(dir == NULL) return NULL; + + _jove_alloc_objdir_inplace(dir, parent, memb); + jove_errno = 0; + return dir; +} + +JoveError +jove_objdir_sync(KernelObjectDirectory *dir) +{ + if(dir->lastmemb) return dir->lastmemb; + + int kerr = _syscall_invoke_objdir_lastmemb(dir, &dir->lastmemb); + jove_errno = jove_error_from_kerror(kerr); + + return dir->lastmemb; +} + +extern JoveError +_jove_objdir_sync_at_arch( + KernelObjectDirectory *dir, + uint8_t i, + obj_type_t type, + KernelObjectTyped **memb + ); + +JoveError +jove_objdir_sync_at(KernelObjectDirectory *dir, uint8_t i, KernelObjectTyped** memb) +{ + obj_type_t type; + int err = _syscall_invoke_objdir_getmemb(dir, i, &type); + if(err != 0) return err; + + KernelObjectTyped *dirmemb = dir->children[i]; + if(dirmemb != NULL) { + if(dirmemb->type == type) { + if(memb) *memb = dirmemb; + return EJOVE_OK; + } + if(_jove_free == NULL) { + return EJOVE_NOFREE; + } + _jove_free(dirmemb); + } + if(_jove_alloc == NULL) + return EJOVE_NOALLOC; + + switch(type) { + case KO_NONE: + return EJOVE_OK; + case KO_OBJECT_DIRECTORY: + dirmemb = JOVE_OBJECT_TYPED(_jove_alloc_objdir(dir, i)); + if(memb) *memb = dirmemb; + break; + case KO_MEMORY_UNTYPED: + { + dirmemb = JOVE_OBJECT_TYPED(_jove_alloc_untyped(dir, i)); + if(memb) *memb = dirmemb; + break; + } + default: + return _jove_objdir_sync_at_arch(dir, i, type, memb); + } + return EJOVE_OK; +} + +int +jove_objdir_nmemb(KernelObjectDirectory *dir) +{ + int nmemb = 0; + for(unsigned i = 1; i < 256; i++) { + if(dir->children[i] != NULL) nmemb++; + } + return nmemb; +} + +int +jove_objdir_lastmemb(KernelObjectDirectory *dir) +{ + if(dir->lastmemb) return dir->lastmemb; + JoveError err = jove_error_from_kerror(_syscall_invoke_objdir_lastmemb(dir, &dir->lastmemb)); + if(err) { + jove_errno = err; + return 0; + } + return dir->lastmemb; +} + +KernelObjectTyped* +jove_objdir_get(KernelObjectDirectory *dir, uint8_t i) +{ + return dir->children[i]; +} + +JoveError +jove_objdir_move( + KernelObjectDirectory *dir, + uint8_t memb, + KernelObjectDirectory *dest_dir, + uint8_t dest_memb) +{ + if(!memb) + return EJOVE_BADOBJ; + if(!dir->children[memb]) + return EJOVE_BADOBJ; + + if(dest_memb) + return EJOVE_BADOBJ; + if(dest_dir->children[dest_memb]) + return EJOVE_FULL; + + int kerr = _syscall_invoke_objdir_move(dir, memb, dest_dir, dest_memb); + if(kerr) return jove_error_from_kerror(kerr); + + KernelObjectTyped *move = dir->children[memb]; + dir->children[memb] = NULL; + dest_dir->children[dest_memb] = move; + + if(dir->lastmemb == move->membi) { + dir->lastmemb = 0; + } + + move->parent = dest_dir; + move->membi = dest_memb; + return EJOVE_OK; +} + +JoveError jove_object_move( + KernelObjectTyped *typed, + KernelObjectDirectory *dest_dir, + uint8_t dest_memb) +{ + return jove_objdir_move(typed->parent, typed->membi, dest_dir, dest_memb); +} + +JoveError jove_object_move_inplace( + KernelObjectTyped *typed, + KernelObjectTyped *dest) +{ + return jove_objdir_move(typed->parent, typed->membi, dest->parent, dest->membi); +} + diff --git a/lib/libjove/object/untyped.c b/lib/libjove/object/untyped.c new file mode 100644 index 0000000..281bb60 --- /dev/null +++ b/lib/libjove/object/untyped.c @@ -0,0 +1,127 @@ +#include <jove.h> +#include <object.h> +#include <syscall.h> +#include <error.h> +#include <string.h> + +void +_jove_alloc_untyped_inplace( + KernelObjectUntyped *untyped, + KernelObjectDirectory *parent, + uint8_t membi + ) +{ + *untyped = (KernelObjectUntyped) { + .typed = (KernelObjectTyped) { + .type = KO_MEMORY_UNTYPED, + .parent = parent, + .membi = membi + }, + .bytes = 0, + .alignment = -1, + .children_head = NULL, + .sibling = NULL + }; + + parent->children[membi] = (KernelObjectTyped*)untyped; + parent->lastmemb = 0; +} + +KernelObjectUntyped* +_jove_alloc_untyped(KernelObjectDirectory *parent, uint8_t membi) +{ + if(_jove_alloc == NULL) { + jove_errno = EJOVE_NOALLOC; + return NULL; + } + if(parent->children[membi] != NULL) { + jove_errno = EJOVE_FULL; + } + + KernelObjectUntyped *untyped = _jove_alloc(sizeof(KernelObjectUntyped)); + + _jove_alloc_untyped_inplace(untyped, parent, membi); + return untyped; +} + +KernelObjectUntyped* +jove_object_as_untyped(KernelObjectTyped *typed) +{ + if(typed->type == KO_MEMORY_UNTYPED) return (KernelObjectUntyped*)typed; + jove_errno = EJOVE_BADOBJ; + return NULL; +} + +int +jove_untyped_size(KernelObjectUntyped *untyped) +{ + if(untyped->bytes != 0) + return untyped->bytes; + + int e = _syscall_invoke_untyped_size(untyped, &untyped->bytes); + if(e) return jove_error_from_kerror(e); + + return untyped->bytes; +} + +int +jove_untyped_alignment(KernelObjectUntyped *untyped) +{ + if(untyped->alignment >= 0) + return untyped->alignment; + + int e = _syscall_invoke_untyped_alignment(untyped, (size_t*)&untyped->alignment); + if(e) return jove_error_from_kerror(e); + + return untyped->alignment; +} + +KernelObjectUntyped* +jove_untyped_split( + KernelObjectUntyped *untyped, + size_t bytes, + KernelObjectDirectory *dest, + uint8_t destmemb + ) +{ + if(!_jove_alloc) { + jove_errno = EJOVE_NOALLOC; + return NULL; + } + + KernelObjectUntyped temp; + _jove_alloc_untyped_inplace(&temp, dest, destmemb); + + jove_errno = jove_untyped_split_inplace(untyped, bytes, &temp); + if(jove_errno) return NULL; + + KernelObjectUntyped *newuntyped = _jove_alloc(sizeof(KernelObjectUntyped)); + memcpy(newuntyped, &temp, sizeof(KernelObjectUntyped)); + + dest->children[destmemb] = JOVE_OBJECT_TYPED(newuntyped); + return newuntyped; +} + +JoveError jove_untyped_split_inplace( + KernelObjectUntyped *untyped, + size_t bytes, + KernelObjectUntyped *dest) +{ + if(jove_untyped_size(untyped) - sizeof(size_t) <= bytes) { + return EJOVE_BADSIZE; + } + if(bytes < sizeof(size_t)) { + return EJOVE_BADSIZE;; + } + + int e = _syscall_invoke_untyped_split(untyped, bytes, dest); + if(e) { + return jove_error_from_kerror(e); + } + + dest->bytes = bytes; + dest->alignment = -1; + untyped->bytes -= bytes; + + return EJOVE_OK; +} |