ipc支持send
This commit is contained in:
@@ -33,13 +33,16 @@ static inline mword_t slist_is_empty(slist_head_t *list)
|
||||
*/
|
||||
static inline bool_t slist_in_list(slist_head_t *item)
|
||||
{
|
||||
if (slist_is_empty(item)) {
|
||||
if (slist_is_empty(item))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (item->prev->next != item) {
|
||||
if (item->prev->next != item)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (item->next->prev != item) {
|
||||
if (item->next->prev != item)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
@@ -59,9 +62,9 @@ static inline void slist_add(slist_head_t *head, slist_head_t *item)
|
||||
}
|
||||
static inline void slist_add_append(slist_head_t *head, slist_head_t *item)
|
||||
{
|
||||
slist_head_t *tail = head->prev;
|
||||
slist_head_t *tail = head->prev;
|
||||
|
||||
return slist_add(tail, item);
|
||||
return slist_add(tail, item);
|
||||
}
|
||||
/**
|
||||
* @brief 获取第一个节点
|
||||
@@ -93,5 +96,14 @@ static inline void slist_del(slist_head_t *item)
|
||||
/**
|
||||
* @brief 遍历每一个节点获得struct的入口
|
||||
*/
|
||||
#define slist_foreach(pos, head, member) \
|
||||
for (pos = slist_entry((head)->next, typeof(*pos), member); &(pos)->member != (head) && !slist_is_empty(head); pos = slist_entry((pos)->member.next, typeof(*pos), member))
|
||||
#define slist_foreach(pos, head, member) \
|
||||
for (pos = slist_entry((head)->next, typeof(*pos), member); \
|
||||
&(pos)->member != (head) && !slist_is_empty(head); \
|
||||
pos = slist_entry((pos)->member.next, typeof(*pos), member))
|
||||
|
||||
#define slist_foreach_not_next(pos, head, member) \
|
||||
for (pos = slist_entry((head)->next, typeof(*pos), member); \
|
||||
&(pos)->member != (head) && !slist_is_empty(head);)
|
||||
|
||||
#define slist_next_entry(pos, head, member) \
|
||||
slist_entry((pos)->member.next, typeof(*pos), member)
|
||||
|
||||
@@ -54,6 +54,7 @@ enum ipc_op
|
||||
IPC_REPLY, //!< 服务端回复信息
|
||||
IPC_BIND, //!< 绑定服务端线程
|
||||
IPC_UNBIND, //!< 解除绑定
|
||||
IPC_SEND, //!<
|
||||
};
|
||||
static int wake_up_th(ipc_t *ipc);
|
||||
static slist_head_t wait_list;
|
||||
@@ -94,7 +95,10 @@ void timeout_times_tick(void)
|
||||
else
|
||||
{
|
||||
//!< 超时时间满后直接唤醒等待者
|
||||
thread_ready(item->th, TRUE);
|
||||
if (item->th->status == THREAD_SUSPEND)
|
||||
{
|
||||
thread_ready(item->th, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
spinlock_set(&ipc->lock, status);
|
||||
@@ -150,11 +154,9 @@ static void ipc_wait_item_init(ipc_wait_item_t *item, ipc_t *ipc, thread_t *th,
|
||||
* @param head
|
||||
* @param th
|
||||
* @param times 超时时间,为0代表一直超时
|
||||
* @param lock
|
||||
* @param status
|
||||
* @return int
|
||||
*/
|
||||
static int add_wait_unlock(ipc_t *ipc, slist_head_t *head, thread_t *th, umword_t times, spinlock_t *lock, int status)
|
||||
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;
|
||||
@@ -169,8 +171,9 @@ static int add_wait_unlock(ipc_t *ipc, slist_head_t *head, thread_t *th, umword_
|
||||
}
|
||||
slist_add_append(head, &item.node);
|
||||
thread_suspend(th);
|
||||
spinlock_set(lock, status);
|
||||
preemption();
|
||||
slist_del(&item.node);
|
||||
// spinlock_set(lock, status);
|
||||
if (times)
|
||||
{
|
||||
if (slist_is_empty(head))
|
||||
@@ -204,7 +207,10 @@ static int wake_up_th(ipc_t *ipc)
|
||||
}
|
||||
else
|
||||
{
|
||||
thread_ready(item->th, TRUE);
|
||||
if (item->th->status == THREAD_SUSPEND)
|
||||
{
|
||||
thread_ready(item->th, TRUE);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -275,14 +281,15 @@ static msg_tag_t ipc_call(ipc_t *ipc, thread_t *th, entry_frame_t *f, msg_tag_t
|
||||
msg_tag_t tmp_tag;
|
||||
|
||||
assert(th != ipc->svr_th);
|
||||
__check:
|
||||
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, &ipc->lock, status);
|
||||
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;
|
||||
@@ -298,16 +305,51 @@ __check:
|
||||
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, &ipc->lock, status);
|
||||
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);
|
||||
}
|
||||
// spinlock_set(&ipc->lock, status);
|
||||
tmp_tag = th->msg.tag;
|
||||
// ipc->last_cli_th = NULL;
|
||||
spinlock_set(&ipc->lock, status);
|
||||
return tmp_tag;
|
||||
}
|
||||
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;
|
||||
}
|
||||
/**
|
||||
@@ -327,6 +369,11 @@ static int ipc_reply(ipc_t *ipc, thread_t *th, entry_frame_t *f, msg_tag_t tag)
|
||||
}
|
||||
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); //!< 拷贝数据
|
||||
|
||||
@@ -428,6 +475,24 @@ static void ipc_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag,
|
||||
}
|
||||
}
|
||||
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
|
||||
@@ -530,6 +595,7 @@ 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);
|
||||
spinlock_init(&ipc->lock);
|
||||
ipc->lim = lim;
|
||||
ipc->svr_th = NULL;
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
/**
|
||||
* @file syscall.c
|
||||
* @author zhangzheng (1358745329@qq.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-11-19
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
#include "types.h"
|
||||
#include "syscall.h"
|
||||
#include "thread.h"
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <pthread.h>
|
||||
#include <futex.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#define FT_NR 16
|
||||
|
||||
static obj_handler_t hd_futex_ipc;
|
||||
@@ -110,13 +111,65 @@ static futex_lock_t *futex_find(futex_t *ft, void *uaddr)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
void futex_svr_thread(void)
|
||||
|
||||
static void futex_svr_thread(void)
|
||||
{
|
||||
ipc_msg_t *msg;
|
||||
uint32_t *uaddr;
|
||||
int futex_op;
|
||||
uint32_t val;
|
||||
const struct timespec *timeout; /*or val2*/
|
||||
uint32_t uaddr2;
|
||||
uint32_t val3;
|
||||
|
||||
ulog_write_str(LOG_PROT, "futex running..\n");
|
||||
thread_msg_buf_get(-1, (umword_t *)(&msg), NULL);
|
||||
while (1)
|
||||
{
|
||||
ipc_wait(hd_futex_ipc, 0);
|
||||
/*TODO:处理锁信息*/
|
||||
uaddr = (uint32_t *)(msg->msg_buf[0]);
|
||||
futex_op = msg->msg_buf[1];
|
||||
val = msg->msg_buf[2];
|
||||
timeout = (const struct timespec *)(msg->msg_buf[3]); /*or val2*/
|
||||
uaddr2 = msg->msg_buf[4];
|
||||
val3 = msg->msg_buf[5];
|
||||
|
||||
futex_op = futex_op & 0x7f;
|
||||
switch (futex_op)
|
||||
{
|
||||
case FUTEX_REQUEUE:
|
||||
{
|
||||
if (val3 == *uaddr)
|
||||
{
|
||||
futex_lock_t *flt = futex_find(&ft, uaddr);
|
||||
int rel_cnt = 0;
|
||||
int wake_cnt = 0;
|
||||
|
||||
if (flt)
|
||||
{
|
||||
wake_cnt = val = INT_MAX ? fq_queue_len(&flt->fqt) : val;
|
||||
|
||||
for (int i = 0; i < wake_cnt; i++)
|
||||
{
|
||||
obj_handler_t hd;
|
||||
int ret = fq_dequeue(&flt->fqt, &hd);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (fq_queue_len(&flt->fqt) == 0)
|
||||
{
|
||||
flt->uaddr = 0;
|
||||
}
|
||||
/*TODO: ipc_send()*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ipc_reply(hd_futex_ipc, msg_tag_init4(0, 0, 0, 0));
|
||||
}
|
||||
@@ -135,7 +188,9 @@ int be_futex(uint32_t *uaddr, int futex_op, uint32_t val,
|
||||
total = timeout->tv_sec * 1000 + timeout->tv_nsec / 1000 / 1000;
|
||||
}
|
||||
umword_t st_val;
|
||||
ipc_msg_t *msg = (ipc_msg_t *)futex_thread_msg_bug;
|
||||
ipc_msg_t *msg;
|
||||
|
||||
thread_msg_buf_get(-1, (umword_t *)(&msg), NULL);
|
||||
|
||||
msg->msg_buf[0] = (umword_t)uaddr;
|
||||
msg->msg_buf[1] = (umword_t)futex_op;
|
||||
|
||||
@@ -51,6 +51,7 @@ 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 */
|
||||
#define EWTIMEDOUT 131 /* Connection timed out */
|
||||
#define ERTIMEDOUT 132 /* Connection timed out */
|
||||
|
||||
@@ -11,18 +11,19 @@ enum ipc_op
|
||||
IPC_REPLY, //!< 服务端回复信息
|
||||
IPC_BIND, //!< 绑定服务端线程
|
||||
IPC_UNBIND, //!< 解除绑定
|
||||
IPC_SEND, //!< 发送数据
|
||||
};
|
||||
msg_tag_t ipc_bind(obj_handler_t obj, obj_handler_t tag_th, 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,
|
||||
user_obj,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
0,
|
||||
tag_th,
|
||||
user_obj,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
asm __volatile__(""
|
||||
:
|
||||
:
|
||||
@@ -37,12 +38,12 @@ msg_tag_t ipc_wait(obj_handler_t obj, umword_t *user_obj)
|
||||
register volatile umword_t r1 asm("r1");
|
||||
|
||||
mk_syscall(syscall_prot_create(IPC_WAIT, IPC_PROT, obj).raw,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
asm __volatile__(""
|
||||
:
|
||||
:
|
||||
@@ -58,12 +59,12 @@ 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);
|
||||
in_tag.raw,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
asm __volatile__(""
|
||||
:
|
||||
:
|
||||
@@ -77,12 +78,12 @@ 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);
|
||||
in_tag.raw,
|
||||
timeout.raw,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
asm __volatile__(""
|
||||
:
|
||||
:
|
||||
@@ -90,4 +91,23 @@ msg_tag_t ipc_call(obj_handler_t obj, msg_tag_t in_tag, ipc_timeout_t timeout)
|
||||
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__(""
|
||||
:
|
||||
:
|
||||
: "r0");
|
||||
msg_tag_t tag = msg_tag_init(r0);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@@ -24,5 +24,5 @@ void u_sleep_init(void)
|
||||
|
||||
void u_sleep_ms(size_t ms)
|
||||
{
|
||||
ipc_call(hd, msg_tag_init4(0, 0, 0, 0), ipc_timeout_create2(ms / (1000 / SYS_SCHE_HZ), 0));
|
||||
ipc_send(hd, msg_tag_init4(0, 0, 0, 0), ipc_timeout_create2(ms / (1000 / SYS_SCHE_HZ), 0));
|
||||
}
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
extern void futex_init(void);
|
||||
int main(int argc, char *args[])
|
||||
{
|
||||
fs_backend_init();
|
||||
// futex_init();
|
||||
ulog_write_str(LOG_PROT, "init..\n");
|
||||
#if 0
|
||||
ulog_test();
|
||||
@@ -35,9 +33,9 @@ int main(int argc, char *args[])
|
||||
mm_test();
|
||||
app_test();
|
||||
mpu_test();
|
||||
ipc_test();
|
||||
thread_press_test();
|
||||
kobj_create_press_test();
|
||||
ipc_test();
|
||||
#endif
|
||||
uenv_t env = *u_get_global_env();
|
||||
obj_handler_t ipc_hd;
|
||||
|
||||
@@ -98,6 +98,7 @@ static void thread_test_func2(void)
|
||||
strcpy(buf, "I am th2.\n");
|
||||
ipc_call(ipc_hd, msg_tag_init4(0, ROUND_UP(strlen(buf), WORD_BYTES), 0, 0), ipc_timeout_create2(0, 0));
|
||||
printf("th2:%s", buf);
|
||||
// hard_sleep();
|
||||
}
|
||||
printf("thread_test_func2.\n");
|
||||
task_unmap(TASK_PROT, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th2_hd));
|
||||
@@ -108,12 +109,14 @@ static void thread_test_func3(void)
|
||||
{
|
||||
char *buf;
|
||||
umword_t len;
|
||||
thread_msg_buf_get(th3_hd, (umword_t *)(&buf), NULL);
|
||||
thread_msg_buf_get(th3_hd, (umword_t *)(&buf), &len);
|
||||
memset(buf, 0, len);
|
||||
while (1)
|
||||
{
|
||||
strcpy(buf, "I am th3.\n");
|
||||
ipc_call(ipc_hd, msg_tag_init4(0, ROUND_UP(strlen(buf), WORD_BYTES), 0, 0), ipc_timeout_create2(0, 0));
|
||||
printf("th3:%s", buf);
|
||||
// hard_sleep();
|
||||
}
|
||||
printf("thread_test_func2.\n");
|
||||
task_unmap(TASK_PROT, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th3_hd));
|
||||
|
||||
Reference in New Issue
Block a user