优化ipc流程

This commit is contained in:
zhangzheng
2023-11-26 16:09:19 +08:00
parent 5a0ad76ad0
commit e7910247ca
41 changed files with 809 additions and 912 deletions

View File

@@ -251,7 +251,9 @@
"u_thread_util.h": "c",
"__mutex_base": "c",
"mutex": "c",
"__threading_support": "c"
"__threading_support": "c",
"spinlock.h": "c",
"mr_api.h": "c"
},
"cortex-debug.showRTOS": false,
"cortex-debug.variableUseNaturalFormat": false,

View File

@@ -1,7 +1,6 @@
#include "arch.h"
#include "thread.h"
#include "ipc.h"
#include "futex.h"
static umword_t sys_tick_cnt;
@@ -16,6 +15,5 @@ void SysTick_Handler(void)
thread_sched();
sys_tick_cnt++;
thread_timeout_check(1);
timeout_times_tick();
futex_timeout_times_tick();
}

View File

@@ -1,5 +1,19 @@
#pragma once
#include "thread.h"
#include "types.h"
struct ipc;
typedef struct ipc ipc_t;
/**
* @brief ipc 对象,用于夸进程消息发送
*
*/
typedef struct ipc
{
kobject_t kobj; //!< 内核对象
spinlock_t lock; //!< 操作的锁
thread_t *svr_th; //!< 绑定的服务端线程
slist_head_t wait_bind; //!<
ram_limit_t *lim; //!< 内存限额
umword_t user_id; //!< 服务端绑定的数据
} ipc_t;
void timeout_times_tick(void);

View File

@@ -127,10 +127,10 @@ typedef struct thread
ref_counter_t ref; //!< 引用计数
msg_buf_t msg; //!< 每个线程独有的消息缓存区
slist_head_t wait_send; //!< 节点
slist_head_t wait_head; //!< 里面是等待发送给当前线程数据的线程们。
slist_head_t wait_node; //!< 节点
mword_t ipc_times; //!< ipc时间
thread_t *last_send_th; //!< 当前线程上次接收到谁的数据
umword_t user_id; //!< 接收到的user_id
enum thread_state status; //!< 线程状态
enum thread_ipc_state ipc_status; //!< ipc状态
@@ -185,3 +185,4 @@ void thread_todead(thread_t *th, bool_t is_sche);
void thread_ready(thread_t *th, bool_t is_sche);
void thread_timeout_check(ssize_t tick);
msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id);

View File

@@ -22,428 +22,17 @@
#include "string.h"
#include "mm_wrap.h"
#include "map.h"
struct ipc;
typedef struct ipc ipc_t;
typedef struct ipc_wait_item
{
slist_head_t node;
thread_t *th;
umword_t sleep_times;
} ipc_wait_item_t;
/**
* @brief ipc 对象用于接收与发送另一个thread发送的消息
*
*/
typedef struct ipc
{
kobject_t kobj; //!< 内核对象
spinlock_t lock; //!< 操作的锁
slist_head_t wait_send; //!< 发送等待队列
slist_head_t recv_send; //!< 接收等待队列
slist_head_t node; //!< 超时检查链表
thread_t *svr_th; //!< 服务端
thread_t *last_cli_th; //!< 上一次发送数据的客户端
ram_limit_t *lim; //!< 内存限额
umword_t user_id; //!< 服务端绑定的数据
} ipc_t;
enum ipc_op
{
IPC_CALL, //!< 客户端CALL操作
IPC_WAIT, //!< 服务端等待接收信息
IPC_REPLY, //!< 服务端回复信息
IPC_BIND, //!< 绑定服务端线程
IPC_UNBIND, //!< 解除绑定
IPC_SEND, //!<
IPC_BIND,
IPC_DO = 6,
};
static int wake_up_th(ipc_t *ipc);
static slist_head_t wait_list;
/**
* @brief 初始化一个超时等待队列
*
*/
static void timeout_wait_list_init(void)
typedef struct ipc_wait_bind_entry
{
slist_init(&wait_list);
}
INIT_KOBJ(timeout_wait_list_init);
/**
* @brief 检查超时队列
*
*/
void timeout_times_tick(void)
{
ipc_t *ipc;
slist_foreach(ipc, &wait_list, node) //!< 第一次循环等待的ipc
{
umword_t status = spinlock_lock(&ipc->lock);
ipc_wait_item_t *item;
slist_foreach(item, &ipc->wait_send, node) //!< 第二次循环等待irq里面的等待者
{
if (item->sleep_times > 0)
{
if ((--item->sleep_times) == 0)
{
//!< 超时时间满后直接唤醒等待者
thread_ready(item->th, TRUE);
}
}
else
{
//!< 超时时间满后直接唤醒等待者
if (item->th->status == THREAD_SUSPEND)
{
thread_ready(item->th, TRUE);
}
}
}
spinlock_set(&ipc->lock, status);
}
}
/**
* @brief 唤醒某个ipc的所有等待者
*
* @param ipc
*/
static void timeout_times_wake_ipc(ipc_t *ipc)
{
assert(ipc);
ipc_wait_item_t *item;
slist_foreach(item, &ipc->wait_send, node) //!< 第二次循环等待irq里面的等待者
{
//!< 超时时间满后直接唤醒等待者
if (thread_get_status(item->th) == THREAD_SUSPEND)
{
thread_todead(item->th, TRUE);
}
}
slist_foreach(item, &ipc->recv_send, node) //!< 第二次循环等待irq里面的等待者
{
//!< 超时时间满后直接唤醒等待者
if (thread_get_status(item->th) == THREAD_SUSPEND)
{
thread_todead(item->th, TRUE);
}
}
thread_sched();
preemption();
}
/**
* @brief ipc_wait_item_t结构体初始化
*
* @param item
* @param ipc
* @param th
* @param times
*/
static void ipc_wait_item_init(ipc_wait_item_t *item, ipc_t *ipc, thread_t *th, umword_t times)
{
slist_init(&item->node);
item->th = th;
item->sleep_times = times;
}
/**
* @brief 添加到一个等待队列,并进行解锁
*
* @param ipc
* @param head
* @param th
* @param times 超时时间为0代表一直超时
* @return int
*/
static int add_wait_unlock(ipc_t *ipc, slist_head_t *head, thread_t *th, umword_t times, bool_t set_last_th)
{
int ret = 0;
ipc_wait_item_t item;
ipc_wait_item_init(&item, ipc, th, times);
if (times)
{
if (slist_is_empty(head))
{
slist_add_append(&wait_list, &ipc->node);
}
}
slist_add_append(head, &item.node);
thread_suspend(th);
preemption();
slist_del(&item.node);
// spinlock_set(lock, status);
if (times)
{
if (slist_is_empty(head))
{
slist_del(&ipc->node);
}
if (item.sleep_times == 0)
{
ret = -ETIMEDOUT;
}
}
if (thread_get_status(th) == THREAD_TODEAD)
{
ret = -ESHUTDOWN;
}
return ret;
}
/**
* @brief 拿出等待队列中的第一个并唤醒
*
* @param ipc
*/
static int wake_up_th(ipc_t *ipc)
{
slist_head_t *mslist = slist_first(&ipc->wait_send);
ipc_wait_item_t *item = container_of(mslist, ipc_wait_item_t, node);
if (thread_get_status(item->th) == THREAD_TODEAD)
{
return -ESHUTDOWN;
}
else
{
if (item->th->status == THREAD_SUSPEND)
{
thread_ready(item->th, TRUE);
}
}
return 0;
}
/**
* @brief ipc传输时的数据拷贝
*
* @param dst_th
* @param src_th
* @param tag
* @return int
*/
static int ipc_data_copy(thread_t *dst_th, thread_t *src_th, msg_tag_t tag)
{
void *src = src_th->msg.msg;
void *dst = dst_th->msg.msg;
ipc_msg_t *src_ipc;
ipc_msg_t *dst_ipc;
src_ipc = src;
dst_ipc = dst;
if (tag.map_buf_len > 0)
{
kobj_del_list_t del;
int map_len = tag.map_buf_len;
kobj_del_list_init(&del);
task_t *src_tk = thread_get_bind_task(src_th);
task_t *dst_tk = thread_get_bind_task(dst_th);
for (int i = 0; i < map_len; i++)
{
int ret = 0;
vpage_t dst_page = vpage_create_raw(dst_ipc->map_buf[i]);
vpage_t src_page = vpage_create_raw(src_ipc->map_buf[i]);
if (src_page.flags & VPAGE_FLAGS_MAP)
{
ret = obj_map_src_dst(&dst_tk->obj_space, &src_tk->obj_space,
vpage_get_obj_handler(dst_page),
vpage_get_obj_handler(src_page),
dst_tk->lim,
vpage_get_attrs(src_page), &del);
}
if (ret < 0)
{
return ret;
}
}
kobj_del_list_to_do(&del);
}
memcpy(dst_ipc->msg_buf, src_ipc->msg_buf, MIN(tag.msg_buf_len * WORD_BYTES, IPC_MSG_SIZE));
return 0;
}
/**
* @brief 客户端发送并接收数据
*
* @param ipc
* @param th
* @param f
* @param tag
*/
static msg_tag_t ipc_call(ipc_t *ipc, thread_t *th, entry_frame_t *f, msg_tag_t tag, ipc_timeout_t timeout)
{
umword_t status;
msg_tag_t tmp_tag;
int ret = -1;
assert(th != ipc->svr_th);
status = spinlock_lock(&ipc->lock);
__check:
if (ipc->svr_th == NULL || ipc->svr_th->status != THREAD_SUSPEND)
{
ret = add_wait_unlock(ipc, &ipc->wait_send, th,
timeout.send_timeout, FALSE);
if (ret < 0)
{
spinlock_set(&ipc->lock, status);
return msg_tag_init4(MSG_TAG_KNL_ERR, 0, 0, ret);
}
goto __check;
}
//!< 发送数据给svr_th
ret = ipc_data_copy(ipc->svr_th, th, tag); //!< 拷贝数据
if (ret < 0)
{
//!< 拷贝失败
spinlock_set(&ipc->lock, status);
return msg_tag_init4(MSG_TAG_KNL_ERR, 0, 0, ret);
}
ipc->svr_th->msg.tag = tag;
thread_ready(ipc->svr_th, TRUE); //!< 直接唤醒接受者
ipc->last_cli_th = th; //!< 设置上一次发送的客户端
ret = add_wait_unlock(ipc, &ipc->recv_send, th, timeout.recv_timeout, TRUE);
if (ret < 0)
{
// ref_counter_dec_and_release(&ipc->last_cli_th->ref, &ipc->last_cli_th->kobj);
ipc->last_cli_th = NULL;
spinlock_set(&ipc->lock, status);
return msg_tag_init4(MSG_TAG_KNL_ERR, 0, 0, ret);
}
tmp_tag = th->msg.tag;
// ipc->last_cli_th = NULL;
spinlock_set(&ipc->lock, status);
return tmp_tag;
}
/**
* @brief ipc发送操作
*
* @param ipc
* @param th
* @param f
* @param tag
* @param timeout
* @return msg_tag_t
*/
static msg_tag_t ipc_send(ipc_t *ipc, thread_t *th, entry_frame_t *f, msg_tag_t tag, ipc_timeout_t timeout)
{
umword_t status;
int ret = -1;
msg_tag_t tmp_tag;
assert(th != ipc->svr_th);
status = spinlock_lock(&ipc->lock);
__check:
if (ipc->svr_th == NULL || ipc->svr_th->status != THREAD_SUSPEND)
{
ret = add_wait_unlock(ipc, &ipc->wait_send, th,
timeout.send_timeout, FALSE);
if (ret < 0)
{
spinlock_set(&ipc->lock, status);
return msg_tag_init4(MSG_TAG_KNL_ERR, 0, 0, ret);
}
goto __check;
}
//!< 发送数据给svr_th
ret = ipc_data_copy(ipc->svr_th, th, tag); //!< 拷贝数据
if (ret < 0)
{
//!< 拷贝失败
spinlock_set(&ipc->lock, status);
return msg_tag_init4(MSG_TAG_KNL_ERR, 0, 0, ret);
}
ipc->svr_th->msg.tag = tag;
thread_ready(ipc->svr_th, TRUE); //!< 直接唤醒接受者
ipc->last_cli_th = NULL;
spinlock_set(&ipc->lock, status);
return tmp_tag;
}
/**
* @brief 服务端用于回复
*
* @param ipc
* @param th
* @param f
* @param tag
*/
static int ipc_reply(ipc_t *ipc, thread_t *th, entry_frame_t *f, msg_tag_t tag)
{
umword_t status;
if (ipc->last_cli_th == NULL)
{
return -1;
}
assert(th == ipc->svr_th); // 服务端才能回复
status = spinlock_lock(&ipc->lock);
if (ipc->last_cli_th == NULL)
{
spinlock_set(&ipc->lock, status);
return -1;
}
//!< 发送数据给svr_th
int ret = ipc_data_copy(ipc->last_cli_th, th, tag); //!< 拷贝数据
if (ret < 0)
{
spinlock_set(&ipc->lock, status);
return ret;
}
ipc->last_cli_th->msg.tag = tag;
if (thread_get_status(ipc->last_cli_th) != THREAD_TODEAD)
{
thread_ready(ipc->last_cli_th, TRUE); //!< 直接唤醒接受者
}
else
{
ret = -EAGAIN;
}
spinlock_set(&ipc->lock, status);
return ret;
}
/**
* @brief 服务端用于接收数据
*
* @param ipc
* @param th
* @param f
* @param tag
*/
static msg_tag_t ipc_wait(ipc_t *ipc, thread_t *th, entry_frame_t *f, msg_tag_t in_tag)
{
assert(ipc->svr_th == th);
umword_t status;
msg_tag_t tag;
status = spinlock_lock(&ipc->lock);
thread_suspend(th);
if (!slist_is_empty(&ipc->wait_send))
{
int ret = wake_up_th(ipc);
if (-ESHUTDOWN == ret)
{
thread_ready(th, TRUE);
tag = msg_tag_init4(0, 0, 0, -EAGAIN);
}
else
{
preemption();
tag = th->msg.tag;
}
}
else
{
preemption();
tag = th->msg.tag;
}
spinlock_set(&ipc->lock, status);
return tag;
}
slist_head_t node;
thread_t *th;
} ipc_wait_bind_entry_t;
/**
* @brief ipc的系统调用
*
@@ -458,127 +47,107 @@ static void ipc_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag,
assert(f);
msg_tag_t tag = msg_tag_init4(0, 0, 0, -EINVAL);
thread_t *th = thread_get_current();
task_t *cur_task = thread_get_current_task();
ipc_t *ipc = container_of(kobj, ipc_t, kobj);
if (sys_p.prot != IPC_PROT)
if (sys_p.prot != IPC_PROT && sys_p.prot != THREAD_PROT)
{
//!< ipc对象拥有代理thread消息的功能所以这里对与thread协议进行放宽
f->r[0] = msg_tag_init4(0, 0, 0, -EPROTO).raw;
return;
}
switch (sys_p.op)
{
case IPC_CALL:
{
if (th == ipc->svr_th)
{
tag = msg_tag_init4(0, 0, 0, -EACCES);
}
else
{
ref_counter_inc(&th->ref); //!< 引用计数+1
tag = ipc_call(ipc, th, f, in_tag, ipc_timeout_create(f->r[1])); //!< ipc call
ref_counter_dec_and_release(&th->ref, &th->kobj); //!< 引用计数-1
if (msg_tag_get_val(tag) == -ESHUTDOWN)
{
thread_dead(th);
}
}
}
break;
case IPC_SEND:
{
if (th == ipc->svr_th)
{
tag = msg_tag_init4(0, 0, 0, -EACCES);
}
else
{
ref_counter_inc(&th->ref); //!< 引用计数+1
tag = ipc_send(ipc, th, f, in_tag, ipc_timeout_create(f->r[1])); //!< ipc call
ref_counter_dec_and_release(&th->ref, &th->kobj); //!< 引用计数-1
if (msg_tag_get_val(tag) == -ESHUTDOWN)
{
thread_dead(th);
}
}
}
break;
case IPC_WAIT:
{
if (ipc->svr_th != th) //!< 只有服务端才能wait
{
tag = msg_tag_init4(0, 0, 0, -EACCES);
}
else
{
ref_counter_inc(&th->ref); //!< 引用计数+1
tag = ipc_wait(ipc, th, f, in_tag); //!< 进入等待
ref_counter_dec_and_release(&th->ref, &th->kobj); //!< 引用计数-1
if (msg_tag_get_val(tag) == -ESHUTDOWN)
{
thread_dead(th);
}
f->r[1] = ipc->user_id;
}
}
break;
case IPC_REPLY:
{
if (ipc->svr_th != th) //!< 只有服务端才能回复
{
tag = msg_tag_init4(0, 0, 0, -EACCES);
}
else
{
ref_counter_inc(&th->ref); //!< 引用计数+1
int ret = ipc_reply(ipc, th, f, in_tag);
ref_counter_dec_and_release(&th->ref, &th->kobj); //!< 引用计数-1
if (msg_tag_get_val(tag) == -ESHUTDOWN)
{
thread_dead(th);
}
tag = msg_tag_init4(0, 0, 0, ret);
}
}
break;
case IPC_BIND:
{
if (!ipc->svr_th)
int ret = 0;
if (sys_p.prot == THREAD_PROT)
{
kobject_t *source_kobj = obj_space_lookup_kobj(&thread_get_current_task()->obj_space, f->r[1]);
tag = msg_tag_init4(0, 0, 0, -EPROTO);
break;
}
/*TODO:原子操作,绑定其他线程不一定是当前线程*/
if (ipc->svr_th == NULL)
{
mword_t status = spinlock_lock(&cur_task->kobj.lock); //!< 锁住当前的task
if (!source_kobj)
if (status < 0)
{
tag = msg_tag_init4(0, 0, 0, -ENOENT);
tag = msg_tag_init4(0, 0, 0, -EACCES);
break;
}
thread_t *srv_th = container_of(source_kobj, thread_t, kobj);
ref_counter_inc(&cur_task->ref_cn); //!< task引用计数+1
thread_t *recv_kobj = (thread_t *)obj_space_lookup_kobj_cmp_type(&cur_task->obj_space, f->r[0], THREAD_TYPE);
ref_counter_inc(&srv_th->ref);
ipc->svr_th = srv_th;
ipc->user_id = f->r[2];
tag = msg_tag_init4(0, 0, 0, 0);
if (!recv_kobj)
{
ret = -ENOENT;
goto end_bind;
}
ref_counter_inc(&recv_kobj->ref); //!< 绑定后线程的引用计数+1防止被删除
ipc->svr_th = recv_kobj;
ipc->user_id = f->r[1];
ipc_wait_bind_entry_t *pos;
slist_foreach_not_next(pos, &ipc->wait_bind, node) //!< 唤醒所有等待绑定的线程
{
ipc_wait_bind_entry_t *next = slist_next_entry(pos, &ipc->wait_bind, node);
assert(pos->th->status == THREAD_SUSPEND);
slist_del(&next->node);
thread_ready(pos->th, TRUE);
pos = next;
}
ret = 0;
end_bind:
//!< 先解锁然后在给task的引用计数-1
spinlock_set(&cur_task->kobj.lock, status);
ref_counter_dec_and_release(&cur_task->ref_cn, &cur_task->kobj);
tag = msg_tag_init4(0, 0, 0, ret);
}
else
{
tag = msg_tag_init4(0, 0, 0, -EACCES);
tag = msg_tag_init4(0, 0, 0, -ECANCELED);
}
}
break;
case IPC_UNBIND:
case IPC_DO:
{
//!< 如果是ipc协议则当成一个ipc处理
if (ipc->svr_th == th)
{
ref_counter_dec_and_release(&th->ref, &th->kobj); //!< 引用计数-1
ipc->svr_th = NULL;
tag = msg_tag_init4(0, 0, 0, 0);
tag = msg_tag_init4(0, 0, 0, -ECANCELED);
break;
}
again:
if (ipc->svr_th == NULL)
{
ipc_wait_bind_entry_t entry = {
.th = th,
};
slist_init(&entry.node);
mword_t status = spinlock_lock(&ipc->lock);
slist_add(&ipc->wait_bind, &entry.node);
thread_suspend(th);
preemption();
slist_del(&entry.node);
if (th->ipc_status == THREAD_IPC_ABORT)
{
th->ipc_status = THREAD_NONE;
tag = msg_tag_init4(0, 0, 0, -ENOENT);
}
spinlock_set(&ipc->lock, status);
goto again;
}
else
{
tag = msg_tag_init4(0, 0, 0, -EACCES);
tag = thread_do_ipc(&ipc->svr_th->kobj, f, ipc->user_id);
}
}
break;
default:
break;
}
f->r[0] = tag.raw;
}
@@ -587,10 +156,18 @@ static void ipc_release_stage1(kobject_t *kobj)
ipc_t *ipc = container_of(kobj, ipc_t, kobj);
kobject_invalidate(kobj);
timeout_times_wake_ipc(ipc);
ipc_wait_bind_entry_t *pos;
slist_foreach(pos, &ipc->wait_bind, node)
{
assert(pos->th->status == THREAD_SUSPEND);
pos->th->ipc_status == THREAD_IPC_ABORT;
thread_ready(pos->th, TRUE);
}
if (ipc->svr_th)
{
ref_counter_dec_and_release(&ipc->svr_th->ref, &ipc->svr_th->kobj);
ipc->svr_th = NULL;
}
}
static void ipc_release_stage2(kobject_t *kobj)
@@ -603,12 +180,9 @@ static void ipc_release_stage2(kobject_t *kobj)
static void ipc_init(ipc_t *ipc, ram_limit_t *lim)
{
kobject_init(&ipc->kobj, IPC_TYPE);
slist_init(&ipc->wait_send);
slist_init(&ipc->recv_send);
slist_init(&ipc->node);
slist_init(&ipc->wait_bind);
spinlock_init(&ipc->lock);
ipc->lim = lim;
ipc->svr_th = NULL;
ipc->kobj.invoke_func = ipc_syscall;
ipc->kobj.stage_1_func = ipc_release_stage1;
ipc->kobj.stage_2_func = ipc_release_stage2;

View File

@@ -32,13 +32,31 @@ enum thread_op
MSG_BUG_GET,
MSG_BUG_SET,
YIELD,
DO_IPC,
DO_IPC = 6, //!< 与ipc对象中的额IPC_DO一致
};
enum IPC_TYPE
{
IPC_CALL,
IPC_REPLY,
IPC_WAIT,
IPC_RECV,
IPC_SEND,
};
static void thread_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag, entry_frame_t *f);
static bool_t thread_put(kobject_t *kobj);
static void thread_release_stage1(kobject_t *kobj);
static void thread_release_stage2(kobject_t *kobj);
static slist_head_t wait_send_queue;
static slist_head_t wait_recv_queue;
static void thread_timeout_init(void)
{
slist_init(&wait_send_queue);
slist_init(&wait_recv_queue);
}
INIT_KOBJ(thread_timeout_init);
/**
* @brief 线程的初始化函数
*
@@ -48,8 +66,7 @@ void thread_init(thread_t *th, ram_limit_t *lim)
{
kobject_init(&th->kobj, THREAD_TYPE);
sched_init(&th->sche);
slist_init(&th->wait_send);
slist_init(&th->wait_head);
slist_init(&th->wait_node);
ref_counter_init(&th->ref);
ref_counter_inc(&th->ref);
th->lim = lim;
@@ -78,21 +95,37 @@ static void thread_release_stage1(kobject_t *kobj)
{
thread_suspend(th);
}
}else {
if (cur->status == THREAD_READY)
{
thread_suspend(th);
}
}
thread_t *pos;
slist_foreach_not_next(pos, &th->wait_head, wait_send)
slist_foreach_not_next(pos, &wait_send_queue, wait_node)
{
assert(pos->status == THREAD_SUSPEND);
thread_t *next = slist_next_entry(pos, &th->wait_head, wait_send);
thread_t *next = slist_next_entry(pos, &th->wait_head, wait_node);
pos->ipc_status = THREAD_IPC_ABORT;
thread_ready(pos, TRUE);
slist_del(&pos->wait_send);
slist_del(&pos->wait_node);
pos = next;
}
slist_del(&th->wait_send); //!< 从链表中删除
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);
pos->ipc_status = THREAD_IPC_ABORT;
thread_ready(pos, TRUE);
slist_del(&pos->wait_node);
pos = next;
}
slist_del(&th->wait_node); //!< 从链表中删除
thread_unbind(th);
}
static void thread_release_stage2(kobject_t *kobj)
@@ -254,23 +287,21 @@ thread_t *thread_create(ram_limit_t *ram)
printk("create thread 0x%x\n", th);
return th;
}
enum IPC_TYPE
{
IPC_CALL,
IPC_REPLY,
IPC_WAIT,
IPC_RECV,
IPC_SEND,
};
/**
* @brief 线程超时检查
*
* @param tick
*/
void thread_timeout_check(ssize_t tick)
{
thread_t *pos;
thread_t *th = thread_get_current();
// thread_t *th = thread_get_current();
slist_foreach_not_next(pos, &th->wait_head, wait_send)
slist_foreach_not_next(pos, &wait_send_queue, wait_node)
{
assert(pos->status == THREAD_SUSPEND);
thread_t *next = slist_next_entry(pos, &th->wait_head, wait_send);
thread_t *next = slist_next_entry(pos, &wait_send_queue, wait_node);
if (pos->ipc_times > 0)
{
@@ -280,7 +311,26 @@ void thread_timeout_check(ssize_t tick)
pos->ipc_status = THREAD_TIMEOUT;
thread_ready(pos, TRUE);
slist_del(&pos->wait_send);
slist_del(&pos->wait_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, &wait_recv_queue, wait_node);
if (pos->ipc_times > 0)
{
pos->ipc_times -= tick;
if (pos->ipc_times <= 0)
{
pos->ipc_status = THREAD_TIMEOUT;
thread_ready(pos, TRUE);
slist_del(&pos->wait_node);
}
}
pos = next;
@@ -336,6 +386,7 @@ static int ipc_data_copy(thread_t *dst_th, thread_t *src_th, msg_tag_t tag)
kobj_del_list_to_do(&del);
}
memcpy(dst_ipc->msg_buf, src_ipc->msg_buf, MIN(tag.msg_buf_len * WORD_BYTES, IPC_MSG_SIZE));
dst_th->msg.tag = tag;
return 0;
}
@@ -344,30 +395,55 @@ static int ipc_data_copy(thread_t *dst_th, thread_t *src_th, msg_tag_t tag)
*
* @return int
*/
static int thread_ipc_recv(msg_tag_t *ret_msg)
static int thread_ipc_recv(msg_tag_t *ret_msg, ipc_timeout_t timeout, umword_t *ret_user_id)
{
int ret = 0;
assert(ret_msg);
assert(ret_user_id);
thread_t *cur_th = thread_get_current();
umword_t lock_status;
lock_status = cpulock_lock();
cur_th->ipc_status = THREAD_RECV; //!< 因为接收挂起
thread_suspend(cur_th); //!< 挂起
if (!slist_is_empty(&cur_th->wait_head))
if (!slist_is_empty(&wait_send_queue))
{
slist_head_t *mslist = slist_first(&cur_th->wait_head);
thread_t *send_th = container_of(mslist, thread_t, wait_send);
//!< 有发送者
slist_head_t *mslist = slist_first(&wait_send_queue);
thread_t *send_th = container_of(mslist, thread_t, wait_node);
slist_del(mslist); //!< 删除唤醒的线程
thread_ready(send_th, TRUE);
}
preemption(); //!< 进行调度
cur_th->ipc_status = THREAD_NONE;
*ret_msg = cur_th->msg.tag;
else
{
//!< 加入等待队列
if (timeout.recv_timeout)
{
cur_th->ipc_times = timeout.recv_timeout;
slist_add_append(&wait_recv_queue, &cur_th->wait_node); //!< 放到等待队列中
}
}
thread_suspend(cur_th); //!< 挂起
preemption(); //!< 进行调度
if (cur_th->ipc_status == THREAD_IPC_ABORT)
{
cur_th->ipc_status = THREAD_NONE;
ret = -ESHUTDOWN;
}
else if (cur_th->ipc_status == THREAD_TIMEOUT)
{
cur_th->ipc_status = THREAD_NONE;
ret = -ERTIMEDOUT;
}
else
{
cur_th->ipc_status = THREAD_NONE;
*ret_msg = cur_th->msg.tag;
*ret_user_id = cur_th->user_id;
}
cpulock_set(lock_status);
return 0;
return ret;
}
/**
@@ -408,93 +484,26 @@ static int thread_ipc_reply(msg_tag_t in_tag)
cpulock_set(status);
return ret;
}
static int thread_ipc_send(obj_handler_t target_th_hd, msg_tag_t in_tag, ipc_timeout_t timout)
static int thread_ipc_send(thread_t *to_th, msg_tag_t in_tag, ipc_timeout_t timout)
{
int ret = -EINVAL;
task_t *cur_task = thread_get_current_task();
thread_t *cur_th = thread_get_current();
mword_t lock_stats = spinlock_lock(&cur_task->kobj.lock);
thread_t *recv_kobj;
thread_t *recv_kobj = to_th;
mword_t lock_stats = spinlock_lock(&cur_th->kobj.lock);
if (lock_stats < 0)
{
//!< 锁已经无效了
return -EACCES;
}
ref_counter_inc(&cur_task->ref_cn);
recv_kobj = (thread_t *)obj_space_lookup_kobj_cmp_type(&cur_task->obj_space, target_th_hd, THREAD_TYPE);
if (!recv_kobj) /*比较类型*/
{
return -ENOENT;
}
again_check:
if (recv_kobj->status == THREAD_READY)
{
cur_th->ipc_status = THREAD_SEND; //!< 因为发送挂起
cur_th->ipc_times = timout.send_timeout;
thread_suspend(cur_th); //!< 挂起
slist_add_append(&recv_kobj->wait_head, &cur_th->wait_send); //!< 放到等待队列中
preemption(); //!< 进行调度
if (cur_th->ipc_status == THREAD_IPC_ABORT)
{
ret = -ESHUTDOWN;
goto end;
}
else if (cur_th->ipc_status == THREAD_TIMEOUT)
{
ret = -EWTIMEDOUT;
goto end;
}
cur_th->ipc_status = THREAD_NONE;
goto again_check;
}
else if (recv_kobj->status == THREAD_SUSPEND && recv_kobj->ipc_status == THREAD_RECV)
{
//!< 开始发送数据
ret = ipc_data_copy(recv_kobj, cur_th, in_tag); //!< 拷贝数据
if (ret < 0)
{
//!< 拷贝失败
goto end;
}
thread_ready(recv_kobj, TRUE); //!< 直接唤醒接受者
preemption(); //!< 进行调度
}
ret = 0;
end:
spinlock_set(&cur_task->kobj.lock, lock_stats);
ref_counter_dec_and_release(&cur_task->ref_cn, &cur_task->kobj);
return ret;
}
static int thread_ipc_call(obj_handler_t target_th_hd, msg_tag_t in_tag, msg_tag_t *ret_tag, ipc_timeout_t timout)
{
assert(ret_tag);
int ret = -EINVAL;
task_t *cur_task = thread_get_current_task();
thread_t *cur_th = thread_get_current();
thread_t *recv_kobj;
mword_t lock_stats = spinlock_lock(&cur_task->kobj.lock);
if (lock_stats < 0)
{
//!< 锁已经无效了
return -EACCES;
}
ref_counter_inc(&cur_task->ref_cn);
recv_kobj = (thread_t *)obj_space_lookup_kobj_cmp_type(&cur_task->obj_space, target_th_hd, THREAD_TYPE);
if (!recv_kobj) /*比较类型*/
{
ret = -ENOENT;
goto end;
}
again_check:
if (recv_kobj->status == THREAD_READY)
{
cur_th->ipc_status = THREAD_SEND; //!< 因为发送挂起
cur_th->ipc_times = timout.send_timeout;
thread_suspend(cur_th); //!< 挂起
slist_add_append(&recv_kobj->wait_head, &cur_th->wait_send); //!< 放到等待队列中
preemption(); //!< 进行调度
thread_suspend(cur_th); //!< 挂起
slist_add_append(&wait_send_queue, &cur_th->wait_node); //!< 放到等待队列中
preemption(); //!< 进行调度
if (cur_th->ipc_status == THREAD_IPC_ABORT)
{
cur_th->ipc_status = THREAD_NONE;
@@ -511,6 +520,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);
}
//!< 开始发送数据
ret = ipc_data_copy(recv_kobj, cur_th, in_tag); //!< 拷贝数据
if (ret < 0)
@@ -521,13 +535,75 @@ again_check:
recv_kobj->last_send_th = cur_th; //!< 设置接收者的上一次发送者是谁
ref_counter_inc(&cur_th->ref); //!< 作为发送者增加一次引用
thread_ready(recv_kobj, TRUE); //!< 直接唤醒接受者
thread_ipc_recv(ret_tag); //!< 当前线程进行接收
preemption(); //!< 进行调度
}
ret = 0;
end:
spinlock_set(&cur_task->kobj.lock, lock_stats);
ref_counter_dec_and_release(&cur_task->ref_cn, &cur_task->kobj);
spinlock_set(&cur_th->kobj.lock, lock_stats);
}
static 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)
{
assert(ret_tag);
int ret = -EINVAL;
thread_t *cur_th = thread_get_current();
thread_t *recv_kobj = to_th;
mword_t lock_stats = spinlock_lock(&cur_th->kobj.lock);
if (lock_stats < 0)
{
//!< 锁已经无效了
return -EACCES;
}
again_check:
if (recv_kobj->status == THREAD_READY)
{
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(); //!< 进行调度
if (cur_th->ipc_status == THREAD_IPC_ABORT)
{
cur_th->ipc_status = THREAD_NONE;
ret = -ESHUTDOWN;
goto end;
}
else if (cur_th->ipc_status == THREAD_TIMEOUT)
{
ret = -EWTIMEDOUT;
goto end;
}
cur_th->ipc_status = THREAD_NONE;
goto 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);
}
//!< 开始发送数据
ret = ipc_data_copy(recv_kobj, cur_th, in_tag); //!< 拷贝数据
if (ret < 0)
{
//!< 拷贝失败
goto end;
}
recv_kobj->last_send_th = cur_th; //!< 设置接收者的上一次发送者是谁
ref_counter_inc(&cur_th->ref); //!< 作为发送者增加一次引用
thread_ready(recv_kobj, TRUE); //!< 直接唤醒接受者
ret = thread_ipc_recv(ret_tag, timout, ret_user_id); //!< 当前线程进行接收
if (ret < 0)
{
//!< 接收超时
goto end;
}
preemption(); //!< 进行调度
}
ret = 0;
end:
spinlock_set(&cur_th->kobj.lock, lock_stats);
return ret;
}
/**
@@ -538,11 +614,12 @@ end:
* @param f
* @return int
*/
static msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f)
msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id)
{
assert(kobj);
task_t *cur_task = thread_get_current_task();
thread_t *cur_th = thread_get_current();
thread_t *to_th = (thread_t *)kobj;
umword_t ipc_type = f->r[1];
obj_handler_t th_hd = 0;
int ret = -EINVAL;
@@ -556,7 +633,8 @@ static msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f)
th_hd = f->r[2];
ipc_timeout_t ipc_tm_out = ipc_timeout_create(f->r[3]);
ret = thread_ipc_call(th_hd, in_tag, &recv_tag, ipc_tm_out);
to_th->user_id = user_id;
ret = thread_ipc_call(to_th, in_tag, &recv_tag, ipc_tm_out, &f->r[1]);
if (ret < 0)
{
return msg_tag_init4(0, 0, 0, ret);
@@ -574,17 +652,20 @@ static msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f)
case IPC_WAIT:
{
msg_tag_t ret_msg;
ipc_timeout_t ipc_tm_out = ipc_timeout_create(f->r[3]);
thread_ipc_recv(&ret_msg);
thread_ipc_recv(&ret_msg, ipc_tm_out, &f->r[1]);
return ret_msg;
}
case IPC_SEND:
{
msg_tag_t in_tag = msg_tag_init(f->r[0]);
ipc_timeout_t ipc_tm_out = ipc_timeout_create(f->r[3]);
msg_tag_t recv_tag;
th_hd = f->r[2];
ipc_timeout_t ipc_tm_out = ipc_timeout_create(f->r[3]);
ret = thread_ipc_send(th_hd, in_tag, ipc_tm_out);
to_th->user_id = user_id;
ret = thread_ipc_call(to_th, in_tag, &recv_tag, ipc_tm_out, &f->r[1]);
return msg_tag_init4(0, 0, 0, ret);
}
default:
@@ -674,7 +755,7 @@ static void thread_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_t
break;
case DO_IPC:
{
tag = thread_do_ipc(&cur_th->kobj, f);
tag = thread_do_ipc(kobj, f, 0);
}
break;
}
@@ -721,7 +802,10 @@ task_t *thread_get_current_task(void)
thread_t *cur = thread_get_current();
kobject_t *kobj = cur->task;
assert(kobj);
if (!kobj)
{
return NULL;
}
return container_of(
kobj, task_t, kobj);
}

View File

@@ -1,57 +1,6 @@
#pragma once
#include "u_prot.h"
#include "u_types.h"
#define MSG_BUG_LEN 128
#define MSG_BUF_RECV_R_FLAGS 0x02U //!< 接收上次发送数据的接收者
#define MSG_BUF_REPLY_FLAGS 0x04U //!<
#define IPC_MSG_SIZE 96 //!< IPC消息大小
#define MAP_BUF_SIZE 16 //!< 映射消息大小
#define IPC_USER_SIZE 12 //!< 用户态消息大小
typedef struct ipc_msg
{
union
{
struct
{
umword_t msg_buf[IPC_MSG_SIZE / WORD_BYTES];
umword_t map_buf[MAP_BUF_SIZE / WORD_BYTES];
umword_t user[IPC_USER_SIZE / WORD_BYTES];
};
uint8_t data[MSG_BUG_LEN];
};
} ipc_msg_t;
typedef union ipc_timeout
{
umword_t raw;
struct
{
uhmword_t send_timeout;
uhmword_t recv_timeout;
};
} ipc_timeout_t;
static inline ipc_timeout_t ipc_timeout_create(umword_t raw)
{
return (ipc_timeout_t){
.raw = raw,
};
}
static inline ipc_timeout_t ipc_timeout_create2(uhmword_t send_timeout, uhmword_t recv_timeout)
{
return (ipc_timeout_t){
.send_timeout = send_timeout,
.recv_timeout = recv_timeout,
};
}
msg_tag_t ipc_bind(obj_handler_t obj, obj_handler_t tag_th, umword_t user_obj);
msg_tag_t ipc_wait(obj_handler_t obj, umword_t *user_obj);
msg_tag_t ipc_reply(obj_handler_t obj, msg_tag_t tag);
msg_tag_t ipc_call(obj_handler_t obj, msg_tag_t in_tag, ipc_timeout_t timeout);
msg_tag_t ipc_send(obj_handler_t obj, msg_tag_t in_tag, ipc_timeout_t timeout);
#define EWTIMEDOUT 131 /* Connection timed out */
#define ERTIMEDOUT 132 /* Connection timed out */
msg_tag_t ipc_bind(obj_handler_t obj, obj_handler_t th_obj, umword_t user_obj);

View File

@@ -2,7 +2,55 @@
#include "u_types.h"
#include "u_prot.h"
#include "u_ipc.h"
#define MSG_BUG_LEN 128
#define MSG_BUF_RECV_R_FLAGS 0x02U //!< 接收上次发送数据的接收者
#define MSG_BUF_REPLY_FLAGS 0x04U //!<
#define IPC_MSG_SIZE 96 //!< IPC消息大小
#define MAP_BUF_SIZE 16 //!< 映射消息大小
#define IPC_USER_SIZE 12 //!< 用户态消息大小
typedef struct ipc_msg
{
union
{
struct
{
umword_t msg_buf[IPC_MSG_SIZE / WORD_BYTES];
umword_t map_buf[MAP_BUF_SIZE / WORD_BYTES];
umword_t user[IPC_USER_SIZE / WORD_BYTES];
};
uint8_t data[MSG_BUG_LEN];
};
} ipc_msg_t;
typedef union ipc_timeout
{
umword_t raw;
struct
{
uhmword_t send_timeout;
uhmword_t recv_timeout;
};
} ipc_timeout_t;
static inline ipc_timeout_t ipc_timeout_create(umword_t raw)
{
return (ipc_timeout_t){
.raw = raw,
};
}
static inline ipc_timeout_t ipc_timeout_create2(uhmword_t send_timeout, uhmword_t recv_timeout)
{
return (ipc_timeout_t){
.send_timeout = send_timeout,
.recv_timeout = recv_timeout,
};
}
#define EWTIMEDOUT 131 /* Connection timed out */
#define ERTIMEDOUT 132 /* Connection timed out */
msg_tag_t thread_yield(obj_handler_t obj);
msg_tag_t thread_msg_buf_set(obj_handler_t obj, void *msg);
msg_tag_t thread_msg_buf_get(obj_handler_t obj, umword_t *msg, umword_t *len);
@@ -10,7 +58,7 @@ msg_tag_t thread_exec_regs(obj_handler_t obj, umword_t pc, umword_t sp, umword_t
msg_tag_t thread_run(obj_handler_t obj, uint8_t prio);
msg_tag_t thread_bind_task(obj_handler_t obj, obj_handler_t tk_obj);
msg_tag_t thread_ipc_wait(void);
msg_tag_t thread_ipc_wait(ipc_timeout_t timeout, umword_t *ret_obj);
msg_tag_t thread_ipc_reply(msg_tag_t in_tag, ipc_timeout_t timeout);
msg_tag_t thread_ipc_send(msg_tag_t in_tag, obj_handler_t target_th_obj, ipc_timeout_t timeout);
msg_tag_t thread_ipc_call(msg_tag_t in_tag, obj_handler_t target_th_obj, ipc_timeout_t timeout);

View File

@@ -6,101 +6,18 @@
enum ipc_op
{
IPC_CALL, //!< 客户端CALL操作
IPC_WAIT, //!< 服务端等待接收信息
IPC_REPLY, //!< 服务端回复信息
IPC_BIND, //!< 绑定服务端线程
IPC_UNBIND, //!< 解除绑定
IPC_SEND, //!< 发送数据
IPC_BIND,
IPC_DO = 6,
};
msg_tag_t ipc_bind(obj_handler_t obj, obj_handler_t tag_th, umword_t user_obj)
msg_tag_t ipc_bind(obj_handler_t obj, obj_handler_t th_obj, umword_t user_obj)
{
register volatile umword_t r0 asm("r0");
mk_syscall(syscall_prot_create(IPC_BIND, IPC_PROT, obj).raw,
0,
tag_th,
th_obj,
user_obj,
0,
0,
0);
asm __volatile__(""
:
:
: "r0");
msg_tag_t tag = msg_tag_init(r0);
return tag;
}
msg_tag_t ipc_wait(obj_handler_t obj, umword_t *user_obj)
{
register volatile umword_t r0 asm("r0");
register volatile umword_t r1 asm("r1");
mk_syscall(syscall_prot_create(IPC_WAIT, IPC_PROT, obj).raw,
0,
0,
0,
0,
0,
0);
asm __volatile__(""
:
:
: "r0", "r1");
if (user_obj)
{
*user_obj = r1;
}
return msg_tag_init(r0);
}
msg_tag_t ipc_reply(obj_handler_t obj, msg_tag_t in_tag)
{
register volatile umword_t r0 asm("r0");
mk_syscall(syscall_prot_create(IPC_REPLY, IPC_PROT, obj).raw,
in_tag.raw,
0,
0,
0,
0,
0);
asm __volatile__(""
:
:
: "r0");
msg_tag_t tag = msg_tag_init(r0);
return tag;
}
msg_tag_t ipc_call(obj_handler_t obj, msg_tag_t in_tag, ipc_timeout_t timeout)
{
register volatile umword_t r0 asm("r0");
mk_syscall(syscall_prot_create(IPC_CALL, IPC_PROT, obj).raw,
in_tag.raw,
timeout.raw,
0,
0,
0,
0);
asm __volatile__(""
:
:
: "r0");
msg_tag_t tag = msg_tag_init(r0);
return tag;
}
msg_tag_t ipc_send(obj_handler_t obj, msg_tag_t in_tag, ipc_timeout_t timeout)
{
register volatile umword_t r0 asm("r0");
mk_syscall(syscall_prot_create(IPC_SEND, IPC_PROT, obj).raw,
in_tag.raw,
timeout.raw,
0,
0,
0,
0);
asm __volatile__(""

View File

@@ -20,20 +20,25 @@ enum IPC_TYPE
IPC_RECV,
IPC_SEND,
};
msg_tag_t thread_ipc_wait(void)
msg_tag_t thread_ipc_wait(ipc_timeout_t timeout, umword_t *obj)
{
register volatile umword_t r0 asm("r0");
register volatile umword_t r1 asm("r1");
mk_syscall(syscall_prot_create4(DO_IPC, THREAD_PROT, -1, TRUE).raw,
0,
IPC_WAIT,
0,
0,
timeout.raw,
0,
0);
asm __volatile__(""
:
:
: "r0");
: "r0", "r1");
if (obj)
{
*obj = r1;
}
return msg_tag_init(r0);
}
msg_tag_t thread_ipc_reply(msg_tag_t in_tag, ipc_timeout_t timeout)
@@ -55,10 +60,10 @@ msg_tag_t thread_ipc_reply(msg_tag_t in_tag, ipc_timeout_t timeout)
msg_tag_t thread_ipc_send(msg_tag_t in_tag, obj_handler_t target_th_obj, ipc_timeout_t timeout)
{
register volatile umword_t r0 asm("r0");
mk_syscall(syscall_prot_create4(DO_IPC, THREAD_PROT, -1, TRUE).raw,
mk_syscall(syscall_prot_create4(DO_IPC, THREAD_PROT, target_th_obj, TRUE).raw,
in_tag.raw,
IPC_SEND,
target_th_obj,
0,
timeout.raw,
0,
0);
@@ -71,10 +76,10 @@ msg_tag_t thread_ipc_send(msg_tag_t in_tag, obj_handler_t target_th_obj, ipc_tim
msg_tag_t thread_ipc_call(msg_tag_t in_tag, obj_handler_t target_th_obj, ipc_timeout_t timeout)
{
register volatile umword_t r0 asm("r0");
mk_syscall(syscall_prot_create4(DO_IPC, THREAD_PROT, -1, TRUE).raw,
mk_syscall(syscall_prot_create4(DO_IPC, THREAD_PROT, target_th_obj, TRUE).raw,
in_tag.raw,
IPC_CALL,
target_th_obj,
0,
timeout.raw,
0,
0);

View File

@@ -5,5 +5,4 @@
typedef struct drv
{
rpc_svr_obj_t svr;
obj_handler_t ipc;
} drv_t;

View File

@@ -6,7 +6,6 @@
typedef struct fs
{
rpc_svr_obj_t svr;
obj_handler_t ipc;
} fs_t;
void fs_init(fs_t *fs);

View File

@@ -19,5 +19,4 @@ typedef struct ns
rpc_svr_obj_t svr;
namespace_entry_t ne_list[NAMESAPCE_NR]; //!< 服务列表
obj_handler_t hd; //!< 存储临时用于映射的hd
obj_handler_t ipc_hd; //!< 服务的ipc hd
} ns_t;

View File

@@ -68,10 +68,119 @@ static bool_t reg_hd(const char *path, obj_handler_t hd, int split_inx)
return FALSE;
}
RPC_GENERATION_CALL2(ns_t, NS_REGISTER_OP, register,
rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, svr_hd)
// RPC_GENERATION_CALL2(ns_t, NS_REGISTER_OP, register,
// rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
// rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, svr_hd)
msg_tag_t ns_t_register_call(obj_handler_t hd, rpc_ref_array_uint32_t_uint8_t_32_t *var0, rpc_obj_handler_t_t *var1)
{
void *buf;
ipc_msg_t *msg_ipc;
thread_msg_buf_get(2, (umword_t *)(&buf), ((void *)0));
msg_ipc = (ipc_msg_t *)buf;
int off = 0;
int off_buf = 0;
int ret = -1;
size_t op_val = ((uint16_t)0);
rpc_memcpy(msg_ipc->msg_buf, &op_val, sizeof(op_val));
off += rpc_align(sizeof(op_val), __alignof(((uint16_t)0)));
do
{
if (1 == 1)
{
if (1 == 1 || 1 == 4)
{
int ret = rpc_cli_msg_to_buf_rpc_ref_array_uint32_t_uint8_t_32_t(var0, (uint8_t *)((uint8_t *)msg_ipc->msg_buf), off);
if (ret < 0)
{
return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret)});
}
off = ret;
}
}
} while (0);
do
{
if (1 == 2)
{
if (1 == 1 || 1 == 4)
{
int ret = rpc_cli_msg_to_buf_rpc_ref_array_uint32_t_uint8_t_32_t(var0, (uint8_t *)((uint8_t *)msg_ipc->map_buf), off_buf);
if (ret < 0)
{
return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret)});
}
off_buf = ret;
}
}
} while (0);
do
{
if (2 == 1)
{
if (1 == 1 || 1 == 4)
{
int ret = rpc_cli_msg_to_buf_rpc_obj_handler_t_t(var1, (uint8_t *)((uint8_t *)msg_ipc->msg_buf), off);
if (ret < 0)
{
return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret)});
}
off = ret;
}
}
} while (0);
do
{
if (2 == 2)
{
if (1 == 1 || 1 == 4)
{
int ret = rpc_cli_msg_to_buf_rpc_obj_handler_t_t(var1, (uint8_t *)((uint8_t *)msg_ipc->map_buf), off_buf);
if (ret < 0)
{
return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret)});
}
off_buf = ret;
}
}
} while (0);
msg_tag_t tag = thread_ipc_call(((msg_tag_t){.flags = (0), .msg_buf_len = ((((off) / ((sizeof(void *)))) + (((off) % ((sizeof(void *)))) ? 1 : 0))), .map_buf_len = ((((off_buf) / ((sizeof(void *)))) + (((off_buf) % ((sizeof(void *)))) ? 1 : 0))), .prot = (0)}), hd, ipc_timeout_create2(0, 0));
if (((int16_t)((tag).prot)) < 0)
{
return tag;
}
off = 0;
do
{
if (1 == 1)
{
if (1 == 2 || 1 == 4)
{
int ret = rpc_cli_buf_to_msg_rpc_ref_array_uint32_t_uint8_t_32_t(var0, (uint8_t *)((uint8_t *)msg_ipc->msg_buf), off, tag.msg_buf_len * (sizeof(void *)));
if (ret < 0)
{
return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret)});
}
off = ret;
}
}
} while (0);
do
{
if (2 == 1)
{
if (1 == 2 || 1 == 4)
{
int ret = rpc_cli_buf_to_msg_rpc_obj_handler_t_t(var1, (uint8_t *)((uint8_t *)msg_ipc->msg_buf), off, tag.msg_buf_len * (sizeof(void *)));
if (ret < 0)
{
return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret)});
}
off = ret;
}
}
} while (0);
return tag;
}
RPC_GENERATION_CALL2(ns_t, NS_QUERY_OP, query,
rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_INOUT, RPC_TYPE_BUF, cli_hd)

View File

@@ -24,10 +24,124 @@ RPC_GENERATION_OP2(ns_t, NS_REGISTER_OP, register,
}
return ret;
}
RPC_GENERATION_DISPATCH2(ns_t, NS_REGISTER_OP, register,
rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, svr_hd)
msg_tag_t ns_t_register_dispatch(ns_t *obj, msg_tag_t tag, ipc_msg_t *ipc_msg)
{
rpc_array_uint32_t_uint8_t_32_t var0;
rpc_obj_handler_t_t var1;
size_t op_val;
uint8_t *value = (uint8_t *)(ipc_msg->msg_buf);
int off = 0;
rpc_var_rpc_array_uint32_t_uint8_t_32_t_init(&var0);
rpc_var_rpc_obj_handler_t_t_init(&var1);
op_val = *((typeof(((uint16_t)0)) *)value);
if (op_val != ((uint16_t)0))
{
return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (-100)});
}
off += sizeof(typeof(((uint16_t)0)));
off = rpc_align(off, __alignof(typeof(((uint16_t)0))));
do
{
if (1 == 1)
{
if (1 == 1 || 1 == 4)
{
int ret = rpc_svr_buf_to_msg_rpc_array_uint32_t_uint8_t_32_t(&var0, (uint8_t *)(value), off, tag.msg_buf_len * (sizeof(void *)));
if (ret < 0)
{
return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret)});
}
off = ret;
}
}
} while (0);
do
{
if (2 == 1)
{
if (1 == 1 || 1 == 4)
{
int ret = rpc_svr_buf_to_msg_rpc_obj_handler_t_t(&var1, (uint8_t *)(value), off, tag.msg_buf_len * (sizeof(void *)));
if (ret < 0)
{
return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret)});
}
off = ret;
}
}
} while (0);
short ret_val = ns_t_register_op(obj, &var0, &var1);
if (ret_val < 0)
{
return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret_val)});
}
off = 0;
int off_map = 0;
do
{
if (1 == 1)
{
if (1 == 2 || 1 == 4)
{
int ret = rpc_svr_msg_to_buf_rpc_array_uint32_t_uint8_t_32_t(&var0, (uint8_t *)(value), off);
if (ret < 0)
{
return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret)});
}
off = ret;
}
}
} while (0);
do
{
if (2 == 1)
{
if (1 == 2 || 1 == 4)
{
int ret = rpc_svr_msg_to_buf_rpc_obj_handler_t_t(&var1, (uint8_t *)(value), off);
if (ret < 0)
{
return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret)});
}
off = ret;
}
}
} while (0);
do
{
if (1 == 2)
{
if (1 == 2 || 1 == 4)
{
int ret = rpc_svr_msg_to_buf_rpc_array_uint32_t_uint8_t_32_t(&var0, (uint8_t *)(ipc_msg->map_buf), off_map);
if (ret < 0)
{
return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret)});
}
off_map = ret;
}
}
} while (0);
do
{
if (2 == 2)
{
if (1 == 2 || 1 == 4)
{
int ret = rpc_svr_msg_to_buf_rpc_obj_handler_t_t(&var1, (uint8_t *)(ipc_msg->map_buf), off_map);
if (ret < 0)
{
return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret)});
}
off_map = ret;
}
}
} while (0);
return ((msg_tag_t){.flags = (0), .msg_buf_len = ((((off) / ((sizeof(void *)))) + (((off) % ((sizeof(void *)))) ? 1 : 0))), .map_buf_len = ((((off_map) / ((sizeof(void *)))) + (((off_map) % ((sizeof(void *)))) ? 1 : 0))), .prot = (ret_val)});
}
// RPC_GENERATION_DISPATCH2(ns_t, NS_REGISTER_OP, register,
// rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
// rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, svr_hd)
RPC_GENERATION_OP2(ns_t, NS_QUERY_OP, query,
rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path,

View File

@@ -31,8 +31,8 @@
RPC_CLI_MSG_TO_BUF_IN(rpc_type0, cli_type0, var0, dir0, (uint8_t *)msg_ipc->msg_buf, off); \
PRC_CLI_FILL_MAP_BUF(rpc_type0, cli_type0, var0, dir0, (uint8_t *)msg_ipc->map_buf, off_map); \
/*msg_tag_t tag = dispatch_test(msg_tag_init4(0, ROUND_UP(off, WORD_BYTES), ROUND_UP(off_map, WORD_BYTES), 0), msg_ipc);*/ \
msg_tag_t tag = ipc_call(hd, msg_tag_init4(0, ROUND_UP(off, WORD_BYTES), ROUND_UP(off_map, WORD_BYTES), 0), \
ipc_timeout_create2(0, 0)); \
msg_tag_t tag = thread_ipc_call(msg_tag_init4(0, ROUND_UP(off, WORD_BYTES), ROUND_UP(off_map, WORD_BYTES), 0), hd, \
ipc_timeout_create2(0, 0)); \
\
if (msg_tag_get_val(tag) < 0) \
{ \
@@ -82,5 +82,3 @@
*/
#define RPC_GENERATION_OP1(struct_type, op, func_name, cli_type0, svr_type0, dir0, rpc_type0, name0) \
short struct_type##_##func_name##_op(struct_type *obj, svr_type0 *name0)

View File

@@ -32,8 +32,8 @@
RPC_CLI_MSG_TO_BUF_IN(rpc_type1, cli_type1, var1, dir1, (uint8_t *)msg_ipc->msg_buf, off); \
PRC_CLI_FILL_MAP_BUF(rpc_type1, cli_type1, var1, dir1, (uint8_t *)msg_ipc->map_buf, off_buf); \
/*msg_tag_t tag = dispatch_test(msg_tag_init4(0, ROUND_UP(off, WORD_BYTES), ROUND_UP(off_buf, WORD_BYTES), 0), msg_ipc); */ \
msg_tag_t tag = ipc_call(hd, msg_tag_init4(0, ROUND_UP(off, WORD_BYTES), ROUND_UP(off_buf, WORD_BYTES), 0), \
ipc_timeout_create2(0, 0)); \
msg_tag_t tag = thread_ipc_call(msg_tag_init4(0, ROUND_UP(off, WORD_BYTES), ROUND_UP(off_buf, WORD_BYTES), 0), hd, \
ipc_timeout_create2(0, 0)); \
\
if (msg_tag_get_val(tag) < 0) \
{ \

View File

@@ -35,8 +35,8 @@
RPC_CLI_MSG_TO_BUF_IN(rpc_type2, cli_type2, var2, dir2, (uint8_t *)msg_ipc->msg_buf, off); \
PRC_CLI_FILL_MAP_BUF(rpc_type2, cli_type2, var2, dir2, (uint8_t *)msg_ipc->map_buf, off_buf); \
/*msg_tag_t tag = dispatch_test(msg_tag_init4(0, ROUND_UP(off, WORD_BYTES), ROUND_UP(off_buf, WORD_BYTES), 0), msg_ipc); */ \
msg_tag_t tag = ipc_call(hd, msg_tag_init4(0, ROUND_UP(off, WORD_BYTES), ROUND_UP(off_buf, WORD_BYTES), 0), \
ipc_timeout_create2(0, 0)); \
msg_tag_t tag = thread_ipc_call(msg_tag_init4(0, ROUND_UP(off, WORD_BYTES), ROUND_UP(off_buf, WORD_BYTES), 0), hd, \
ipc_timeout_create2(0, 0)); \
\
if (msg_tag_get_val(tag) < 0) \
{ \
@@ -101,4 +101,3 @@
cli_type1, svr_type1, dir1, rpc_type1, name1, \
cli_type2, svr_type2, dir2, rpc_type2, name2) \
short struct_type##_##func_name##_op(struct_type *obj, svr_type0 *name0, svr_type1 *name1, svr_type2 *name2)

View File

@@ -2,7 +2,7 @@
#include "u_types.h"
#include "u_prot.h"
#include "u_ipc.h"
#include "u_thread.h"
struct rpc_svr_obj;
typedef msg_tag_t (*rpc_dispatch_func)(struct rpc_svr_obj *obj, msg_tag_t tag, ipc_msg_t *msg);
@@ -20,4 +20,4 @@ static inline int rpc_svr_obj_init(rpc_svr_obj_t *obj, rpc_dispatch_func dis, mw
}
int rpc_creaite_bind_ipc(obj_handler_t th, void *obj, obj_handler_t *ipc_hd);
void rpc_loop(obj_handler_t ipc_hd, rpc_svr_obj_t *svr_obj);
void rpc_loop(void);

View File

@@ -3,5 +3,4 @@
#include "u_types.h"
#include <sys/types.h>
void u_sleep_init(void);
void u_sleep_ms(size_t ms);

View File

@@ -65,7 +65,6 @@ int app_load(const char *name, uenv_t *cur_env)
umword_t ram_base;
obj_handler_t hd_task = handler_alloc();
obj_handler_t hd_thread = handler_alloc();
// obj_handler_t hd_ipc = handler_alloc();
if (hd_task == HANDLER_INVALID)
{
@@ -75,10 +74,6 @@ int app_load(const char *name, uenv_t *cur_env)
{
goto end;
}
// if (hd_ipc == HANDLER_INVALID)
// {
// goto end;
// }
tag = factory_create_task(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, hd_task));
if (msg_tag_get_prot(tag) < 0)
@@ -90,13 +85,6 @@ int app_load(const char *name, uenv_t *cur_env)
{
goto end_del_obj;
}
// tag = factory_create_ipc(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, hd_ipc));
// if (msg_tag_get_prot(tag) < 0)
// {
// goto end_del_obj;
// }
// printf("ipc hd is %d\n", hd_ipc);
tag = task_alloc_ram_base(hd_task, app->i.ram_size, &ram_base);
if (msg_tag_get_prot(tag) < 0)
{
@@ -152,12 +140,6 @@ int app_load(const char *name, uenv_t *cur_env)
{
goto end_del_obj;
}
// tag = ipc_bind(hd_ipc, hd_thread, 0);
// if (msg_tag_get_prot(tag) < 0)
// {
// goto end_del_obj;
// }
void *sp_addr = (char *)ram_base + app->i.stack_offset - app->i.data_offset;
void *sp_addr_top = (char *)sp_addr + app->i.stack_size;
@@ -197,11 +179,6 @@ int app_load(const char *name, uenv_t *cur_env)
/*启动线程运行*/
tag = thread_run(hd_thread, 2);
assert(msg_tag_get_prot(tag) >= 0);
// umword_t len;
// thread_msg_buf_get(THREAD_MAIN, (umword_t *)(&buf), NULL);
// strcpy((char *)buf, "hello shell.\n");
// ipc_call(hd_ipc, msg_tag_init4(0, ROUND_UP(strlen((char *)buf), WORD_BYTES), 0, 0), ipc_timeout_create2(0, 0));
// printf("test ok\n");
return 0;
end_del_obj:
if (hd_task != HANDLER_INVALID)

View File

@@ -9,7 +9,6 @@ AUTO_CALL(101)
int u_drv_init(void)
{
msg_tag_t tag;
u_sleep_init();
tag = mm_align_alloc(MM_PROT, (void *)0x40000000, 0x50000000 - 0x40000000);
if (msg_tag_get_val(tag) < 0)

View File

@@ -45,9 +45,9 @@ int cli_ns_register(const char *name, obj_handler_t hd)
((char *)(&ipc_msg->msg_buf[2]))[IPC_MSG_SIZE - WORD_BYTES * 2 - 1] = 0;
// 发送ipc
tag = ipc_call(u_get_global_env()->ns_hd,
msg_tag_init4(0, 2 + ROUND_UP(len, WORD_BYTES), 1, 0),
ipc_timeout_create2(0, 0));
tag = thread_ipc_call(
msg_tag_init4(0, 2 + ROUND_UP(len, WORD_BYTES), 1, 0), u_get_global_env()->ns_hd,
ipc_timeout_create2(0, 0));
return msg_tag_get_val(tag);
}
int cli_ns_query(const char *name, obj_handler_t *ret_hd)
@@ -80,9 +80,9 @@ int cli_ns_query(const char *name, obj_handler_t *ret_hd)
((char *)(&ipc_msg->msg_buf[2]))[IPC_MSG_SIZE - WORD_BYTES * 2 - 1] = 0;
// 发送ipc
tag = ipc_call(u_get_global_env()->ns_hd,
msg_tag_init4(0, 2 + ROUND_UP(len, WORD_BYTES), 0, 0),
ipc_timeout_create2(0, 0));
tag = thread_ipc_call(
msg_tag_init4(0, 2 + ROUND_UP(len, WORD_BYTES), 0, 0), u_get_global_env()->ns_hd,
ipc_timeout_create2(0, 0));
if (msg_tag_get_val(tag) < 0)
{

View File

@@ -49,28 +49,28 @@ int rpc_creaite_bind_ipc(obj_handler_t th, void *obj, obj_handler_t *ret_ipc_hd)
* @param svr_obj
* @param dispatch
*/
void rpc_loop(obj_handler_t ipc_hd, rpc_svr_obj_t *svr_obj)
void rpc_loop(void)
{
umword_t obj;
msg_tag_t tag;
umword_t buf;
ipc_msg_t *msg;
assert(svr_obj);
rpc_svr_obj_t *svr_obj;
thread_msg_buf_get(-1, &buf, NULL);
msg = (ipc_msg_t *)buf;
while (1)
{
tag = ipc_wait(ipc_hd, &obj);
tag = thread_ipc_wait(ipc_timeout_create2(0, 0), &obj);
if (msg_tag_get_val(tag) < 0)
{
continue;
}
svr_obj = (rpc_svr_obj_t *)obj;
if (svr_obj->dispatch)
{
tag = svr_obj->dispatch(svr_obj, tag, msg);
}
ipc_reply(ipc_hd, tag);
thread_ipc_reply(tag, ipc_timeout_create2(0, 0));
}
}

View File

@@ -5,24 +5,12 @@
#include "u_arch.h"
#include "u_ipc.h"
#include "u_factory.h"
#include "u_thread.h"
#include <sys/types.h>
#include <assert.h>
static obj_handler_t hd = HANDLER_INVALID;
void u_sleep_init(void)
{
msg_tag_t tag;
if (hd != HANDLER_INVALID)
{
return;
}
hd = handler_alloc();
assert(hd != HANDLER_INVALID);
tag = factory_create_ipc(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, hd));
assert(msg_tag_get_val(tag) >= 0);
}
void u_sleep_ms(size_t ms)
{
ipc_send(hd, msg_tag_init4(0, 0, 0, 0), ipc_timeout_create2(ms / (1000 / SYS_SCHE_HZ), 0));
thread_ipc_wait(ipc_timeout_create2(0, ms / (1000 / SYS_SCHE_HZ)), NULL);
}

View File

@@ -8,10 +8,9 @@
#include <fcntl.h>
static fs_t fs;
void fs_svr_init(obj_handler_t ipc)
void fs_svr_init(void)
{
fs_init(&fs);
fs.ipc = ipc;
}
typedef struct file_desc
{
@@ -68,5 +67,5 @@ int fs_svr_fstat(int fd, stat_t *stat)
void fs_svr_loop(void)
{
rpc_loop(fs.ipc, &fs.svr);
rpc_loop(&fs.svr);
}

View File

@@ -1,4 +1,4 @@
#pragma once
#include <u_types.h>
void drv_svr_init(obj_handler_t ipc);
obj_handler_t drv_svr_init(void);
void drv_svr_loop(void);

View File

@@ -2,12 +2,19 @@
#include <mr_api.h>
#include <drv_types.h>
#include "drv_rpc.h"
#include <assert.h>
static drv_t drv;
static obj_handler_t ipc_hd;
void drv_svr_init(obj_handler_t ipc)
obj_handler_t drv_svr_init(void)
{
drv_init(&drv);
drv.ipc = ipc;
int ret;
printf("mr drv init...\n");
ret = rpc_creaite_bind_ipc(THREAD_MAIN, &drv, &ipc_hd);
assert(ret >= 0);
return ipc_hd;
}
int dev_open(const char *name, uint32_t oflags)
@@ -41,5 +48,5 @@ int dev_ioctl(int desc, int cmd, void *args)
void drv_svr_loop(void)
{
rpc_loop(drv.ipc, &drv.svr);
rpc_loop();
}

View File

@@ -9,16 +9,9 @@
#include <mr_api.h>
int main(int argc, char *args[])
{
obj_handler_t ipc_hd;
int ret;
printf("mr drv init...\n");
ret = rpc_creaite_bind_ipc(THREAD_MAIN, NULL, &ipc_hd);
assert(ret >= 0);
ns_register("/dev", ipc_hd);
ns_register("/dev", drv_svr_init());
printf("mr drv start success...\n");
mr_auto_init();
drv_svr_init(ipc_hd);
drv_svr_loop();
return 0;
}

View File

@@ -9,10 +9,9 @@
#include <errno.h>
static fs_t fs;
void fs_svr_init(obj_handler_t ipc)
void fs_svr_init(void)
{
fs_init(&fs);
fs.ipc = ipc;
}
typedef struct file_desc
{
@@ -308,5 +307,5 @@ int fs_svr_fstat(int fd, stat_t *stat)
void fs_svr_loop(void)
{
rpc_loop(fs.ipc, &fs.svr);
rpc_loop();
}

View File

@@ -1,6 +1,6 @@
#define HEAP_SIZE 0 * 1024
#define STACK_SIZE 1024 + 512
#define HEAP_SIZE 512
#define STACK_SIZE 2048
#if defined(__CC_ARM)
#define HEAP_ATTR SECTION("HEAP") __attribute__((zero_init))

View File

@@ -23,7 +23,6 @@ void drv_test(void)
int main(int argc, char *args[])
{
u_sleep_init();
u_sleep_ms(100);
// printf("Hello world.\n");
ulog_write_str(u_get_global_env()->log_hd, "hello is runing...\n");

View File

@@ -29,7 +29,6 @@ int main(int argc, char *args[])
thread_test();
thread_exit_test();
map_test();
ipc_timeout_test();
mm_test();
app_test();
mpu_test();
@@ -37,15 +36,14 @@ int main(int argc, char *args[])
kobj_create_press_test();
pthread_cond_lock_test();
pthread_lock_test();
#endif
u_sleep_ms(1000);
ipc_test();
ipc_obj_test();
#endif
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;
namespace_init(ipc_hd);
u_sleep_init();
env.ns_hd = namespace_init();
int ret;
ret = ret;
// ret = app_load("mr_drv", &env);
// if (ret < 0)
// {
@@ -77,8 +75,5 @@ int main(int argc, char *args[])
namespace_pre_alloc_map_fd();
namespace_loop();
// task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, TASK_THIS)); // 删除当前task以及申请得所有对象
// printf("exit init.\n");
// ulog_write_str(LOG_PROT, "app load fail.\n");
return 0;
}

View File

@@ -9,12 +9,18 @@
#include "ns_types.h"
#include "ns_svr.h"
#include "namespace.h"
static ns_t ns;
void namespace_init(obj_handler_t ipc)
static ns_t ns;
static obj_handler_t ipc_hd;
obj_handler_t namespace_init(void)
{
int ret;
ns_init(&ns);
ns.ipc_hd = ipc;
printf("ns svr init...\n");
ret = rpc_creaite_bind_ipc(THREAD_MAIN, &ns, &ipc_hd);
assert(ret >= 0);
return ipc_hd;
}
static int namespace_alloc(const char *path, obj_handler_t hd)
@@ -95,5 +101,5 @@ int namespace_pre_alloc_map_fd(void)
void namespace_loop(void)
{
rpc_loop(ns.ipc_hd, &ns.svr);
rpc_loop();
}

View File

@@ -2,7 +2,7 @@
#include "u_types.h"
#include "u_prot.h"
void namespace_init(obj_handler_t ipc);
obj_handler_t namespace_init(void);
int namespace_register(const char *path, obj_handler_t hd);
int namespace_query(const char *path, obj_handler_t *hd);
// msg_tag_t ns_dispatch(ipc_msg_t *msg);

View File

@@ -114,6 +114,6 @@ void app_test(void)
umword_t len;
thread_msg_buf_get(THREAD_MAIN, (umword_t *)(&buf), NULL);
strcpy((char *)buf, "hello shell.\n");
ipc_call(hd_ipc, msg_tag_init4(0, ROUND_UP(strlen((char *)buf), WORD_BYTES), 0, 0), ipc_timeout_create2(0, 0));
thread_ipc_call(msg_tag_init4(0, ROUND_UP(strlen((char *)buf), WORD_BYTES), 0, 0), hd_ipc, ipc_timeout_create2(0, 0));
printf("test ok\n");
}

View File

@@ -0,0 +1,137 @@
#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 "u_sleep.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#define DEBUG_IPC_CALL 1
static obj_handler_t th1_hd = 0;
static obj_handler_t th2_hd = 0;
static obj_handler_t th3_hd = 0;
static obj_handler_t ipc_hd = 0;
static char msg_buf0[MSG_BUG_LEN];
static char msg_buf1[MSG_BUG_LEN];
static char msg_buf2[MSG_BUG_LEN];
#define STACK_SIZE 1024
static __attribute__((aligned(8))) uint8_t stack0[STACK_SIZE];
static __attribute__((aligned(8))) uint8_t stack1[STACK_SIZE];
static __attribute__((aligned(8))) uint8_t stack2[STACK_SIZE];
static void hard_sleep(void)
{
for (volatile int i; i < 10000000; i++)
;
}
static void thread_test_func(void)
{
char *buf;
umword_t len;
thread_msg_buf_get(th1_hd, (umword_t *)(&buf), NULL);
u_sleep_ms(100);
ipc_bind(ipc_hd, th1_hd, 0);
while (1)
{
thread_ipc_wait(ipc_timeout_create2(0, 0), NULL);
printf("srv recv:%s", buf);
hard_sleep();
buf[0] = '_';
thread_ipc_reply(msg_tag_init4(0, ROUND_UP(strlen(buf), WORD_BYTES), 0, 0), ipc_timeout_create2(0, 0));
}
printf("thread_test_func.\n");
task_unmap(TASK_PROT, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th1_hd));
printf("Error\n");
}
static void thread_test_func2(void)
{
char *buf;
umword_t len;
thread_msg_buf_get(th2_hd, (umword_t *)(&buf), NULL);
while (1)
{
strcpy(buf, "I am th2.\n");
thread_ipc_call(msg_tag_init4(0, ROUND_UP(strlen(buf), WORD_BYTES), 0, 0), ipc_hd, ipc_timeout_create2(0, 0));
printf("th2:%s", buf);
}
printf("thread_test_func2.\n");
task_unmap(TASK_PROT, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th2_hd));
printf("Error\n");
}
static void thread_test_func3(void)
{
char *buf;
umword_t len;
thread_msg_buf_get(th3_hd, (umword_t *)(&buf), &len);
memset(buf, 0, len);
while (1)
{
strcpy(buf, "I am th3.\n");
thread_ipc_call(msg_tag_init4(0, ROUND_UP(strlen(buf), WORD_BYTES), 0, 0), ipc_hd, ipc_timeout_create2(0, 0));
printf("th3:%s", buf);
}
printf("thread_test_func2.\n");
task_unmap(TASK_PROT, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th3_hd));
printf("Error\n");
}
/**
* @brief 启动两个线程并进行ipc测试
*
*/
void ipc_obj_test(void)
{
msg_tag_t tag;
th1_hd = handler_alloc();
assert(th1_hd != HANDLER_INVALID);
th2_hd = handler_alloc();
assert(th2_hd != HANDLER_INVALID);
th3_hd = handler_alloc();
assert(th3_hd != HANDLER_INVALID);
ipc_hd = handler_alloc();
assert(ipc_hd != HANDLER_INVALID);
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_msg_buf_set(th1_hd, msg_buf0);
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);
assert(msg_tag_get_prot(tag) >= 0);
tag = factory_create_thread(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, th2_hd));
assert(msg_tag_get_prot(tag) >= 0);
tag = thread_msg_buf_set(th2_hd, msg_buf1);
assert(msg_tag_get_prot(tag) >= 0);
tag = thread_exec_regs(th2_hd, (umword_t)thread_test_func2, (umword_t)stack1 + STACK_SIZE, RAM_BASE(), 0);
assert(msg_tag_get_prot(tag) >= 0);
tag = thread_bind_task(th2_hd, TASK_THIS);
assert(msg_tag_get_prot(tag) >= 0);
tag = thread_run(th2_hd, 2);
assert(msg_tag_get_prot(tag) >= 0);
assert(msg_tag_get_prot(tag) >= 0);
tag = factory_create_thread(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, th3_hd));
assert(msg_tag_get_prot(tag) >= 0);
tag = thread_msg_buf_set(th3_hd, msg_buf2);
assert(msg_tag_get_prot(tag) >= 0);
tag = thread_exec_regs(th3_hd, (umword_t)thread_test_func3, (umword_t)stack2 + STACK_SIZE, RAM_BASE(), 0);
assert(msg_tag_get_prot(tag) >= 0);
tag = thread_bind_task(th3_hd, TASK_THIS);
assert(msg_tag_get_prot(tag) >= 0);
tag = thread_run(th3_hd, 2);
assert(msg_tag_get_prot(tag) >= 0);
}

View File

@@ -14,7 +14,6 @@
static umword_t th1_hd = 0;
static umword_t th2_hd = 0;
static umword_t th3_hd = 0;
static umword_t ipc_hd = 0;
static char msg_buf0[MSG_BUG_LEN];
static char msg_buf1[MSG_BUG_LEN];
@@ -72,6 +71,7 @@ static void hard_sleep(void)
for (volatile int i; i < 1000000000; i++)
;
}
#include <u_sleep.h>
static void thread_test_func(void)
{
char *buf;
@@ -79,9 +79,11 @@ static void thread_test_func(void)
thread_msg_buf_get(th1_hd, (umword_t *)(&buf), NULL);
while (1)
{
thread_ipc_wait();
thread_ipc_wait(ipc_timeout_create2(0, 0), NULL);
printf("srv recv:%s", buf);
hard_sleep();
// u_sleep_ms(10);
buf[0] = ',';
thread_ipc_reply(msg_tag_init4(0, ROUND_UP(strlen(buf), WORD_BYTES), 0, 0), ipc_timeout_create2(0, 0));
}
printf("thread_test_func.\n");
@@ -137,7 +139,6 @@ void ipc_test(void)
tag = factory_create_thread(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, th1_hd));
assert(msg_tag_get_prot(tag) >= 0);
ipc_bind(ipc_hd, th1_hd, 0);
tag = thread_msg_buf_set(th1_hd, msg_buf0);
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);
@@ -170,7 +171,3 @@ void ipc_test(void)
tag = thread_run(th3_hd, 2);
assert(msg_tag_get_prot(tag) >= 0);
}
void ipc_timeout_test(void)
{
}

View File

@@ -15,7 +15,6 @@
static umword_t th1_hd = 0;
static umword_t th2_hd = 0;
static umword_t ipc_hd = 0;
static char msg_buf0[MSG_BUG_LEN];
static char msg_buf1[MSG_BUG_LEN];
@@ -38,11 +37,11 @@ static void thread_test_func(void)
thread_msg_buf_get(th1_hd, (umword_t *)(&buf), NULL);
ipc_msg = (ipc_msg_t *)buf;
ipc_msg->map_buf[0] = vpage_create_raw3(0, 0, log_hd).raw;
ipc_wait(ipc_hd, 0);
thread_ipc_wait(ipc_timeout_create2(0, 0), NULL);
printf("srv recv:%s", buf);
ulog_write_str(log_hd, "map test success.\n");
hard_sleep();
ipc_reply(ipc_hd, msg_tag_init4(0, ROUND_UP(strlen(buf), WORD_BYTES), 0, 0));
thread_ipc_reply(msg_tag_init4(0, ROUND_UP(strlen(buf), WORD_BYTES), 0, 0), ipc_timeout_create2(0, 0));
printf("thread_test_func.\n");
handler_free(log_hd);
task_unmap(TASK_PROT, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th1_hd));
@@ -58,7 +57,7 @@ static void thread_test_func2(void)
ipc_msg = (ipc_msg_t *)buf;
strcpy((char *)(ipc_msg->msg_buf), "I am th2.\n");
ipc_msg->map_buf[0] = vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, LOG_PROT).raw;
ipc_call(ipc_hd, msg_tag_init4(0, ROUND_UP(strlen((char *)(ipc_msg->msg_buf)), WORD_BYTES), 1, 0), ipc_timeout_create2(0, 0));
thread_ipc_call(msg_tag_init4(0, ROUND_UP(strlen((char *)(ipc_msg->msg_buf)), WORD_BYTES), 1, 0), th1_hd, ipc_timeout_create2(0, 0));
printf("th2:%s", buf);
printf("thread_test_func2.\n");
task_unmap(TASK_PROT, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th2_hd));
@@ -75,11 +74,9 @@ void map_test(void)
th2_hd = handler_alloc();
assert(th2_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);
msg_tag_t tag;
tag = factory_create_thread(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, th1_hd));
assert(msg_tag_get_prot(tag) >= 0);
ipc_bind(ipc_hd, th1_hd, 0);
tag = thread_msg_buf_set(th1_hd, msg_buf0);
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);

View File

@@ -11,7 +11,7 @@ void printf_test(void);
void ipc_test(void);
void thread_exit_test(void);
void map_test(void);
void ipc_timeout_test(void);
void ipc_obj_test(void);
void irq_test(void);
void thread_press_test(void);
void kobj_create_press_test(void);

View File

@@ -6,12 +6,8 @@
#include "u_task.h"
#include "u_ipc.h"
#include "u_hd_man.h"
#include "u_sleep.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);
u_sleep_ms(tick);
}