修复ipc超时错误的问题
This commit is contained in:
@@ -128,11 +128,10 @@ typedef struct thread
|
||||
|
||||
slist_head_t futex_node; //!< futex使用
|
||||
|
||||
msg_buf_t msg; //!< 每个线程独有的消息缓存区
|
||||
slist_head_t wait_node; //!< 节点
|
||||
mword_t ipc_times; //!< ipc时间
|
||||
thread_t *last_send_th; //!< 当前线程上次接收到谁的数据
|
||||
umword_t user_id; //!< 接收到的user_id
|
||||
msg_buf_t msg; //!< 每个线程独有的消息缓存区
|
||||
slist_head_t wait_send_head; //!< 等待头,那些节点等待给当前线程发送数据
|
||||
thread_t *last_send_th; //!< 当前线程上次接收到谁的数据
|
||||
umword_t user_id; //!< 接收到的user_id
|
||||
|
||||
enum thread_state status; //!< 线程状态
|
||||
enum thread_ipc_state ipc_status; //!< ipc状态
|
||||
|
||||
@@ -47,6 +47,22 @@ static bool_t thread_put(kobject_t *kobj);
|
||||
static void thread_release_stage1(kobject_t *kobj);
|
||||
static void thread_release_stage2(kobject_t *kobj);
|
||||
|
||||
typedef struct thread_wait_entry
|
||||
{
|
||||
slist_head_t node;
|
||||
slist_head_t node_timeout;
|
||||
thread_t *th;
|
||||
mword_t times;
|
||||
} thread_wait_entry_t;
|
||||
|
||||
static inline void thread_wait_entry_init(thread_wait_entry_t *entry, thread_t *th, mword_t times)
|
||||
{
|
||||
slist_init(&entry->node);
|
||||
slist_init(&entry->node_timeout);
|
||||
entry->th = th;
|
||||
entry->times = times;
|
||||
}
|
||||
|
||||
static slist_head_t wait_send_queue;
|
||||
static slist_head_t wait_recv_queue;
|
||||
|
||||
@@ -66,8 +82,8 @@ void thread_init(thread_t *th, ram_limit_t *lim)
|
||||
{
|
||||
kobject_init(&th->kobj, THREAD_TYPE);
|
||||
sched_init(&th->sche);
|
||||
slist_init(&th->wait_node);
|
||||
slist_init(&th->futex_node);
|
||||
slist_init(&th->wait_send_head);
|
||||
ref_counter_init(&th->ref);
|
||||
ref_counter_inc(&th->ref);
|
||||
th->lim = lim;
|
||||
@@ -104,34 +120,37 @@ static void thread_release_stage1(kobject_t *kobj)
|
||||
thread_suspend(th);
|
||||
}
|
||||
}
|
||||
thread_t *pos;
|
||||
thread_wait_entry_t *pos;
|
||||
|
||||
slist_foreach_not_next(pos, &wait_send_queue, wait_node)
|
||||
slist_foreach_not_next(pos, &wait_send_queue, node_timeout)
|
||||
{
|
||||
assert(pos->status == THREAD_SUSPEND);
|
||||
thread_t *next = slist_next_entry(pos, &th->wait_head, wait_node);
|
||||
assert(pos->th->status == THREAD_SUSPEND);
|
||||
thread_wait_entry_t *next = slist_next_entry(pos, &wait_send_queue, node_timeout);
|
||||
|
||||
pos->ipc_status = THREAD_IPC_ABORT;
|
||||
thread_ready(pos, TRUE);
|
||||
pos->th->ipc_status = THREAD_IPC_ABORT;
|
||||
thread_ready(pos->th, TRUE);
|
||||
|
||||
slist_del(&pos->wait_node);
|
||||
slist_del(&pos->node_timeout);
|
||||
if (slist_in_list(&pos->node))
|
||||
{
|
||||
slist_del(&pos->node);
|
||||
}
|
||||
pos = next;
|
||||
}
|
||||
slist_foreach_not_next(pos, &wait_recv_queue, wait_node)
|
||||
{
|
||||
assert(pos->status == THREAD_SUSPEND);
|
||||
thread_t *next = slist_next_entry(pos, &th->wait_head, wait_node);
|
||||
thread_wait_entry_t *pos2;
|
||||
|
||||
pos->ipc_status = THREAD_IPC_ABORT;
|
||||
thread_ready(pos, TRUE);
|
||||
|
||||
slist_del(&pos->wait_node);
|
||||
pos = next;
|
||||
}
|
||||
if (slist_in_list(&th->wait_node))
|
||||
slist_foreach_not_next(pos2, &wait_recv_queue, node)
|
||||
{
|
||||
slist_del(&th->wait_node); //!< 从链表中删除
|
||||
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);
|
||||
|
||||
slist_del(&pos2->node);
|
||||
pos2 = next;
|
||||
}
|
||||
|
||||
thread_unbind(th);
|
||||
}
|
||||
static void thread_release_stage2(kobject_t *kobj)
|
||||
@@ -301,45 +320,47 @@ thread_t *thread_create(ram_limit_t *ram)
|
||||
*/
|
||||
void thread_timeout_check(ssize_t tick)
|
||||
{
|
||||
thread_t *pos;
|
||||
// thread_t *th = thread_get_current();
|
||||
thread_wait_entry_t *pos;
|
||||
|
||||
slist_foreach_not_next(pos, &wait_send_queue, wait_node)
|
||||
slist_foreach_not_next(pos, &wait_send_queue, node_timeout)
|
||||
{
|
||||
assert(pos->status == THREAD_SUSPEND);
|
||||
thread_t *next = slist_next_entry(pos, &wait_send_queue, wait_node);
|
||||
|
||||
if (pos->ipc_times > 0)
|
||||
assert(pos->th->status == THREAD_SUSPEND);
|
||||
thread_wait_entry_t *next = slist_next_entry(pos, &wait_send_queue, node_timeout);
|
||||
if (pos->times > 0)
|
||||
{
|
||||
pos->ipc_times -= tick;
|
||||
if (pos->ipc_times <= 0)
|
||||
pos->times -= tick;
|
||||
if (pos->times <= 0)
|
||||
{
|
||||
pos->ipc_status = THREAD_TIMEOUT;
|
||||
thread_ready(pos, TRUE);
|
||||
pos->th->ipc_status = THREAD_TIMEOUT;
|
||||
thread_ready(pos->th, TRUE);
|
||||
|
||||
slist_del(&pos->wait_node);
|
||||
slist_del(&pos->node_timeout);
|
||||
if (slist_in_list(&pos->node))
|
||||
{
|
||||
slist_del(&pos->node);
|
||||
}
|
||||
}
|
||||
}
|
||||
pos = next;
|
||||
}
|
||||
|
||||
slist_foreach_not_next(pos, &wait_recv_queue, wait_node)
|
||||
thread_wait_entry_t *pos2;
|
||||
slist_foreach_not_next(pos2, &wait_recv_queue, node)
|
||||
{
|
||||
assert(pos->status == THREAD_SUSPEND);
|
||||
thread_t *next = slist_next_entry(pos, &wait_recv_queue, wait_node);
|
||||
assert(pos2->th->status == THREAD_SUSPEND);
|
||||
thread_wait_entry_t *next = slist_next_entry(pos2, &wait_recv_queue, node);
|
||||
|
||||
if (pos->ipc_times > 0)
|
||||
if (pos2->times > 0)
|
||||
{
|
||||
pos->ipc_times -= tick;
|
||||
if (pos->ipc_times <= 0)
|
||||
pos2->times -= tick;
|
||||
if (pos2->times <= 0)
|
||||
{
|
||||
pos->ipc_status = THREAD_TIMEOUT;
|
||||
thread_ready(pos, TRUE);
|
||||
pos2->th->ipc_status = THREAD_TIMEOUT;
|
||||
thread_ready(pos2->th, TRUE);
|
||||
|
||||
slist_del(&pos->wait_node);
|
||||
slist_del(&pos2->node);
|
||||
}
|
||||
}
|
||||
pos = next;
|
||||
pos2 = next;
|
||||
}
|
||||
}
|
||||
/**
|
||||
@@ -411,22 +432,28 @@ static int thread_ipc_recv(msg_tag_t *ret_msg, ipc_timeout_t timeout, umword_t *
|
||||
|
||||
lock_status = cpulock_lock();
|
||||
cur_th->ipc_status = THREAD_RECV; //!< 因为接收挂起
|
||||
if (!slist_is_empty(&wait_send_queue))
|
||||
if (!slist_is_empty(&cur_th->wait_send_head))
|
||||
{
|
||||
//!< 有发送者
|
||||
slist_head_t *mslist = slist_first(&wait_send_queue);
|
||||
thread_t *send_th = container_of(mslist, thread_t, wait_node);
|
||||
slist_head_t *mslist = slist_first(&cur_th->wait_send_head);
|
||||
thread_wait_entry_t *wait = container_of(mslist, thread_wait_entry_t, node);
|
||||
|
||||
slist_del(mslist); //!< 删除唤醒的线程
|
||||
thread_ready(send_th, TRUE);
|
||||
if (slist_in_list(&wait->node_timeout))
|
||||
{
|
||||
slist_del(&wait->node_timeout);
|
||||
}
|
||||
thread_ready(wait->th, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
//!< 加入等待队列
|
||||
if (timeout.recv_timeout)
|
||||
{
|
||||
cur_th->ipc_times = timeout.recv_timeout;
|
||||
slist_add_append(&wait_recv_queue, &cur_th->wait_node); //!< 放到等待队列中
|
||||
thread_wait_entry_t wait;
|
||||
|
||||
thread_wait_entry_init(&wait, cur_th, timeout.recv_timeout);
|
||||
slist_add_append(&wait_recv_queue, &wait.node); //!< 放到等待队列中
|
||||
}
|
||||
}
|
||||
thread_suspend(cur_th); //!< 挂起
|
||||
@@ -505,11 +532,15 @@ static int thread_ipc_send(thread_t *to_th, msg_tag_t in_tag, ipc_timeout_t timo
|
||||
again_check:
|
||||
if (recv_kobj->status == THREAD_READY)
|
||||
{
|
||||
thread_wait_entry_t wait;
|
||||
|
||||
cur_th->ipc_status = THREAD_SEND; //!< 因为发送挂起
|
||||
cur_th->ipc_times = timout.send_timeout;
|
||||
thread_suspend(cur_th); //!< 挂起
|
||||
slist_add_append(&wait_send_queue, &cur_th->wait_node); //!< 放到等待队列中
|
||||
preemption(); //!< 进行调度
|
||||
|
||||
thread_wait_entry_init(&wait, cur_th, timout.send_timeout);
|
||||
slist_add_append(&recv_kobj->wait_send_head, &wait.node); //!< 放到线程的等待队列中
|
||||
slist_add_append(&wait_send_queue, &wait.node_timeout);
|
||||
thread_suspend(cur_th); //!< 挂起
|
||||
preemption(); //!< 进行调度
|
||||
if (cur_th->ipc_status == THREAD_IPC_ABORT)
|
||||
{
|
||||
cur_th->ipc_status = THREAD_NONE;
|
||||
@@ -526,11 +557,11 @@ again_check:
|
||||
}
|
||||
else if (recv_kobj->status == THREAD_SUSPEND && recv_kobj->ipc_status == THREAD_RECV)
|
||||
{
|
||||
if (slist_in_list(&recv_kobj->wait_node))
|
||||
{
|
||||
//!< 如果已经在队列中,则删除
|
||||
slist_del(&recv_kobj->wait_node);
|
||||
}
|
||||
// if (slist_in_list(&recv_kobj->wait_node))
|
||||
// {
|
||||
// //!< 如果已经在队列中,则删除
|
||||
// slist_del(&recv_kobj->wait_node);
|
||||
// }
|
||||
//!< 开始发送数据
|
||||
ret = ipc_data_copy(recv_kobj, cur_th, in_tag); //!< 拷贝数据
|
||||
if (ret < 0)
|
||||
@@ -563,11 +594,15 @@ static int thread_ipc_call(thread_t *to_th, msg_tag_t in_tag, msg_tag_t *ret_tag
|
||||
again_check:
|
||||
if (recv_kobj->status == THREAD_READY)
|
||||
{
|
||||
thread_wait_entry_t wait;
|
||||
|
||||
cur_th->ipc_status = THREAD_SEND; //!< 因为发送挂起
|
||||
cur_th->ipc_times = timout.send_timeout;
|
||||
thread_suspend(cur_th); //!< 挂起
|
||||
slist_add_append(&wait_send_queue, &cur_th->wait_node); //!< 放到等待队列中
|
||||
preemption(); //!< 进行调度
|
||||
|
||||
thread_wait_entry_init(&wait, cur_th, timout.send_timeout);
|
||||
slist_add_append(&recv_kobj->wait_send_head, &wait.node); //!< 放到线程的等待队列中
|
||||
slist_add_append(&wait_send_queue, &wait.node_timeout);
|
||||
thread_suspend(cur_th); //!< 挂起
|
||||
preemption();
|
||||
if (cur_th->ipc_status == THREAD_IPC_ABORT)
|
||||
{
|
||||
cur_th->ipc_status = THREAD_NONE;
|
||||
@@ -584,11 +619,11 @@ again_check:
|
||||
}
|
||||
else if (recv_kobj->status == THREAD_SUSPEND && recv_kobj->ipc_status == THREAD_RECV)
|
||||
{
|
||||
if (slist_in_list(&recv_kobj->wait_node))
|
||||
{
|
||||
//!< 如果已经在队列中,则删除
|
||||
slist_del(&recv_kobj->wait_node);
|
||||
}
|
||||
// if (slist_in_list(&recv_kobj->wait_node))
|
||||
// {
|
||||
// //!< 如果已经在队列中,则删除
|
||||
// slist_del(&recv_kobj->wait_node);
|
||||
// }
|
||||
//!< 开始发送数据
|
||||
ret = ipc_data_copy(recv_kobj, cur_th, in_tag); //!< 拷贝数据
|
||||
if (ret < 0)
|
||||
@@ -747,8 +782,8 @@ static void thread_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_t
|
||||
break;
|
||||
case BIND_TASK:
|
||||
{
|
||||
kobject_t *task_kobj = obj_space_lookup_kobj(&task->obj_space, f->r[1]);
|
||||
if (task_kobj == NULL /*TODO:检测kobj类型*/)
|
||||
kobject_t *task_kobj = obj_space_lookup_kobj_cmp_type(&task->obj_space, f->r[1], TASK_TYPE);
|
||||
if (task_kobj == NULL)
|
||||
{
|
||||
f->r[0] = msg_tag_init4(0, 0, 0, -ENOENT).raw;
|
||||
return;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# export TOOLCHAIN=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/bin/
|
||||
# export TOOLCHAIN_LIB=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/lib/gcc/arm-none-eabi/5.4.1/armv7-m
|
||||
export TOOLCHAIN=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/bin/
|
||||
export TOOLCHAIN_LIB=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/lib/gcc/arm-none-eabi/10.3.1/thumb/v7-m/nofp
|
||||
export TOOLCHAIN=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/bin/
|
||||
export TOOLCHAIN_LIB=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/lib/gcc/arm-none-eabi/5.4.1/armv7-m
|
||||
# export TOOLCHAIN=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/bin/
|
||||
# export TOOLCHAIN_LIB=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/lib/gcc/arm-none-eabi/10.3.1/thumb/v7-m/nofp
|
||||
export KEN_OFFSET=0x2000
|
||||
export INIT_OFFSET=0x10000
|
||||
export BOOTFS_ADDR_OFFSET=0x20000
|
||||
|
||||
Reference in New Issue
Block a user