From 72cbd3d0cd4ad963461585b622e0badac146594a Mon Sep 17 00:00:00 2001 From: zhangzheng <1358745329@qq.com> Date: Thu, 13 Feb 2025 20:45:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=BD=9C=E5=9C=A8=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TODO.md | 4 +- mkrtos_knl/inc/knl/sema.h | 2 +- mkrtos_knl/knl/sema.c | 97 +++++++++----------- mkrtos_knl/knl/sleep.c | 2 +- mkrtos_user/server/init/src/test/sema_test.c | 50 +++++----- 5 files changed, 74 insertions(+), 81 deletions(-) diff --git a/TODO.md b/TODO.md index 1d1518497..6f672286e 100644 --- a/TODO.md +++ b/TODO.md @@ -10,10 +10,10 @@ * [ ] 进程管理机制完善,进程状态订阅,进程间信号发送。 * [ ] 内核信号量对象完善(支持优先级反转,支持超时)。 * [ ] FPU完善支持,目前版本偶发压栈错误 -* [ ] console 支持自动切换 +* [ ] console 支持自动切换前后台 * [ ] 重构路径管理 * [ ] 线程占用率统计 -* [ ] 去除原来的ipc机制(使用fastipc机制),并单独实现sleep接口,目前的ipc有概率卡死问题 +* [x] 去除原来的ipc机制(使用fastipc机制),并单独实现sleep接口,目前的ipc有概率卡死问题 * [ ] 几大组件稳定性测试 ### mid prio * [ ] net server support diff --git a/mkrtos_knl/inc/knl/sema.h b/mkrtos_knl/inc/knl/sema.h index ba34eb5a8..f24404fc9 100644 --- a/mkrtos_knl/inc/knl/sema.h +++ b/mkrtos_knl/inc/knl/sema.h @@ -2,7 +2,7 @@ #include #include - +#include typedef struct sema { kobject_t kobj; //!< 内核对象节点 diff --git a/mkrtos_knl/knl/sema.c b/mkrtos_knl/knl/sema.c index 8fffd87bd..aaf05a56f 100644 --- a/mkrtos_knl/knl/sema.c +++ b/mkrtos_knl/knl/sema.c @@ -1,23 +1,21 @@ -#include "types.h" -#include "kobject.h" -#include "spinlock.h" -#include "atomics.h" -#include "slist.h" -#include "thread.h" -#include "factory.h" #include "sema.h" +#include "atomics.h" +#include "factory.h" #include "init.h" +#include "kobject.h" #include "ref.h" -#include "slist.h" #include "sleep.h" +#include "slist.h" +#include "spinlock.h" +#include "thread.h" +#include "types.h" #if IS_ENABLED(CONFIG_BUDDY_SLAB) #include static slab_t *sema_slab; #endif -enum SEMA_OP -{ +enum SEMA_OP { SEMA_UP, SEMA_DOWN, }; @@ -30,8 +28,7 @@ static void sema_mem_init(void) #endif } INIT_KOBJ_MEM(sema_mem_init); -typedef struct sema_wait_item -{ +typedef struct sema_wait_item { slist_head_t node; thread_t *thread; } sema_wait_item_t; @@ -48,29 +45,23 @@ void sema_up(sema_t *obj) umword_t status; status = spinlock_lock(&obj->lock); - if (slist_is_empty(&obj->suspend_head)) - { - if (obj->cnt < obj->max_cnt) - { + if (slist_is_empty(&obj->suspend_head)) { + if (obj->cnt < obj->max_cnt) { obj->cnt++; } // printk("up0 sema cnt:%d max:%d.\n", obj->cnt, obj->max_cnt); - } - else - { + } else { slist_head_t *first_wait_node; sema_wait_item_t *first_wait; first_wait_node = slist_first(&obj->suspend_head); first_wait = container_of(first_wait_node, sema_wait_item_t, node); slist_del(first_wait_node); - if (ref_counter_dec_and_release(&first_wait->thread->ref, &first_wait->thread->kobj) != 1) - { + if (ref_counter_dec_and_release(&first_wait->thread->ref, &first_wait->thread->kobj) != 1) { // thread_ready_remote(first_wait->thread, FALSE); thread_sleep_del_and_wakeup(first_wait->thread); } - if (obj->cnt < obj->max_cnt) - { + if (obj->cnt < obj->max_cnt) { obj->cnt++; } // printk("up1 sema cnt:%d max:%d.\n", obj->cnt, obj->max_cnt); @@ -88,19 +79,25 @@ umword_t sema_down(sema_t *obj, umword_t ticks) again: status = spinlock_lock(&obj->lock); - if (obj->cnt == 0) - { + if (obj->cnt == 0) { sema_wait_item_init(&wait_item, th); ref_counter_inc(&th->ref); slist_add_append(&obj->suspend_head, &wait_item.node); - // thread_suspend_sw(th, FALSE); remain_sleep = thread_sleep(ticks); - spinlock_set(&obj->lock, status); - preemption(); - goto again; - } - else - { + if (remain_sleep == 0 && ticks != 0) { + // 超时退出的,直接从列表中删除 + assert(slist_in_list(&wait_item.node)); + slist_del(&wait_item.node); + ref_counter_dec(&th->ref); + } + if (!(remain_sleep == 0 && ticks != 0)) { + spinlock_set(&obj->lock, status); + if (cpulock_get_status()) { + preemption(); + } + goto again; + } + } else { assert(obj->cnt > 0); obj->cnt--; // printk("down sema cnt:%d max:%d.\n", obj->cnt, obj->max_cnt); @@ -116,21 +113,16 @@ static void sema_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t tag = msg_tag_init4(0, 0, 0, -EINVAL); task_t *task = thread_get_current_task(); - if (sys_p.prot != SEMA_PROT) - { + if (sys_p.prot != SEMA_PROT) { f->regs[0] = msg_tag_init4(0, 0, 0, -EPROTO).raw; return; } - switch (sys_p.op) - { - case SEMA_UP: - { + switch (sys_p.op) { + case SEMA_UP: { sema_up(sema); tag = msg_tag_init4(0, 0, 0, 0); - } - break; - case SEMA_DOWN: - { + } break; + case SEMA_DOWN: { umword_t ret; ret = sema_down(sema, f->regs[0]); @@ -150,8 +142,7 @@ static sema_t *sema_create(ram_limit_t *lim, umword_t cnt, umword_t max) #else kobj = mm_limit_alloc(lim, sizeof(sema_t)); #endif - if (!kobj) - { + if (!kobj) { return NULL; } sema_init(kobj, cnt, max); @@ -175,12 +166,10 @@ static void sema_release_stage1(kobject_t *kobj) first_wait_node = slist_first(&obj->suspend_head); first_wait = container_of(first_wait_node, sema_wait_item_t, node); slist_del(first_wait_node); - if (ref_counter_dec_and_release(&first_wait->thread->ref, &first_wait->thread->kobj) != 1) - { + if (ref_counter_dec_and_release(&first_wait->thread->ref, &first_wait->thread->kobj) != 1) { thread_ready_remote(first_wait->thread, FALSE); } - if (obj->cnt < obj->max_cnt) - { + if (obj->cnt < obj->max_cnt) { obj->cnt++; } } @@ -199,16 +188,13 @@ static void sema_release_stage2(kobject_t *kobj) void sema_init(sema_t *obj, int cnt, int max) { - if (max <= 0) - { + if (max <= 0) { max = 1; } - if (cnt < 0) - { + if (cnt < 0) { cnt = 0; } - if (cnt > max) - { + if (cnt > max) { cnt = max; } obj->cnt = cnt; @@ -227,8 +213,7 @@ static kobject_t *sema_func(ram_limit_t *lim, umword_t arg0, umword_t arg1, umword_t arg2, umword_t arg3) { sema_t *sema = sema_create(lim, arg0, arg1); - if (!sema) - { + if (!sema) { return NULL; } return &sema->kobj; diff --git a/mkrtos_knl/knl/sleep.c b/mkrtos_knl/knl/sleep.c index a88341529..3f75c5cbc 100644 --- a/mkrtos_knl/knl/sleep.c +++ b/mkrtos_knl/knl/sleep.c @@ -44,7 +44,6 @@ void thread_check_timeout(void) pos, (slist_head_t *)&wait_list, node) { - assert(pos->th->status == THREAD_SUSPEND); thread_wait_entry_t *next = slist_next_entry( pos, (slist_head_t *)wait_list, node); @@ -53,6 +52,7 @@ void thread_check_timeout(void) pos->times--; if (pos->times == 0) { + assert(pos->th->status == THREAD_SUSPEND); thread_ready(pos->th, TRUE); slist_del(&pos->node); } diff --git a/mkrtos_user/server/init/src/test/sema_test.c b/mkrtos_user/server/init/src/test/sema_test.c index 117462a3d..f8dec4212 100644 --- a/mkrtos_user/server/init/src/test/sema_test.c +++ b/mkrtos_user/server/init/src/test/sema_test.c @@ -1,13 +1,13 @@ #include "u_factory.h" -#include "u_sema.h" #include "u_hd_man.h" +#include "u_sema.h" #include "u_task.h" -#include +#include #include #include #include -#include +#include #include int u_sema_test(void) @@ -34,14 +34,12 @@ static obj_handler_t sema_hd2; static void *thread_th1(void *arg) { int j = 0; - while (1) - { + while (1) { printf("sema_up start\n"); u_sema_up(sema_hd2); u_sleep_ms(100); printf("sema_up end\n"); - if (j == TEST_CN * 2 + 2) - { + if (j == TEST_CN * 2 + 2) { break; } j++; @@ -52,14 +50,12 @@ static void *thread_th1(void *arg) static void *thread_th2(void *arg) { int j = 0; - while (1) - { + while (1) { printf("sema_down start\n"); u_sema_down(sema_hd2, 0, NULL); u_sleep_ms(50); printf("sema_down end\n"); - if (j == TEST_CN) - { + if (j == TEST_CN) { break; } j++; @@ -70,14 +66,12 @@ static void *thread_th2(void *arg) static void *thread_th3(void *arg) { int j = 0; - while (1) - { + while (1) { printf("sema_down2 start\n"); u_sema_down(sema_hd2, 0, NULL); u_sleep_ms(50); printf("sema_down2 end\n"); - if (j == TEST_CN) - { + if (j == TEST_CN) { break; } j++; @@ -97,25 +91,39 @@ static void u_sema_test2(CuTest *tc) CuAssert(tc, "pthread_create fail.\n", pthread_create(&pth1, NULL, thread_th1, NULL) == 0); CuAssert(tc, "pthread_create fail.\n", pthread_create(&pth2, NULL, thread_th2, NULL) == 0); CuAssert(tc, "pthread_create fail.\n", pthread_create(&pth3, NULL, thread_th3, NULL) == 0); - if (pth1 != PTHREAD_NULL) - { + if (pth1 != PTHREAD_NULL) { CuAssert(tc, "pthread_join fail.\n", pthread_join(pth1, NULL) == 0); } - if (pth2 != PTHREAD_NULL) - { + if (pth2 != PTHREAD_NULL) { CuAssert(tc, "pthread_join fail.\n", pthread_join(pth2, NULL) == 0); } - if (pth3 != PTHREAD_NULL) - { + if (pth3 != PTHREAD_NULL) { CuAssert(tc, "pthread_join fail.\n", pthread_join(pth3, NULL) == 0); } } +static void u_sema_test3(CuTest *tc) +{ + msg_tag_t tag; + obj_handler_t sema_hd2; + umword_t reamin_times; + + tag = facotry_create_sema(FACTORY_PROT, + vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, sema_hd2), 0, 1); + CuAssert(tc, "hd alloc fail.\n", msg_tag_get_val(tag) >= 0); + for (int i = 0; i < 5; i++) { + tag = u_sema_down(sema_hd2, 100, &reamin_times); + CuAssert(tc, "sema down fail.\n", msg_tag_get_val(tag) >= 0); + CuAssert(tc, "sema down fail.\n", reamin_times == 0); + } + handler_free_umap(sema_hd2); +} static CuSuite suite; CuSuite *sema_test_suite(void) { CuSuiteInit(&suite); SUITE_ADD_TEST(&suite, u_sema_test2); + SUITE_ADD_TEST(&suite, u_sema_test3); return &suite; }