diff options
Diffstat (limited to 'arch/x86_64/hal/obj.c')
| -rw-r--r-- | arch/x86_64/hal/obj.c | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/arch/x86_64/hal/obj.c b/arch/x86_64/hal/obj.c index af0491a..cb0e13d 100644 --- a/arch/x86_64/hal/obj.c +++ b/arch/x86_64/hal/obj.c @@ -16,6 +16,18 @@ obj_take(jove_obj_t *obj) return (jove_owned_obj_t*)obj; } +jove_owned_obj_t* +obj_trytake(jove_obj_t *obj) +{ + if((uintptr_t)obj < IDENT_VIRT_BASE) { + reterr(EBADOBJ); + } + if(try_take_mutex(&obj->lock)) { + reterr(EBUSY); + } + return (jove_owned_obj_t*)obj; +} + jove_obj_t* obj_release(jove_owned_obj_t *obj) { @@ -97,16 +109,32 @@ objdir_getlocal( } jove_owned_obj_t* +objdir_trygetlocal( + jove_owned_obj_t *objdir_obj, + uint16_t entry) +{ + if(obj_gettype_linked(objdir_obj) != JOVE_OBJ_OBJDIR) { + reterr(EBADOBJ); + } + if(entry >= JOVE_OBJDIR_ENTRIES) { + reterr(EBADPATH); + } + + jove_objdir_t *objtab = obj_deref_linked(objdir_obj); + return obj_trytake(&objtab->entries[entry]); +} + +jove_owned_obj_t* objdir_getobj( jove_owned_obj_t *objdir_obj, const uint16_t *path, size_t path_len) { + errno = 0; if(path_len == 0) { return objdir_obj; } { - errno = 0; jove_owned_obj_t *child_objdir = objdir_getlocal(objdir_obj, path[0]); if(child_objdir == 0) { reterr(EBADPATH); @@ -118,3 +146,25 @@ objdir_getobj( } } +jove_owned_obj_t* +objdir_trygetobj( + jove_owned_obj_t *objdir_obj, + const uint16_t *path, + size_t path_len) +{ + errno = 0; + if(path_len == 0) { + return objdir_obj; + } + { + jove_owned_obj_t *child_objdir = objdir_trygetlocal(objdir_obj, path[0]); + if(child_objdir == 0) { + return 0; + } + + jove_owned_obj_t *target_obj = objdir_trygetobj(child_objdir, path + 1, path_len - 1); + obj_release(child_objdir); + return target_obj; + } +} + |
