优化ipc流程
This commit is contained in:
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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__(""
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -5,5 +5,4 @@
|
||||
typedef struct drv
|
||||
{
|
||||
rpc_svr_obj_t svr;
|
||||
obj_handler_t ipc;
|
||||
} drv_t;
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
typedef struct fs
|
||||
{
|
||||
rpc_svr_obj_t svr;
|
||||
obj_handler_t ipc;
|
||||
} fs_t;
|
||||
|
||||
void fs_init(fs_t *fs);
|
||||
|
||||
@@ -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;
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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) \
|
||||
{ \
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -3,5 +3,4 @@
|
||||
#include "u_types.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
void u_sleep_init(void);
|
||||
void u_sleep_ms(size_t ms);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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))
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
137
mkrtos_user/server/init/src/test/ipc_obj_test.c
Normal file
137
mkrtos_user/server/init/src/test/ipc_obj_test.c
Normal 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);
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user