修复潜在问题

This commit is contained in:
zhangzheng
2025-02-13 20:45:46 +08:00
parent fe4e4a377d
commit 72cbd3d0cd
5 changed files with 74 additions and 81 deletions

View File

@@ -10,10 +10,10 @@
* [ ] 进程管理机制完善,进程状态订阅,进程间信号发送。 * [ ] 进程管理机制完善,进程状态订阅,进程间信号发送。
* [ ] 内核信号量对象完善(支持优先级反转,支持超时)。 * [ ] 内核信号量对象完善(支持优先级反转,支持超时)。
* [ ] FPU完善支持目前版本偶发压栈错误 * [ ] FPU完善支持目前版本偶发压栈错误
* [ ] console 支持自动切换 * [ ] console 支持自动切换前后台
* [ ] 重构路径管理 * [ ] 重构路径管理
* [ ] 线程占用率统计 * [ ] 线程占用率统计
* [ ] 去除原来的ipc机制使用fastipc机制并单独实现sleep接口目前的ipc有概率卡死问题 * [x] 去除原来的ipc机制使用fastipc机制并单独实现sleep接口目前的ipc有概率卡死问题
* [ ] 几大组件稳定性测试 * [ ] 几大组件稳定性测试
### mid prio ### mid prio
* [ ] net server support * [ ] net server support

View File

@@ -2,7 +2,7 @@
#include <spinlock.h> #include <spinlock.h>
#include <slist.h> #include <slist.h>
#include <kobject.h>
typedef struct sema typedef struct sema
{ {
kobject_t kobj; //!< 内核对象节点 kobject_t kobj; //!< 内核对象节点

View File

@@ -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 "sema.h"
#include "atomics.h"
#include "factory.h"
#include "init.h" #include "init.h"
#include "kobject.h"
#include "ref.h" #include "ref.h"
#include "slist.h"
#include "sleep.h" #include "sleep.h"
#include "slist.h"
#include "spinlock.h"
#include "thread.h"
#include "types.h"
#if IS_ENABLED(CONFIG_BUDDY_SLAB) #if IS_ENABLED(CONFIG_BUDDY_SLAB)
#include <slab.h> #include <slab.h>
static slab_t *sema_slab; static slab_t *sema_slab;
#endif #endif
enum SEMA_OP enum SEMA_OP {
{
SEMA_UP, SEMA_UP,
SEMA_DOWN, SEMA_DOWN,
}; };
@@ -30,8 +28,7 @@ static void sema_mem_init(void)
#endif #endif
} }
INIT_KOBJ_MEM(sema_mem_init); INIT_KOBJ_MEM(sema_mem_init);
typedef struct sema_wait_item typedef struct sema_wait_item {
{
slist_head_t node; slist_head_t node;
thread_t *thread; thread_t *thread;
} sema_wait_item_t; } sema_wait_item_t;
@@ -48,29 +45,23 @@ void sema_up(sema_t *obj)
umword_t status; umword_t status;
status = spinlock_lock(&obj->lock); status = spinlock_lock(&obj->lock);
if (slist_is_empty(&obj->suspend_head)) if (slist_is_empty(&obj->suspend_head)) {
{ if (obj->cnt < obj->max_cnt) {
if (obj->cnt < obj->max_cnt)
{
obj->cnt++; obj->cnt++;
} }
// printk("up0 sema cnt:%d max:%d.\n", obj->cnt, obj->max_cnt); // printk("up0 sema cnt:%d max:%d.\n", obj->cnt, obj->max_cnt);
} } else {
else
{
slist_head_t *first_wait_node; slist_head_t *first_wait_node;
sema_wait_item_t *first_wait; sema_wait_item_t *first_wait;
first_wait_node = slist_first(&obj->suspend_head); first_wait_node = slist_first(&obj->suspend_head);
first_wait = container_of(first_wait_node, sema_wait_item_t, node); first_wait = container_of(first_wait_node, sema_wait_item_t, node);
slist_del(first_wait_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_ready_remote(first_wait->thread, FALSE);
thread_sleep_del_and_wakeup(first_wait->thread); thread_sleep_del_and_wakeup(first_wait->thread);
} }
if (obj->cnt < obj->max_cnt) if (obj->cnt < obj->max_cnt) {
{
obj->cnt++; obj->cnt++;
} }
// printk("up1 sema cnt:%d max:%d.\n", obj->cnt, obj->max_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: again:
status = spinlock_lock(&obj->lock); status = spinlock_lock(&obj->lock);
if (obj->cnt == 0) if (obj->cnt == 0) {
{
sema_wait_item_init(&wait_item, th); sema_wait_item_init(&wait_item, th);
ref_counter_inc(&th->ref); ref_counter_inc(&th->ref);
slist_add_append(&obj->suspend_head, &wait_item.node); slist_add_append(&obj->suspend_head, &wait_item.node);
// thread_suspend_sw(th, FALSE);
remain_sleep = thread_sleep(ticks); remain_sleep = thread_sleep(ticks);
spinlock_set(&obj->lock, status); if (remain_sleep == 0 && ticks != 0) {
preemption(); // 超时退出的,直接从列表中删除
goto again; assert(slist_in_list(&wait_item.node));
} slist_del(&wait_item.node);
else 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); assert(obj->cnt > 0);
obj->cnt--; obj->cnt--;
// printk("down sema cnt:%d max:%d.\n", obj->cnt, obj->max_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); msg_tag_t tag = msg_tag_init4(0, 0, 0, -EINVAL);
task_t *task = thread_get_current_task(); 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; f->regs[0] = msg_tag_init4(0, 0, 0, -EPROTO).raw;
return; return;
} }
switch (sys_p.op) switch (sys_p.op) {
{ case SEMA_UP: {
case SEMA_UP:
{
sema_up(sema); sema_up(sema);
tag = msg_tag_init4(0, 0, 0, 0); tag = msg_tag_init4(0, 0, 0, 0);
} } break;
break; case SEMA_DOWN: {
case SEMA_DOWN:
{
umword_t ret; umword_t ret;
ret = sema_down(sema, f->regs[0]); 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 #else
kobj = mm_limit_alloc(lim, sizeof(sema_t)); kobj = mm_limit_alloc(lim, sizeof(sema_t));
#endif #endif
if (!kobj) if (!kobj) {
{
return NULL; return NULL;
} }
sema_init(kobj, cnt, max); 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_node = slist_first(&obj->suspend_head);
first_wait = container_of(first_wait_node, sema_wait_item_t, node); first_wait = container_of(first_wait_node, sema_wait_item_t, node);
slist_del(first_wait_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_ready_remote(first_wait->thread, FALSE);
} }
if (obj->cnt < obj->max_cnt) if (obj->cnt < obj->max_cnt) {
{
obj->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) void sema_init(sema_t *obj, int cnt, int max)
{ {
if (max <= 0) if (max <= 0) {
{
max = 1; max = 1;
} }
if (cnt < 0) if (cnt < 0) {
{
cnt = 0; cnt = 0;
} }
if (cnt > max) if (cnt > max) {
{
cnt = max; cnt = max;
} }
obj->cnt = cnt; 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) umword_t arg2, umword_t arg3)
{ {
sema_t *sema = sema_create(lim, arg0, arg1); sema_t *sema = sema_create(lim, arg0, arg1);
if (!sema) if (!sema) {
{
return NULL; return NULL;
} }
return &sema->kobj; return &sema->kobj;

View File

@@ -44,7 +44,6 @@ void thread_check_timeout(void)
pos, (slist_head_t *)&wait_list, pos, (slist_head_t *)&wait_list,
node) node)
{ {
assert(pos->th->status == THREAD_SUSPEND);
thread_wait_entry_t *next = slist_next_entry( thread_wait_entry_t *next = slist_next_entry(
pos, (slist_head_t *)wait_list, pos, (slist_head_t *)wait_list,
node); node);
@@ -53,6 +52,7 @@ void thread_check_timeout(void)
pos->times--; pos->times--;
if (pos->times == 0) if (pos->times == 0)
{ {
assert(pos->th->status == THREAD_SUSPEND);
thread_ready(pos->th, TRUE); thread_ready(pos->th, TRUE);
slist_del(&pos->node); slist_del(&pos->node);
} }

View File

@@ -1,13 +1,13 @@
#include "u_factory.h" #include "u_factory.h"
#include "u_sema.h"
#include "u_hd_man.h" #include "u_hd_man.h"
#include "u_sema.h"
#include "u_task.h" #include "u_task.h"
#include <u_sleep.h> #include <CuTest.h>
#include <assert.h> #include <assert.h>
#include <pthread.h> #include <pthread.h>
#include <stdio.h> #include <stdio.h>
#include <CuTest.h> #include <u_sleep.h>
#include <unistd.h> #include <unistd.h>
int u_sema_test(void) int u_sema_test(void)
@@ -34,14 +34,12 @@ static obj_handler_t sema_hd2;
static void *thread_th1(void *arg) static void *thread_th1(void *arg)
{ {
int j = 0; int j = 0;
while (1) while (1) {
{
printf("sema_up start\n"); printf("sema_up start\n");
u_sema_up(sema_hd2); u_sema_up(sema_hd2);
u_sleep_ms(100); u_sleep_ms(100);
printf("sema_up end\n"); printf("sema_up end\n");
if (j == TEST_CN * 2 + 2) if (j == TEST_CN * 2 + 2) {
{
break; break;
} }
j++; j++;
@@ -52,14 +50,12 @@ static void *thread_th1(void *arg)
static void *thread_th2(void *arg) static void *thread_th2(void *arg)
{ {
int j = 0; int j = 0;
while (1) while (1) {
{
printf("sema_down start\n"); printf("sema_down start\n");
u_sema_down(sema_hd2, 0, NULL); u_sema_down(sema_hd2, 0, NULL);
u_sleep_ms(50); u_sleep_ms(50);
printf("sema_down end\n"); printf("sema_down end\n");
if (j == TEST_CN) if (j == TEST_CN) {
{
break; break;
} }
j++; j++;
@@ -70,14 +66,12 @@ static void *thread_th2(void *arg)
static void *thread_th3(void *arg) static void *thread_th3(void *arg)
{ {
int j = 0; int j = 0;
while (1) while (1) {
{
printf("sema_down2 start\n"); printf("sema_down2 start\n");
u_sema_down(sema_hd2, 0, NULL); u_sema_down(sema_hd2, 0, NULL);
u_sleep_ms(50); u_sleep_ms(50);
printf("sema_down2 end\n"); printf("sema_down2 end\n");
if (j == TEST_CN) if (j == TEST_CN) {
{
break; break;
} }
j++; 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(&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(&pth2, NULL, thread_th2, NULL) == 0);
CuAssert(tc, "pthread_create fail.\n", pthread_create(&pth3, NULL, thread_th3, 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); 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); 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); 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; static CuSuite suite;
CuSuite *sema_test_suite(void) CuSuite *sema_test_suite(void)
{ {
CuSuiteInit(&suite); CuSuiteInit(&suite);
SUITE_ADD_TEST(&suite, u_sema_test2); SUITE_ADD_TEST(&suite, u_sema_test2);
SUITE_ADD_TEST(&suite, u_sema_test3);
return &suite; return &suite;
} }