修复thread被释放后内存被重复访问的问题

This commit is contained in:
zhangzheng
2023-09-30 13:19:58 +08:00
parent 4ba8d8fb9a
commit 851ea69883
22 changed files with 210 additions and 47 deletions

View File

@@ -67,7 +67,10 @@ void NMI_Handler(void)
void HardFault_Handler(void)
{
printk("%s\n", __FUNCTION__);
umword_t status;
status = cpulock_lock();
task_kill(thread_get_current_task());
cpulock_set(status);
/* Go to infinite loop when Hard Fault exception occurs */
// while (1)
// {
@@ -83,6 +86,7 @@ void MemManage_Handler(void)
{
addr_t fault_addr = (addr_t)(SCB->MMFAR);
task_t *cur_task = thread_get_current_task();
umword_t status;
// printk("%s\n", __FUNCTION__);
if (SCB->CFSR & 0x1)
@@ -149,7 +153,9 @@ void MemManage_Handler(void)
// {
// }
end:
status = cpulock_lock();
task_kill(thread_get_current_task());
cpulock_set(status);
}
/**
@@ -159,13 +165,16 @@ end:
*/
void BusFault_Handler(void)
{
umword_t status;
printk("%s\n", __FUNCTION__);
/* Go to infinite loop when Bus Fault exception occurs */
// while (1)
// {
// }
status = cpulock_lock();
task_kill(thread_get_current_task());
cpulock_set(status);
}
/**
@@ -204,7 +213,10 @@ void UsageFault_Handler(void)
// while (1)
// {
// }
umword_t status;
status = cpulock_lock();
task_kill(thread_get_current_task());
cpulock_set(status);
}
// /**

View File

@@ -3,6 +3,7 @@
.thumb
.global mpu_switch_to
.global sched_reset
.global PendSV_Handler
.type PendSV_Handler, %function
@@ -21,9 +22,11 @@ PendSV_Handler:
MRSNE r3, PSP
MOVNE r2, #1
push {r4}
ldr r4, =sched_reset
ldr r4, [r4]
//! psp
//CMP r0,#0
//CBZ r0, thread_sche
CBZ r4, thread_sche
SUB R3, R3, #0x20 //R3 -= 32
STM R3, {R4-R11}
@@ -36,6 +39,7 @@ PendSV_Handler:
MSRNE PSP, r3
MOVNE r0,r3
thread_sche:
pop {r4}
// r0:psp r1:msp r2:(0msp 1 psp)
LDR.w r3,=schde_to
BLX r3

View File

@@ -28,6 +28,19 @@ static inline void kobj_map_init(kobj_map_t *map)
slist_init(&map->node);
}
enum knl_obj_type
{
BASE_KOBJ_TYPE,
TASK_TYPE,
THREAD_TYPE,
IRQ_SENDER_TYPE,
IPC_TYPE,
LOG_TYPE,
MM_TYPE,
FACTORY_TYPE,
SYS_TYPE,
};
typedef struct kobject
{
kobj_map_t mappable;
@@ -37,6 +50,7 @@ typedef struct kobject
obj_release_stage_1_func stage_1_func;
obj_release_stage_2_func stage_2_func;
obj_release_put put_func;
enum knl_obj_type kobj_type;
} kobject_t;
typedef struct kobj_del_list
@@ -94,7 +108,7 @@ static inline void kobject_release_stage2(kobject_t *kobj)
{
}
static inline void kobject_init(kobject_t *kobj)
static inline void kobject_init(kobject_t *kobj, enum knl_obj_type type)
{
kobj_map_init(&kobj->mappable);
slist_init(&kobj->del_node);
@@ -103,4 +117,5 @@ static inline void kobject_init(kobject_t *kobj)
kobj->put_func = kobject_put;
kobj->stage_1_func = kobject_release_stage1;
kobj->stage_2_func = kobject_release_stage2;
kobj->kobj_type = type;
}

View File

@@ -36,3 +36,4 @@ void scheduler_init(void);
sched_t *scheduler_next(void);
void scheduler_add(sched_t *node);
void scheduler_del(sched_t *node);
void scheduler_reset(void);

View File

@@ -1,4 +1,5 @@
#pragma once
void thread_exit(void);
void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram, umword_t stack);
void thread_knl_pf_set(thread_t *cur_th, void *pc);
void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram, umword_t stack);

View File

@@ -1,12 +1,12 @@
/**
* @file factory.c
* @author zhangzheng (1358745329@qq.com)
* @brief
* @brief
* @version 0.1
* @date 2023-09-29
*
*
* @copyright Copyright (c) 2023
*
*
*/
#include "factory.h"
#include "kobject.h"
@@ -62,19 +62,35 @@ static kobject_t *factory_manu_kobj(kobject_t *kobj, ram_limit_t *lim, entry_fra
static msg_tag_t factory_create_map(kobject_t *kobj, task_t *tk, entry_frame_t *f)
{
vpage_t page = vpage_create_raw(f->r[2]);
mword_t status = spinlock_lock(&tk->kobj.lock);
if (status < 0)
{
return msg_tag_init4(0, 0, 0, -EINVAL);
}
kobject_t *new_kobj = factory_manu_kobj(kobj, tk->lim, f);
if (!new_kobj)
{
spinlock_set(&tk->kobj.lock, status);
return msg_tag_init4(0, 0, 0, -ENOMEM);
}
page.attrs |= KOBJ_ALL_RIGHTS;
if (obj_map_root(new_kobj, &tk->obj_space, tk->lim, page) == FALSE)
{
mm_limit_free(tk->lim, new_kobj);
if (new_kobj->kobj_type == THREAD_TYPE)
{
mm_limit_free_align(tk->lim, new_kobj, THREAD_BLOCK_SIZE);
}
else
{
mm_limit_free(tk->lim, new_kobj);
}
spinlock_set(&tk->kobj.lock, status);
return msg_tag_init4(0, 0, 0, -ENOMEM);
}
spinlock_set(&tk->kobj.lock, status);
return msg_tag_init4(0, 0, 0, 0);
}
/**
@@ -109,7 +125,7 @@ factory_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag, entry_f
}
static void factory_init(factory_t *fac, umword_t max)
{
kobject_init(&fac->kobj);
kobject_init(&fac->kobj, FACTORY_TYPE);
ram_limit_init(&fac->limit, max);
fac->kobj.invoke_func = factory_syscall;
}

View File

@@ -483,7 +483,7 @@ static void ipc_release_stage2(kobject_t *kobj)
}
static void ipc_init(ipc_t *ipc, ram_limit_t *lim)
{
kobject_init(&ipc->kobj);
kobject_init(&ipc->kobj, IPC_TYPE);
slist_init(&ipc->wait_send);
slist_init(&ipc->recv_send);
spinlock_init(&ipc->lock);

View File

@@ -184,7 +184,7 @@ static void irq_sender_stage2(kobject_t *kobj)
*/
void irq_sender_init(irq_sender_t *irq)
{
kobject_init(&irq->kobj);
kobject_init(&irq->kobj, IRQ_SENDER_TYPE);
ref_counter_init(&irq->ref);
ref_counter_inc(&irq->ref);
irq->kobj.invoke_func = irq_sender_syscall;

View File

@@ -42,6 +42,7 @@ static void log_reg(void)
{
// kobject_init(&log.kobj);
irq_sender_init(&log.kobj);
log.kobj.kobj.kobj_type = IRQ_SENDER_TYPE;
log.kobj.kobj.invoke_func = log_syscall;
log.kobj.kobj.stage_1_func = kobject_release_stage1;
log.kobj.kobj.stage_2_func = kobject_release_stage2;

View File

@@ -26,7 +26,7 @@ static void mm_man_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_t
static void mm_man_reg(void)
{
kobject_init(&mm_man.kobj);
kobject_init(&mm_man.kobj, MM_TYPE);
mm_man.kobj.invoke_func = mm_man_syscall;
global_reg_kobj(&mm_man.kobj, MM_PROT);
}

View File

@@ -1,12 +1,12 @@
/**
* @file scheduler.c
* @author zhangzheng (1358745329@qq.com)
* @brief
* @brief
* @version 0.1
* @date 2023-09-29
*
*
* @copyright Copyright (c) 2023
*
*
*/
#include "scheduler.h"
#include "util.h"
@@ -14,6 +14,12 @@
#include "thread.h"
#include "init.h"
static scheduler_t scheduler;
umword_t sched_reset = 0;
void scheduler_reset(void)
{
sched_reset = 0;
}
scheduler_t *scheduler_get_current(void)
{
@@ -37,6 +43,7 @@ void scheduler_add(sched_t *node)
if (node->prio != sched->max_prio)
{
sched->max_prio = node->prio;
sched->cur_sche = NULL;
}
slist_add(&sched->prio_list[node->prio], &node->node);
@@ -52,12 +59,13 @@ void scheduler_del(sched_t *node)
/*TODO:更新最大优先级,这里可以用位图优化*/
for (mword_t i = node->prio - 1; i >= 0; i--)
{
if (slist_is_empty(&sched->prio_list[i]))
if (!slist_is_empty(&sched->prio_list[i]))
{
sched->max_prio = i;
break;
}
}
sched->cur_sche = NULL;
}
}
sched_t *scheduler_next(void)
@@ -87,12 +95,16 @@ sp_info_t *schde_to(void *usp, void *ksp, umword_t sp_type)
{
scheduler_t *sche = scheduler_get_current();
thread_t *cur_th = thread_get_current();
sched_t *next = sche->cur_sche;
thread_t *next_th = container_of(next, thread_t, sche);
cur_th->sp.knl_sp = ksp;
cur_th->sp.user_sp = usp;
cur_th->sp.sp_type = sp_type;
if (sched_reset)
{
thread_t *cur_th = thread_get_current();
cur_th->sp.knl_sp = ksp;
cur_th->sp.user_sp = usp;
cur_th->sp.sp_type = sp_type;
}
sched_reset = 1;
return &next_th->sp;
}

View File

@@ -34,7 +34,7 @@ static void sys_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag,
static void sys_reg(void)
{
kobject_init(&sys_obj.kobj);
kobject_init(&sys_obj.kobj, SYS_TYPE);
sys_obj.kobj.invoke_func = sys_syscall;
global_reg_kobj(&sys_obj.kobj, SYS_PROT);
}

View File

@@ -131,7 +131,7 @@ void task_init(task_t *task, ram_limit_t *ram, int is_knl)
assert(task);
assert(ram);
kobject_init(&task->kobj);
kobject_init(&task->kobj, TASK_TYPE);
obj_space_init(&task->obj_space, ram);
mm_space_init(&task->mm_space, is_knl);
ref_counter_init(&task->ref_cn);
@@ -141,7 +141,6 @@ void task_init(task_t *task, ram_limit_t *ram, int is_knl)
task->kobj.put_func = task_put;
task->kobj.stage_1_func = task_release_stage1;
task->kobj.stage_2_func = task_release_stage2;
mm_space_add(&task->mm_space, KNL_TEXT, 64 * 1024 * 1024, REGION_RO); // TODO:
}
@@ -172,7 +171,8 @@ static void task_release_stage2(kobject_t *kobj)
{
thread_sched();
}
// mm_trace();
scheduler_reset();
mm_trace();
printk("release tk %x\n", tk);
}
void task_kill(task_t *tk)

View File

@@ -34,7 +34,7 @@ static void thread_release_stage2(kobject_t *kobj);
*/
void thread_init(thread_t *th, ram_limit_t *lim)
{
kobject_init(&th->kobj);
kobject_init(&th->kobj, THREAD_TYPE);
sched_init(&th->sche);
// slist_init(&th->wait);
ref_counter_init(&th->ref);
@@ -91,10 +91,10 @@ static void thread_release_stage2(kobject_t *kobj)
printk("release thread 0x%x\n", kobj);
mm_limit_free_align(th->lim, kobj, THREAD_BLOCK_SIZE);
if (cur_th == th)
{
thread_sched();
}
// if (cur_th == th)
// {
thread_sched();
// }
}
/**
@@ -310,7 +310,7 @@ static void thread_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_t
}
thread_bind(tag_th, task_kobj);
tag = msg_tag_init4(0, 0, 0, 0);
printk("thread bind to %d\n", f->r[7], f->r[1]);
printk("thread bind to %d\n", f->r[1]);
}
break;
}

View File

@@ -21,9 +21,22 @@ syscall_entry_func syscall_handler_get(void)
{
return syscall_entry;
}
void thread_knl_pf_set(thread_t *cur_th, void *pc)
{
pf_t *cur_pf = ((pf_t *)((char *)cur_th + THREAD_BLOCK_SIZE)) - 1;
cur_pf->pf_s.xpsr = 0x01000000L;
cur_pf->pf_s.lr = (umword_t)NULL; //!< 线程退出时调用的函数
cur_pf->pf_s.pc = (umword_t)pc | 0x1;
// cur_pf->rg1[5] = (umword_t)0;
cur_th->sp.knl_sp = (char *)cur_pf;
cur_th->sp.user_sp = 0;
cur_th->sp.sp_type = 0;
}
void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram, umword_t stack)
{
assert((((umword_t)user_sp) & 0x7UL) == 0);
umword_t usp = ((umword_t)(user_sp - 8) & ~0x7UL);
if (stack)

View File

@@ -25,6 +25,14 @@
static thread_t *knl_thread;
static task_t knl_task;
static void knl_main(void)
{
printk("knl main run..\n");
while (1)
{
}
}
/**
* 初始化内核线程
* 初始化内核任务
@@ -36,6 +44,7 @@ static void knl_init_1(void)
thread_init(cur_th, &root_factory_get()->limit);
task_init(&knl_task, &root_factory_get()->limit, TRUE);
thread_knl_pf_set(cur_th, knl_main);
thread_bind(cur_th, &knl_task.kobj);
thread_ready(cur_th, FALSE);
}
@@ -63,7 +72,8 @@ static void knl_init_2(void)
thread_set_msg_bug(init_thread, (char *)(init_task->mm_space.mm_block) + app->i.ram_size);
thread_bind(init_thread, &init_task->kobj);
thread_user_pf_set(init_thread, (void *)(KNL_TEXT + INIT_OFFSET), sp_addr_top, init_task->mm_space.mm_block, 0);
thread_user_pf_set(init_thread, (void *)(KNL_TEXT + INIT_OFFSET), (void *)((umword_t)sp_addr_top - 8),
init_task->mm_space.mm_block, 0);
assert(obj_map_root(&init_thread->kobj, &init_task->obj_space, &root_factory_get()->limit, vpage_create3(KOBJ_ALL_RIGHTS, 0, THREAD_PROT)));
assert(obj_map_root(&init_task->kobj, &init_task->obj_space, &root_factory_get()->limit, vpage_create3(KOBJ_ALL_RIGHTS, 0, TASK_PROT)));
for (int i = FACTORY_PORT_START; i < FACTORY_PORT_END; i++)
@@ -106,7 +116,7 @@ void start_kernel(void)
printk("mkrtos running..\n");
print_mkrtos_info();
sti();
sys_startup();
sys_startup(); //!< 开始调度
thread_sched();
cli();

View File

@@ -68,8 +68,8 @@ msg_tag_t thread_run(obj_handler_t obj, uint8_t prio)
register volatile umword_t r0 asm("r0");
syscall(syscall_prot_create(RUN_THREAD, THREAD_PROT, obj),
prio,
0,
prio,
0,
0,
0,

View File

@@ -55,6 +55,10 @@ obj_handler_t handler_alloc(void)
void handler_free(obj_handler_t hd_inx)
{
hd_inx -= HANDLER_START_INX;
if (hd_inx < 0)
{
return;
}
umword_t word_offset = hd_inx / WORD_BITS;
umword_t bits_offset = hd_inx % WORD_BITS;
@@ -73,6 +77,6 @@ void handler_free(obj_handler_t hd_inx)
*/
void handler_free_umap(obj_handler_t hd_inx)
{
task_unmap(TASK_THIS, vpage_create_raw3(0, 0, hd_inx));
handler_free(hd_inx);
task_unmap(TASK_THIS, vpage_create_raw3(0, 0, hd_inx));
}

View File

@@ -33,28 +33,30 @@ int main(int argc, char *args[])
mm_test();
app_test();
mpu_test();
#endif
ipc_test();
uenv_t env = *u_get_global_env();
obj_handler_t ipc_hd;
int ret = rpc_creaite_bind_ipc(THREAD_MAIN, NULL, &ipc_hd);
assert(ret >= 0);
env.ns_hd = ipc_hd;
#endif
thread_press_test();
// uenv_t env = *u_get_global_env();
// obj_handler_t ipc_hd;
// int ret = rpc_creaite_bind_ipc(THREAD_MAIN, NULL, &ipc_hd);
// assert(ret >= 0);
// env.ns_hd = ipc_hd;
// ret = app_load("fatfs", &env);
// // ret = app_load("fatfs", &env);
// // if (ret < 0)
// // {
// // printf("app load fail, 0x%x\n", ret);
// // }
// ret = app_load("app", &env);
// if (ret < 0)
// {
// printf("app load fail, 0x%x\n", ret);
// }
ret = app_load("app", &env);
if (ret < 0)
{
printf("app load fail, 0x%x\n", ret);
}
// namespace_init(ipc_hd);
// namespace_loop();
while(1);
task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, TASK_THIS)); // 删除当前task以及申请得所有对象
printf("exit init.\n");
return 0;

View File

@@ -13,3 +13,5 @@ void thread_exit_test(void);
void map_test(void);
void ipc_timeout_test(void);
void irq_test(void);
void thread_press_test(void);
void sleep_tick(int tick);

View File

@@ -0,0 +1,53 @@
#include "u_log.h"
#include "u_prot.h"
#include "u_mm.h"
#include "u_factory.h"
#include "u_thread.h"
#include "u_task.h"
#include "u_ipc.h"
#include "u_hd_man.h"
#include <assert.h>
#include <stdio.h>
#include "test.h"
static umword_t th1_hd = 0;
static umword_t ipc_hd = 0;
#define STACK_SIZE 1024
static __attribute__((aligned(8))) uint8_t stack0[STACK_SIZE];
static void thread_test_func(void)
{
// char *buf;
// umword_t len;
// thread_msg_buf_get(th1_hd, (umword_t *)(&buf), NULL);
// printf("thread_test_func.\n");
ulog_write_str(LOG_PROT, ".");
// task_unmap(TASK_PROT, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th1_hd));
handler_free_umap(ipc_hd);
handler_free_umap(th1_hd);
printf("Error\n");
}
void thread_press_test(void)
{
int i = 100;
while (i--)
{
th1_hd = handler_alloc();
assert(th1_hd != HANDLER_INVALID);
ipc_hd = handler_alloc();
assert(ipc_hd != HANDLER_INVALID);
msg_tag_t tag = factory_create_ipc(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, ipc_hd));
assert(msg_tag_get_prot(tag) >= 0);
tag = factory_create_thread(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, th1_hd));
assert(msg_tag_get_prot(tag) >= 0);
tag = thread_exec_regs(th1_hd, (umword_t)thread_test_func, (umword_t)stack0 + STACK_SIZE, RAM_BASE(), 0);
assert(msg_tag_get_prot(tag) >= 0);
tag = thread_bind_task(th1_hd, TASK_THIS);
assert(msg_tag_get_prot(tag) >= 0);
tag = thread_run(th1_hd, 2);
ulog_write_str(LOG_PROT, "\n");
// sleep_tick(20);
}
}

View File

@@ -0,0 +1,17 @@
#include "u_log.h"
#include "u_prot.h"
#include "u_mm.h"
#include "u_factory.h"
#include "u_thread.h"
#include "u_task.h"
#include "u_ipc.h"
#include "u_hd_man.h"
void sleep_tick(int tick)
{
obj_handler_t hd = handler_alloc();
factory_create_ipc(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, hd));
ipc_call(hd, msg_tag_init4(0, 0, 0, 0), ipc_timeout_create2(tick, 0));
handler_free_umap(hd);
}