添加服务端并发支持,还未测试

This commit is contained in:
zhangzheng
2024-01-01 22:57:49 +08:00
parent 0bc4a32d6f
commit 1e8d407664
16 changed files with 280 additions and 146 deletions

View File

@@ -19,7 +19,7 @@ typedef struct ipc_msg
{
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];
umword_t user[IPC_USER_SIZE / WORD_BYTES]; // 0 pthread使用 1驱动使用 2 ipc通信时存储目标的pid
};
uint8_t data[MSG_BUG_LEN];
};
@@ -58,18 +58,11 @@ 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(ipc_timeout_t timeout, umword_t *ret_obj);
msg_tag_t thread_ipc_wait(ipc_timeout_t timeout, umword_t *obj, obj_handler_t ipc_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);
// #define thread_get_cur_ipc_msg() \
// ( \
// { \
// umword_t buf; \
// thread_msg_buf_get(-1, &buf, NULL); \
// ((ipc_msg_t *)buf); \
// })
static inline ipc_msg_t *thread_get_cur_ipc_msg(void)
{
umword_t buf;

View File

@@ -20,7 +20,7 @@ enum IPC_TYPE
IPC_RECV,
IPC_SEND,
};
msg_tag_t thread_ipc_wait(ipc_timeout_t timeout, umword_t *obj)
msg_tag_t thread_ipc_wait(ipc_timeout_t timeout, umword_t *obj, obj_handler_t ipc_obj)
{
register volatile umword_t r0 asm("r0");
register volatile umword_t r1 asm("r1");
@@ -29,7 +29,7 @@ msg_tag_t thread_ipc_wait(ipc_timeout_t timeout, umword_t *obj)
IPC_WAIT,
0,
timeout.raw,
0,
ipc_obj,
0);
asm __volatile__(""
:

View File

@@ -36,9 +36,11 @@ target_link_libraries(
sys
muslc
cpio
util
)
set_target_properties(sys_util PROPERTIES LINK_FLAGS "-pie ")
add_dependencies(sys_util sys)
add_dependencies(sys_util muslc)
add_dependencies(sys_util util)

View File

@@ -6,6 +6,8 @@
#include "u_thread.h"
#include "u_util.h"
#include <assert.h>
// FIXME: 每个线程应该有一个buf_hd
#define RPC_SVR_MAP_OBJ_NR (MAP_BUF_SIZE / sizeof(umword_t))
static obj_handler_t buf_hd[RPC_SVR_MAP_OBJ_NR];
@@ -46,6 +48,15 @@ int rpc_hd_alloc(void)
{
return -1;
}
// 如果新申请的和后面的一样,则后面的需要清空
for (int j = i + 1; j < RPC_SVR_MAP_OBJ_NR; j++)
{
if (hd == buf_hd[j])
{
buf_hd[j] = 0;
break;
}
}
}
else
{

View File

@@ -8,9 +8,16 @@
#include "u_err.h"
#include "u_rpc_buf.h"
#include "cons_cli.h"
#include "u_env.h"
#include "u_sleep.h"
#include "u_thread_util.h"
#include "u_slist.h"
#include "cons_cli.h"
#include <pthread.h>
#include <errno.h>
#include <assert.h>
#include <stdio.h>
#include <malloc.h>
static meta_t meta_obj;
static msg_tag_t rpc_meta_t_dispatch(struct rpc_svr_obj *obj, msg_tag_t in_tag, ipc_msg_t *ipc_msg);
@@ -151,7 +158,7 @@ int rpc_meta_init(obj_handler_t th, obj_handler_t *ret_ipc_hd)
*/
void rpc_loop(void)
{
umword_t obj;
umword_t obj = 0;
msg_tag_t tag;
umword_t buf;
ipc_msg_t *msg;
@@ -162,7 +169,7 @@ void rpc_loop(void)
while (1)
{
rpc_hd_alloc();
tag = thread_ipc_wait(ipc_timeout_create2(0, 0), &obj);
tag = thread_ipc_wait(ipc_timeout_create2(0, 0), &obj, -1);
if (msg_tag_get_val(tag) < 0)
{
continue;
@@ -175,3 +182,128 @@ void rpc_loop(void)
thread_ipc_reply(tag, ipc_timeout_create2(0, 0));
}
}
#define RPC_MTD_TH_STACK_SIZE 1024
typedef struct mtd_params
{
rpc_svr_obj_t *obj;
msg_tag_t in_tag;
obj_handler_t ipc_obj;
obj_handler_t th_obj;
slist_head_t node;
} mtd_params_t;
static slist_head_t th_head;
static pthread_spinlock_t lock;
static void rpc_mtc_thread(void *arg)
{
rpc_svr_obj_t *svr_obj;
msg_tag_t tag;
ipc_msg_t *msg;
mtd_params_t *params = (mtd_params_t *)arg;
svr_obj = (rpc_svr_obj_t *)params->obj;
if (svr_obj->dispatch)
{
tag = svr_obj->dispatch(svr_obj, params->in_tag, msg);
}
thread_ipc_send(tag, params->ipc_obj, ipc_timeout_create2(0, 0));
handler_free_umap(params->ipc_obj);
params->ipc_obj = HANDLER_INVALID;
u_thread_del(params->th_obj);
while (1)
;
}
static void check_release_stack_mem(void)
{
mtd_params_t *pos;
slist_foreach_not_next(pos, &th_head, node)
{
mtd_params_t *next = slist_next_entry(pos, &th_head, node);
slist_del(&pos->node);
void *stack = (void *)((char *)pos - (RPC_MTD_TH_STACK_SIZE + MSG_BUG_LEN));
free(stack);
pos = next;
}
}
extern void __pthread_new_thread_entry__(void);
int rpc_mtd_loop(void)
{
umword_t obj = 0;
msg_tag_t tag;
umword_t buf;
obj_handler_t ipc_hd;
slist_init(&th_head);
while (1)
{
rpc_hd_alloc();
check_release_stack_mem();
ipc_hd = handler_alloc();
if (ipc_hd == HANDLER_INVALID)
{
cons_write_str("mtd alloc is fial.\n");
u_sleep_ms(1000);
continue;
}
tag = factory_create_ipc(FACTORY_PROT, vpage_create_raw3(0, 0, ipc_hd));
if (msg_tag_get_val(tag) < 0)
{
cons_write_str("mtd factory ipc fail.\n");
handler_free(ipc_hd);
u_sleep_ms(1000);
continue;
}
tag = thread_ipc_wait(ipc_timeout_create2(0, 0), &obj, ipc_hd);
if (msg_tag_get_val(tag) < 0)
{
continue;
}
again_create:;
obj_handler_t th_obj;
void *stack = malloc(RPC_MTD_TH_STACK_SIZE + MSG_BUG_LEN + sizeof(mtd_params_t));
if (!stack)
{
cons_write_str("mtd no stack mem.\n");
check_release_stack_mem();
u_sleep_ms(1000);
goto again_create;
}
int ret_val;
umword_t *stack_tmp = (umword_t *)stack;
mtd_params_t *params = (mtd_params_t *)((char *)stack + RPC_MTD_TH_STACK_SIZE + MSG_BUG_LEN);
// 设置调用参数等
*(--stack_tmp) = (umword_t)(params);
*(--stack_tmp) = (umword_t)0; // 保留
*(--stack_tmp) = (umword_t)rpc_mtc_thread;
params->in_tag = tag;
params->ipc_obj = ipc_hd;
params->obj = (rpc_svr_obj_t *)obj;
slist_init(&params->node);
slist_add(&th_head, &params->node);
again_th_create:
ret_val = u_thread_create(&params->th_obj,
stack,
RPC_MTD_TH_STACK_SIZE,
(char *)stack + RPC_MTD_TH_STACK_SIZE,
(void (*)(void))__pthread_new_thread_entry__);
if (ret_val < 0)
{
cons_write_str("mtd no mem.\n");
check_release_stack_mem();
u_sleep_ms(1000);
goto again_th_create;
}
// thread_ipc_reply(tag, ipc_timeout_create2(0, 0));
}
return 0;
}

View File

@@ -40,7 +40,7 @@ static void sig_func(void)
while (1)
{
msg_tag_t tag = thread_ipc_wait(ipc_timeout_create2(0, 0), NULL);
msg_tag_t tag = thread_ipc_wait(ipc_timeout_create2(0, 0), NULL, -1);
if (msg_tag_get_val(tag) < 0)
{
continue;

View File

@@ -12,5 +12,5 @@ static obj_handler_t hd = HANDLER_INVALID;
void u_sleep_ms(size_t ms)
{
thread_ipc_wait(ipc_timeout_create2(0, ms / (1000 / CONFIG_SYS_SCHE_HZ)), NULL);
thread_ipc_wait(ipc_timeout_create2(0, ms / (1000 / CONFIG_SYS_SCHE_HZ)), NULL, -1);
}

View File

@@ -9,7 +9,7 @@
#include <u_thread_util.h>
void u_thread_del(obj_handler_t th_hd)
{
task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th_hd));
handler_free_umap(th_hd);
}
int u_thread_create(obj_handler_t *th_hd, void *stack, umword_t stack_size, void *msg_buf, void (*thread_func)(void))
{

View File

@@ -41,7 +41,7 @@ static void thread_test_func(void)
ipc_bind(ipc_hd, th1_hd, 0);
while (1)
{
thread_ipc_wait(ipc_timeout_create2(0, 0), NULL);
thread_ipc_wait(ipc_timeout_create2(0, 0), NULL, -1);
printf("srv recv:%s", buf);
hard_sleep();
buf[0] = '_';

View File

@@ -76,10 +76,11 @@ static void thread_test_func(void)
{
char *buf;
umword_t len;
thread_msg_buf_get(th1_hd, (umword_t *)(&buf), NULL);
while (1)
{
thread_ipc_wait(ipc_timeout_create2(0, 0), NULL);
thread_ipc_wait(ipc_timeout_create2(0, 0), NULL, -1);
printf("srv recv:%s", buf);
hard_sleep();
// u_sleep_ms(10);

View File

@@ -37,7 +37,7 @@ 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;
thread_ipc_wait(ipc_timeout_create2(0, 0), NULL);
thread_ipc_wait(ipc_timeout_create2(0, 0), NULL, -1);
printf("srv recv:%s", buf);
ulog_write_str(log_hd, "map test success.\n");
hard_sleep();