diff --git a/include/arch/mr_hw_stack.h b/include/arch/mr_hw_stack.h deleted file mode 100644 index a024eed..0000000 --- a/include/arch/mr_hw_stack.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @copyright (c) 2024, MacRsh - * - * @license SPDX-License-Identifier: Apache-2.0 - * - * @date 2024-09-06 MacRsh First version - */ - -#ifndef __MR_HW_STACK_H__ -#define __MR_HW_STACK_H__ - -#ifdef __cplusplus -"C" { -#endif /* __cplusplus */ - -/** - * @addtogroup Stack hardware interface - * @{ - */ - -/** - * @brief This function initialize the hardware stack. - * @param entry The entry point. - * @param stack_addr The stack address(top). - * @return The top of the stack. - */ - void *mr_hw_stack_init(void *entry, void *stack_addr); - -/** - * @brief This function switch the hardware stack. - * - * @param from The old stack address(top). - * @param to The new stack address(top). - */ -void mr_hw_context_switch(void *from, void *to); - -/** - * @brief This function switch the hardware stack. - * - * @param to The new stack address(top). - */ -void mr_hw_context_switch_to(void *to); - -/** @} */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __MR_HW_STACK_H__ */ diff --git a/include/kernel/kos/mr_kos.h b/include/kernel/kos/mr_kos.h index 981888e..6bd4966 100644 --- a/include/kernel/kos/mr_kos.h +++ b/include/kernel/kos/mr_kos.h @@ -54,23 +54,37 @@ typedef struct mr_kos { } mr_kos_t; /** - * @brief This function registers kernel os. + * @brief This function registers a kernel os. * * @return 0 on success, or a negative error code on failure. */ -mr_err_t mr_kos_register(mr_kos_type_t *type); +mr_err_t mr_kos_register(mr_kos_type_t *ktype); /** - * @brief This function gets kernel os. + * @brief This function gets a kernel os. + * + * @param kos The kernel os. + * @return The kernel os on success, or MR_NULL on failure. + */ +MR_INLINE mr_kos_t *mr_kos_get(mr_kos_t *kos) { + return (mr_kos_t *)mr_kobject_get((mr_kobject_t *)kos); +} + +/** + * @brief This function puts a kernel os. + * + * @param kos The kernel os. + */ +MR_INLINE void mr_kos_put(mr_kos_t *kos) { + mr_kobject_put((mr_kobject_t *)kos); +} + +/** + * @brief This function finds a kernel os. * * @return The kernel os. */ -mr_kos_t *mr_kos_get(void); - -/** - * @brief This function puts kernel os. - */ -void mr_kos_put(void); +mr_kos_t *mr_kos_find(void); /** * @brief This macro function gets the kthread operations of a kernel os. diff --git a/include/kernel/kos/mr_kthread.h b/include/kernel/kos/mr_kthread.h index d42d2d8..f00c1b6 100644 --- a/include/kernel/kos/mr_kthread.h +++ b/include/kernel/kos/mr_kthread.h @@ -144,6 +144,25 @@ mr_err_t mr_kthread_exit(mr_kthread_t *kth); */ mr_kthread_t *mr_kthread_self(void); +/** + * @brief This function get a kthread. + * + * @param kth The kthread. + * @return The kthread on success, or MR_NULL on failure. + */ +MR_INLINE mr_kthread_t *mr_kthread_get(mr_kthread_t *kth) { + return (mr_kthread_t *)mr_kobject_get((mr_kobject_t *)kth); +} + +/** + * @brief This function put a kthread. + * + * @param kth The kthread. + */ +MR_INLINE void mr_kthread_put(mr_kthread_t *kth) { + mr_kobject_put((mr_kobject_t *)kth); +} + /** * @brief This function find a kthread. * diff --git a/include/mr_config.h b/include/mr_config.h index 64378b9..a7f824f 100644 --- a/include/mr_config.h +++ b/include/mr_config.h @@ -5,6 +5,7 @@ extern "C" { #endif /* __cplusplus */ +#define MR_USE_LIBC_PRINTF #ifdef __cplusplus } diff --git a/kernel/kos/kos.c b/kernel/kos/kos.c index 3251ac9..9a85c66 100644 --- a/kernel/kos/kos.c +++ b/kernel/kos/kos.c @@ -8,41 +8,36 @@ #include -static mr_kos_t kos; +static mr_kos_t kroot; -MR_INLINE void kos_init(mr_kos_t *os, mr_kos_type_t *type) { +MR_INLINE void kos_init(mr_kos_t *os, mr_kos_type_t *ktype) { /* Init kos */ - os->type = type; + os->type = ktype; } -MR_INLINE mr_err_t kos_init_register(mr_kos_t *os, const char *name, - mr_kos_type_t *type) { +MR_INLINE mr_err_t kos_init_register(mr_kos_t *kos, const char *name, + mr_kos_type_t *ktype) { /* Init kos */ - kos_init(os, type); + kos_init(kos, ktype); /* Init kset */ - mr_kset_init((mr_kset_t *)os, MR_NULL); + mr_kset_init((mr_kset_t *)kos, MR_NULL); /* Register kset */ - return mr_kset_register((mr_kset_t *)os, name); + return mr_kset_register((mr_kset_t *)kos, name); } mr_err_t mr_kos_register(mr_kos_type_t *type) { /* Check arguments */ - if (MR_KOBJECT_IS_INITED(&kos) || (!type)) { + if (MR_KOBJECT_IS_INITED(&kroot) || (!type)) { return -MR_EINVAL; } /* Init and register kos */ - return kos_init_register(&kos, "os", type); + return kos_init_register(&kroot, "os", type); } -mr_kos_t *mr_kos_get(void) { - /* Get kos */ - return (mr_kos_t *)mr_kobject_get((mr_kobject_t *)&kos); -} - -void mr_kos_put(void) { - /* Put kos */ - mr_kobject_put((mr_kobject_t *)&kos); +mr_kos_t *mr_kos_find(void) { + /* Find kos in kroot */ + return &kroot; } diff --git a/kernel/kos/kthread.c b/kernel/kos/kthread.c index 7ee129c..2d78424 100644 --- a/kernel/kos/kthread.c +++ b/kernel/kos/kthread.c @@ -34,6 +34,20 @@ MR_INLINE mr_err_t kthread_res_alloc(mr_kthread_t *kth, mr_size_t size) { return 0; } +MR_INLINE void kthread_res_free(mr_kthread_t *kth) { + const void *res; + + /* If resource is inline or takeover, not need to free */ + res = ((kth->res != kth->ires) && (kth->entry)) ? kth->res : MR_NULL; + if (res) { + mr_free((void *)res); + } +} + +MR_INLINE mr_bool_t kthread_is_takeover(mr_kthread_t *kth) { + return (kth->res != kth->ires) && (!kth->entry); +} + MR_INLINE mr_err_t kthread_init(mr_kthread_t *kth, const char *name, mr_ptr_t entry, mr_ptr_t args, void *stack, mr_size_t stack_size, mr_uint32_t priority, @@ -47,30 +61,38 @@ MR_INLINE mr_err_t kthread_init(mr_kthread_t *kth, const char *name, return -MR_EINVAL; } + /* Non-takeover kthread need to initialize resources */ + if (!kthread_is_takeover(kth)) { + /* Alloc resource */ + ret = kthread_res_alloc(kth, type->size); + if (ret != 0) { + return ret; + } + + /* Init kthread resource */ + ret = MR_KOS_KTH_OPS(kos)->init((void *)kth->res, name, kth, stack, + stack_size, priority, tick); + if (ret != 0) { + kthread_res_free(kth); + return ret; + } + } + /* Init kthread */ kth->priority = priority; kth->tick = tick; kth->entry = entry; kth->args = args; - kth->os = kos; - - /* Takeover kthread resources not need init. */ - if (!kth->entry) { - return 0; - } - - /* Alloc resource */ - ret = kthread_res_alloc(kth, type->size); - if (ret != 0) { - return ret; - } - - /* Init kthread resource */ - return MR_KOS_KTH_OPS(kth->os)->init((void *)kth->res, name, kth, stack, - stack_size, priority, tick); + kth->os = mr_kos_get(kos); + return 0; } MR_INLINE mr_err_t kthread_del(mr_kthread_t *kth) { + /* Takeover kthread do not need to delete */ + if (kthread_is_takeover(kth)) { + return 0; + } + /* Delete kthread resource */ return MR_KOS_KTH_OPS(kth->os)->del((void *)kth->res); } @@ -84,7 +106,7 @@ MR_INLINE mr_err_t kthread_init_add(mr_kthread_t *kth, mr_ktype_t *ktype, mr_err_t ret; /* Get kos */ - kos = mr_kos_get(); + kos = mr_kos_get(mr_kos_find()); if (!kos) { return -MR_ENOSYS; } @@ -102,13 +124,15 @@ MR_INLINE mr_err_t kthread_init_add(mr_kthread_t *kth, mr_ktype_t *ktype, /* Add kobject to kroot */ ret = mr_kobject_add((mr_kobject_t *)kth, (mr_kobject_t *)&kroot, name); if (ret != 0) { + mr_kos_put(kos); kthread_del(kth); + kthread_res_free(kth); goto _exit; } _exit: /* Put kos */ - mr_kos_put(); + mr_kos_put(kos); return ret; } @@ -200,11 +224,20 @@ mr_err_t mr_kthread_del(mr_kthread_t *kth) { } MR_INLINE mr_err_t kthread_startup(mr_kthread_t *kth) { - /* Get kobject */ - mr_kobject_get((mr_kobject_t *)kth); + mr_err_t ret; + + /* Prevents run-time release(exit and cleanup) */ + mr_kthread_get(kth); + mr_kthread_get(kth); /* Startup kthread resource */ - return MR_KOS_KTH_OPS(kth->os)->startup((void *)kth->res); + ret = MR_KOS_KTH_OPS(kth->os)->startup((void *)kth->res); + if (ret != 0) { + mr_kthread_put(kth); + mr_kthread_put(kth); + return ret; + } + return 0; } mr_err_t mr_kthread_startup(mr_kthread_t *kth) { @@ -237,7 +270,7 @@ MR_INLINE mr_err_t kthread_yield(void) { mr_err_t ret; /* Get kos */ - kos = mr_kos_get(); + kos = mr_kos_get(mr_kos_find()); if (!kos) { return -MR_ENOSYS; } @@ -246,7 +279,7 @@ MR_INLINE mr_err_t kthread_yield(void) { ret = MR_KOS_KTH_OPS(kos)->yield(); /* Put kos */ - mr_kos_put(); + mr_kos_put(kos); return ret; } @@ -275,7 +308,7 @@ MR_INLINE mr_err_t kthread_sleep(mr_tick_t tick) { mr_err_t ret; /* Get kos */ - kos = mr_kos_get(); + kos = mr_kos_get(mr_kos_find()); if (!kos) { return -MR_ENOSYS; } @@ -284,7 +317,7 @@ MR_INLINE mr_err_t kthread_sleep(mr_tick_t tick) { ret = MR_KOS_KTH_OPS(kos)->sleep(tick); /* Put kos */ - mr_kos_put(); + mr_kos_put(kos); return ret; } @@ -294,8 +327,17 @@ mr_err_t mr_kthread_sleep(mr_tick_t tick) { } MR_INLINE mr_err_t kthread_exit(mr_kthread_t *kth) { + mr_err_t ret; + /* Exit kthread resource */ - return MR_KOS_KTH_OPS(kth->os)->exit((void *)kth->res); + ret = MR_KOS_KTH_OPS(kth->os)->exit((void *)kth->res); + if (ret != 0) { + return ret; + } + + /* Free runtime(exit) */ + mr_kthread_put(kth); + return 0; } mr_err_t mr_kthread_exit(mr_kthread_t *kth) { @@ -313,16 +355,16 @@ MR_INLINE mr_kthread_t *kthread_self(void) { mr_kos_t *kos; /* Get kos */ - kos = mr_kos_get(); + kos = mr_kos_get(mr_kos_find()); if (!kos) { return MR_NULL; } /* Get kthread self */ - ret = MR_KOS_KTH_OPS(mr_kos_get())->self(); + ret = MR_KOS_KTH_OPS(kos)->self(); /* Put kos */ - mr_kos_put(); + mr_kos_put(kos); return ret; } @@ -342,8 +384,8 @@ void mr_kthread_cleanup(mr_kthread_t *kth) { return; } - /* Cleanup kthread */ - mr_kobject_put((mr_kobject_t *)kth); + /* Free runtime(cleanup) */ + mr_kthread_put(kth); } void mr_kthread_entry(mr_kthread_t *kth) { @@ -354,23 +396,22 @@ void mr_kthread_entry(mr_kthread_t *kth) { /* Call kthread entry */ ((void (*)(mr_kthread_t *, void *))kth->entry)(kth, kth->args); + + /* Free runtime(exit) */ + mr_kthread_put(kth); } MR_INLINE mr_kthread_t *kthread_release_kobj(mr_kobject_t *kobj) { mr_kthread_t *kth; - const void *res; /* Get kthread */ kth = MR_CONTAINER_OF(kobj, mr_kthread_t, parent); - /* If resource is inline or takeover, not need to free */ - res = ((kth->res != kth->ires) && (kth->entry)) ? kth->res : MR_NULL; - if (res) { - mr_free((void *)res); - } + /* Free kthread resource */ + kthread_res_free(kth); /* Put kos */ - mr_kos_put(); + mr_kos_put(kth->os); return kth; }