修复服务端并发错误&内核内存分配错误问题

This commit is contained in:
zhangzheng
2024-01-05 23:08:42 +08:00
parent 1e8d407664
commit a2723c39c8
19 changed files with 197 additions and 101 deletions

View File

@@ -191,7 +191,7 @@ static void ipc_release_stage2(kobject_t *kobj)
ipc_t *ipc = container_of(kobj, ipc_t, kobj);
mm_limit_free(ipc->lim, kobj);
printk("ipc release 0x%x\n", kobj);
// printk("ipc release 0x%x\n", kobj);
}
static bool_t ipc_put(kobject_t *kobj)
{

View File

@@ -24,29 +24,48 @@ void mem_init(mem_t *_this)
static void mem_merge(mem_t *_this, struct mem_heap *mem)
{
struct mem_heap *prev_mem;
struct mem_heap *t_mem;
struct mem_heap *next_mem;
struct mem_heap *t_mem = mem;
_this->l_heap = mem;
prev_mem = mem->prev;
for (t_mem = mem; t_mem != _this->heap_end; t_mem = t_mem->next)
if (mem->used != 0)
{
if (prev_mem && prev_mem->used == 0)
{
// 如果当前没有使用,并且上一个的下一个位置等于当前,则上一个和当前合并
if (t_mem->used == 0 && ((ptr_t)prev_mem + prev_mem->size + MEM_HEAP_STRUCT_SIZE) == (ptr_t)t_mem)
{
// 上一个和当前合并
prev_mem->size += t_mem->size + MEM_HEAP_STRUCT_SIZE;
prev_mem->next = t_mem->next;
t_mem->next->prev = prev_mem;
return;
}
_this->l_heap = prev_mem;
}
prev_mem = t_mem->prev;
while (prev_mem && prev_mem->used == 0)
{
prev_mem->size += t_mem->size + MEM_HEAP_STRUCT_SIZE;
prev_mem->next = t_mem->next;
t_mem->next->prev = prev_mem;
t_mem = prev_mem;
prev_mem = t_mem->prev;
}
// if (t_mem < _this->l_heap || _this->l_heap->used == 1)
// {
// _this->l_heap = t_mem;
// }
while (t_mem && t_mem != _this->heap_end && t_mem->used == 0)
{
next_mem = t_mem->next;
if (next_mem == _this->heap_end)
{
break;
}
if (next_mem->used == 0)
{
t_mem->size += next_mem->size + MEM_HEAP_STRUCT_SIZE;
t_mem->next = next_mem->next;
next_mem->next->prev = t_mem;
}
else
{
prev_mem = t_mem;
break;
}
t_mem = t_mem->next;
}
}
/**
@@ -104,6 +123,7 @@ void *mem_split(mem_t *_this, void *mem, uint32_t size)
r_mem->next = t_mem->next;
r_mem->prev = t_mem;
r_mem->magic = MAGIC_NUM;
t_mem->next->prev = r_mem;
t_mem->next = r_mem;
t_mem->used = 1;
t_mem->size = size - MEM_HEAP_STRUCT_SIZE;
@@ -207,7 +227,7 @@ void *mem_alloc(mem_t *_this, uint32_t size)
for (mem = _this->l_heap; mem != _this->heap_end; mem = mem->next)
{
assert(mem->magic == MAGIC_NUM);
if (mem->used == 0 && mem->size > size)
if (mem->used == 0 && mem->size >= size)
{
if (mem->size - size > MEM_HEAP_STRUCT_SIZE)
{
@@ -218,10 +238,11 @@ void *mem_alloc(mem_t *_this, uint32_t size)
mem_temp->used = 0;
mem_temp->magic = MAGIC_NUM;
mem_temp->size = mem->size - size - MEM_HEAP_STRUCT_SIZE;
_this->l_heap = mem_temp;
// _this->l_heap = mem_temp;
mem->size = size;
mem->used = 1;
mem->next->prev = mem_temp;
mem->next = mem_temp;
spinlock_set(&_this->lock, status);
@@ -250,6 +271,8 @@ int mem_heap_add(mem_t *_this, void *mem, uint32_t size)
mem = (void *)(ALIGN((ptr_t)mem, 4));
size -= 4;
printk("total mem size:%d.\n", size);
// ((struct mem_heap *)mem)->name[0] = ' ';
// ((struct mem_heap *)mem)->name[1] = ' ';
// ((struct mem_heap *)mem)->name[2] = ' ';
@@ -350,7 +373,7 @@ struct mem_heap *mem_get_free(mem_t *_this, struct mem_heap *next,
void mem_trace(mem_t *_this)
{
struct mem_heap *mem;
size_t total = 0;
printk("================");
printk("start heap:0x%x.\n", _this->heap_start);
printk("l heap:0x%x.\n", _this->l_heap);
@@ -359,6 +382,8 @@ void mem_trace(mem_t *_this)
for (mem = _this->heap_start; mem != _this->heap_end; mem = mem->next)
{
printk("%d [0x%x-] %dB\n", mem->used, mem, mem->size);
total += mem->size + MEM_HEAP_STRUCT_SIZE;
}
printk("mem total size:%d.\n", total);
printk("================");
}

View File

@@ -16,7 +16,7 @@
void mm_space_init(mm_space_t *mm_space, int is_knl)
{
region_info_t *regi_info;
// region_info_t *regi_info;
for (int i = 0; i < CONFIG_REGION_NUM; i++)
{
@@ -24,8 +24,8 @@ void mm_space_init(mm_space_t *mm_space, int is_knl)
}
if (!is_knl)
{
regi_info = mm_space_alloc_pt_region(mm_space);
assert(regi_info);
// regi_info = mm_space_alloc_pt_region(mm_space);
// assert(regi_info);
// mm_pages_init(&mm_space->mm_pages, regi_info);
}
}

View File

@@ -132,8 +132,11 @@ static void thread_release_stage1(kobject_t *kobj)
assert(pos->th->status == THREAD_SUSPEND);
thread_wait_entry_t *next = slist_next_entry(pos, &wait_send_queue, node_timeout);
pos->th->ipc_status = THREAD_IPC_ABORT;
thread_ready(pos->th, TRUE);
if (pos->th != th)
{
pos->th->ipc_status = THREAD_IPC_ABORT;
thread_ready(pos->th, TRUE);
}
slist_del(&pos->node_timeout);
if (slist_in_list(&pos->node))
@@ -149,9 +152,11 @@ static void thread_release_stage1(kobject_t *kobj)
assert(pos2->th->status == THREAD_SUSPEND);
thread_wait_entry_t *next = slist_next_entry(pos2, &wait_recv_queue, node);
pos2->th->ipc_status = THREAD_IPC_ABORT;
thread_ready(pos2->th, TRUE);
if (pos2->th != th)
{
pos2->th->ipc_status = THREAD_IPC_ABORT;
thread_ready(pos2->th, TRUE);
}
slist_del(&pos2->node);
pos2 = next;
}
@@ -162,7 +167,7 @@ static void thread_release_stage2(kobject_t *kobj)
{
thread_t *th = container_of(kobj, thread_t, kobj);
thread_t *cur_th = thread_get_current();
printk("release thread 0x%x\n", kobj);
// printk("release thread 0x%x\n", kobj);
mm_limit_free_align(th->lim, kobj, THREAD_BLOCK_SIZE);
if (cur_th == th)
@@ -170,6 +175,7 @@ static void thread_release_stage2(kobject_t *kobj)
scheduler_reset();
thread_sched();
}
// mm_trace();
}
/**
@@ -297,7 +303,6 @@ void thread_todead(thread_t *th, bool_t is_sche)
thread_sched();
}
}
/**
* @brief 创建线程
*
@@ -314,7 +319,7 @@ thread_t *thread_create(ram_limit_t *ram)
}
memset(th, 0, THREAD_BLOCK_SIZE);
thread_init(th, ram);
printk("create thread 0x%x\n", th);
// printk("create thread 0x%x\n", th);
return th;
}
@@ -368,6 +373,22 @@ void thread_timeout_check(ssize_t tick)
pos2 = next;
}
}
static void thread_timeout_del_recv(thread_t *th)
{
thread_wait_entry_t *pos2;
slist_foreach_not_next(pos2, &wait_recv_queue, node)
{
thread_wait_entry_t *next = slist_next_entry(pos2, &wait_recv_queue, node);
if (pos2->th == th)
{
slist_del(&pos2->node);
break;
}
pos2 = next;
}
}
/**
* @brief ipc传输时的数据拷贝
*
@@ -440,6 +461,16 @@ static int thread_ipc_recv(msg_tag_t *ret_msg, ipc_timeout_t timeout,
lock_status = cpulock_lock();
cur_th->ipc_status = THREAD_RECV; //!< 因为接收挂起
if (ipc_kobj)
{
/*IPC对象的引用计数+1*/
ref_counter_inc(&ipc_kobj->ref);
cur_th->ipc_kobj = &ipc_kobj->kobj;
}
else
{
cur_th->ipc_kobj = NULL;
}
if (!slist_is_empty(&cur_th->wait_send_head))
{
//!< 有发送者
@@ -462,18 +493,6 @@ static int thread_ipc_recv(msg_tag_t *ret_msg, ipc_timeout_t timeout,
slist_add_append(&wait_recv_queue, &wait.node); //!< 放到等待队列中
}
}
if (ipc_kobj)
{
/*IPC对象的引用计数+1*/
ref_counter_inc(&ipc_kobj->ref);
cur_th->ipc_kobj = &ipc_kobj->kobj;
}
else
{
cur_th->ipc_kobj = NULL;
}
thread_suspend(cur_th); //!< 挂起
preemption(); //!< 进行调度
if (cur_th->ipc_status == THREAD_IPC_ABORT)
@@ -548,7 +567,10 @@ static int thread_ipc_reply(msg_tag_t in_tag)
int thread_ipc_call(thread_t *to_th, msg_tag_t in_tag, msg_tag_t *ret_tag,
ipc_timeout_t timout, umword_t *ret_user_id, bool_t is_call)
{
assert(is_call && ret_tag);
if (is_call)
{
assert(is_call && ret_tag);
}
int ret = -EINVAL;
thread_t *cur_th = thread_get_current();
thread_t *recv_kobj = to_th;
@@ -587,6 +609,7 @@ again_check:
}
else if (recv_kobj->status == THREAD_SUSPEND && recv_kobj->ipc_status == THREAD_RECV)
{
thread_timeout_del_recv(recv_kobj);
//!< 开始发送数据
ret = ipc_data_copy(recv_kobj, cur_th, in_tag); //!< 拷贝数据
if (ret < 0)
@@ -594,23 +617,24 @@ again_check:
//!< 拷贝失败
goto end;
}
if (recv_kobj->ipc_kobj)
{
// 绑定回复的ipc到当前的线程
assert(ipc_bind(((ipc_t *)(recv_kobj->ipc_kobj)), -1, 0, cur_th) >= 0);
ref_counter_dec_and_release(&((ipc_t *)(recv_kobj->ipc_kobj))->ref,
recv_kobj->ipc_kobj);
recv_kobj->ipc_kobj = NULL;
recv_kobj->last_send_th = NULL;
}
else
{
recv_kobj->last_send_th = cur_th; //!< 设置接收者的上一次发送者是谁
ref_counter_inc(&cur_th->ref); //!< 作为发送者增加一次引用
}
thread_ready(recv_kobj, TRUE); //!< 直接唤醒接受者
if (is_call)
{
if (recv_kobj->ipc_kobj)
{
// 绑定回复的ipc到当前的线程
assert(ipc_bind(((ipc_t *)(recv_kobj->ipc_kobj)), -1, 0, cur_th) >= 0);
ref_counter_dec_and_release(&((ipc_t *)(recv_kobj->ipc_kobj))->ref,
recv_kobj->ipc_kobj);
recv_kobj->ipc_kobj = NULL;
recv_kobj->last_send_th = NULL;
}
else
{
recv_kobj->last_send_th = cur_th; //!< 设置接收者的上一次发送者是谁
ref_counter_inc(&cur_th->ref); //!< 作为发送者增加一次引用
}
ret = thread_ipc_recv(ret_tag, timout, ret_user_id, NULL); //!< 当前线程进行接收
if (ret < 0)
{
@@ -672,7 +696,7 @@ msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id)
{
msg_tag_t ret_msg;
ipc_timeout_t ipc_tm_out = ipc_timeout_create(f->r[3]);
kobject_t *ipc_kobj = obj_space_lookup_kobj_cmp_type(&cur_task->obj_space, f->r[4], IPC_PROT);
kobject_t *ipc_kobj = obj_space_lookup_kobj_cmp_type(&cur_task->obj_space, f->r[4], IPC_TYPE);
int ret = thread_ipc_recv(&ret_msg, ipc_tm_out, &f->r[1], (ipc_t *)ipc_kobj);
if (ret < 0)
@@ -685,7 +709,7 @@ msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id)
{
msg_tag_t in_tag = msg_tag_init(f->r[0]);
msg_tag_t recv_tag;
th_hd = f->r[2];
// th_hd = f->r[2];
ipc_timeout_t ipc_tm_out = ipc_timeout_create(f->r[3]);
to_th->user_id = user_id;
@@ -787,7 +811,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[1]);
// printk("thread bind to %d\n", f->r[1]);
}
break;
case YIELD:

View File

@@ -56,5 +56,5 @@ void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram, um
cur_th->sp.user_sp = cur_pf;
cur_th->sp.sp_type = 0xfffffffd;
printk("exc_regs:%x %x %x\n", cur_pf->pf_s.pc, cur_th->sp.user_sp, ram);
// printk("exc_regs:%x %x %x\n", cur_pf->pf_s.pc, cur_th->sp.user_sp, ram);
}