fastipc初版

This commit is contained in:
zhangzheng
2024-12-27 08:23:26 +08:00
parent 90407a8777
commit a1f149e2f3
19 changed files with 536 additions and 141 deletions

View File

@@ -115,7 +115,7 @@ CONFIG_BOARD_NAME="STM32F205"
CONFIG_BUDDY_SLAB=n
CONFIG_SMP=n
CONFIG_CPU=1
CONFIG_THREAD_BLOCK_SIZE=0x400
CONFIG_THREAD_BLOCK_SIZE=0x800
CONFIG_PAGE_SHIFT=9
CONFIG_MMU=n
CONFIG_KNL_TEST=n

View File

@@ -40,7 +40,7 @@ void thread_knl_pf_set(thread_t *cur_th, void *pc)
cur_th->sp.user_sp = 0;
cur_th->sp.sp_type = 0xfffffff9;
}
void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram, umword_t stack)
void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram)
{
// assert((((umword_t)user_sp) & 0x7UL) == 0);
umword_t usp = ((umword_t)(user_sp) & ~0x7UL);
@@ -55,8 +55,12 @@ void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram, um
cur_th->sp.knl_sp = ((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE - 8);
cur_th->sp.user_sp = cur_pf;
cur_th->sp.sp_type = 0xfffffffd;
// printk("exc_regs:%x %x %x\n", cur_pf->pf_s.pc, cur_th->sp.user_sp, ram);
}
void thread_user_pf_restore(thread_t *cur_th, void *user_sp)
{
cur_th->sp.knl_sp = ((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE - 8);
cur_th->sp.user_sp = user_sp;
cur_th->sp.sp_type = 0xfffffffd;
}
void task_knl_init(task_t *knl_tk)
{

View File

@@ -67,7 +67,7 @@ void uart_init(void)
nvic_priority_group_config(NVIC_PRIORITY_GROUP_2);
nvic_irq_enable(USART1_IRQn, 0, 0);
/* configure uart param */
usart_init(PRINT_USARTx, 115200, USART_DATA_8BITS, USART_STOP_1_BIT);
usart_init(PRINT_USARTx, 921600, USART_DATA_8BITS, USART_STOP_1_BIT);
usart_transmitter_enable(PRINT_USARTx, TRUE);
usart_receiver_enable(PRINT_USARTx, TRUE);

View File

@@ -18,15 +18,15 @@ void sema_init(sema_t *obj, int cnt, int max);
void sema_up(sema_t *obj);
void sema_down(sema_t *obj);
void mutex_init(mutex_t *lock)
static inline void mutex_init(mutex_t *lock)
{
sema_init(lock, 1, 1);
}
void mutex_lock(mutex_t *lock)
static inline void mutex_lock(mutex_t *lock)
{
sema_down(lock);
}
void mutex_unlock(mutex_t *lock)
static inline void mutex_unlock(mutex_t *lock)
{
sema_up(lock);
}

View File

@@ -18,7 +18,7 @@
#include "obj_space.h"
#include "mm_space.h"
#include "ref.h"
#include "sema.h"
typedef struct task
{
kobject_t kobj; //!< task kernel object.
@@ -28,8 +28,15 @@ typedef struct task
kobject_t *exec_th; //!< execption thread.
ref_counter_t ref_cn; //!< ref count.
slist_head_t del_node; //!< delect list node.
void *nofity_point; //!< commint point.
void *nofity_point; //!< commint point func.
addr_t nofity_stack; //!< nofity_point_stack.
mutex_t nofity_lock;
addr_t nofity_msg_buf; //!<
umword_t *nofity_bitmap; //!<
int nofity_bitmap_len; //!< max is WORD_BITS
slist_head_t nofity_theads_head;
pid_t pid; //!< task pid.
} task_t;

View File

@@ -17,6 +17,7 @@
#include "ref.h"
#include <atomics.h>
#include "task.h"
#include "stack.h"
struct task;
typedef struct task task_t;
struct thread;
@@ -107,13 +108,21 @@ typedef struct msg_buf
#endif
msg_tag_t tag; //!< 存放发送的临时标识
} msg_buf_t;
typedef struct thread_fast_ipc_item
{
kobject_t *task_bk; //!< 备份task用于快速通信
void *usp_backup; //!< 备份用户栈,用于快速通信
void *msg_buf;
} thread_fast_ipc_item_t;
#define THREAD_FAST_IPC_ITEM_NUM 8
#define THREAD_MAGIC 0xdeadead //!< 用于栈溢出检测
typedef struct thread
{
kobject_t kobj; //!< 内核对象节点
sched_t sche; //!< 调度节点
kobject_t *task; //!< 绑定的task
kobject_t *task_bk; //!< 备份task用于快速通信
sp_info_t sp; //!< sp信息
ram_limit_t *lim; //!< 内存限制
ref_counter_t ref; //!< 引用计数
@@ -141,7 +150,9 @@ typedef struct thread
enum thread_state status; //!< 线程状态
enum thread_ipc_state ipc_status; //!< ipc状态
void *usp_backup;
thread_fast_ipc_item_t fast_ipc_stack_data[THREAD_FAST_IPC_ITEM_NUM]; //!< 栈数据,用于通信栈备份
stack_t fast_ipc_stack; //!< fast ipc stack
slist_head_t fast_ipc_node; //!< 用于加入到task中去。
umword_t magic; //!< maigc
} thread_t;
@@ -207,14 +218,51 @@ static inline thread_t *thread_get_current(void)
return th;
}
static inline void thread_set_task_and_backup(thread_t *th, task_t *tk)
static inline int thread_fast_ipc_save(thread_t *th, task_t *tk, void *usp)
{
th->task_bk = th->task;
th->task = (void*)(&(tk->kobj));
int ret;
assert(th);
assert(tk);
assert(usp);
thread_fast_ipc_item_t item = {
.task_bk = th->task,
.usp_backup = (void *)arch_get_user_sp(),
.msg_buf = th->msg.msg,
};
ret = stack_push(&th->fast_ipc_stack, &item);
if (ret < 0)
{
return ret;
}
th->task = &tk->kobj;
arch_set_user_sp((umword_t)usp); //!< 重新设置
return 0;
}
static inline void thread_task_restore(thread_t *th)
static inline int thread_fast_ipc_restore(thread_t *th)
{
th->task = th->task_bk;
int ret;
assert(th);
thread_fast_ipc_item_t item;
ret = stack_pop(&th->fast_ipc_stack, &item);
if (ret < 0)
{
return ret;
}
th->task = item.task_bk;
th->msg.msg = item.msg_buf;
arch_set_user_sp((umword_t)(item.usp_backup));
return 0;
}
static inline int thread_fast_ipc_pop(thread_t *th, thread_fast_ipc_item_t *item)
{
int ret;
assert(th);
assert(item);
ret = stack_pop(&th->fast_ipc_stack, item);
return ret;
}
task_t *thread_get_current_task(void);
task_t *thread_get_task(thread_t *th);
@@ -225,7 +273,7 @@ static inline pf_t *thread_get_current_pf(void)
return thread_get_pf(thread_get_current());
}
void thread_init(thread_t *th, ram_limit_t *lim, umword_t flags);
void thread_set_exc_regs(thread_t *th, umword_t pc, umword_t user_sp, umword_t ram, umword_t stack);
void thread_set_exc_regs(thread_t *th, umword_t pc, umword_t user_sp, umword_t ram);
thread_t *thread_create(ram_limit_t *ram, umword_t flags);
void thread_bind(thread_t *th, kobject_t *tk);
void thread_unbind(thread_t *th);

View File

@@ -1,4 +1,5 @@
#pragma once
void thread_knl_pf_set(thread_t *cur_th, void *pc);
void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram, umword_t stack);
void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram);
void thread_user_pf_restore(thread_t *cur_th, void *user_sp);
void task_knl_init(task_t *knl_tk);

View File

@@ -0,0 +1,13 @@
#pragma once
typedef struct
{
void *data;
int top;
int len;
int item_size;
} stack_t;
void stack_init(stack_t *stack, void *stack_data, int len, int item_size);
int stack_push(stack_t *stack, void *item);
int stack_pop(stack_t *stack, void *item);

View File

@@ -22,6 +22,7 @@
#include "string.h"
#include "thread.h"
#include "thread_arch.h"
#include "thread_task_arch.h"
#if IS_ENABLED(CONFIG_MMU)
#include "arch.h"
#endif
@@ -41,6 +42,8 @@ enum task_op_code
TASK_SET_OBJ_NAME, //!< 设置对象的名字
TASK_COPY_DATA_TO, //!< 从当前task拷贝数据到目的task
TASK_SET_COM_POINT, //!< 通信点
TASK_COM_UNLOCK, //!< 任务通信解锁
TASK_COM_LOCK, //!< 任务通信加锁
};
static bool_t task_put(kobject_t *kobj);
static void task_release_stage1(kobject_t *kobj);
@@ -396,10 +399,51 @@ static void task_syscall_func(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t i
tag = msg_tag_init4(0, 0, 0, ret);
}
break;
case TASK_SET_COM_POINT:
case TASK_SET_COM_POINT: //!< 设置通信点
{
if (!is_rw_access(tag_task, (void *)(f->regs[1]), f->regs[2], FALSE))
{
tag = msg_tag_init4(0, 0, 0, -EPERM);
break;
}
if (f->regs[4] >= WORD_BITS)
{
tag = msg_tag_init4(0, 0, 0, -EINVAL);
break;
}
if (!is_rw_access(tag_task, (void *)(f->regs[3]), ROUND_UP(f->regs[4], 8), FALSE))
{
tag = msg_tag_init4(0, 0, 0, -EPERM);
break;
}
if (!is_rw_access(tag_task, (void *)(f->regs[5]), THREAD_MSG_BUG_LEN, FALSE))
{
tag = msg_tag_init4(0, 0, 0, -EPERM);
break;
}
int stack_size = f->regs[2];
tag_task->nofity_point = (void *)(f->regs[0]);
tag_task->nofity_stack = (addr_t)(f->regs[1]);
tag_task->nofity_stack = (addr_t)(f->regs[1] + stack_size);
tag_task->nofity_bitmap = (void *)(f->regs[3]);
tag_task->nofity_bitmap_len = (f->regs[4]);
tag_task->nofity_msg_buf = (addr_t)f->regs[5];
tag = msg_tag_init4(0, 0, 0, 0);
}
break;
case TASK_COM_UNLOCK:
{
task_t *cur_task = thread_get_current_task();
mutex_unlock(&cur_task->nofity_lock);
tag = msg_tag_init4(0, 0, 0, 0);
}
break;
case TASK_COM_LOCK:
{
task_t *cur_task = thread_get_current_task();
mutex_lock(&cur_task->nofity_lock);
tag = msg_tag_init4(0, 0, 0, 0);
}
break;
@@ -420,6 +464,8 @@ void task_init(task_t *task, ram_limit_t *ram, int is_knl)
ref_counter_init(&task->ref_cn);
ref_counter_inc(&task->ref_cn);
slist_init(&task->del_node);
slist_init(&task->nofity_theads_head);
mutex_init(&task->nofity_lock);
task->pid = -1;
task->lim = ram;
task->kobj.invoke_func = task_syscall_func;
@@ -442,6 +488,7 @@ static bool_t task_put(kobject_t *kobj)
}
static void task_release_stage1(kobject_t *kobj)
{
int ret;
task_t *tk = container_of(kobj, task_t, kobj);
kobj_del_list_t kobj_list;
kobject_invalidate(kobj);
@@ -449,6 +496,28 @@ static void task_release_stage1(kobject_t *kobj)
obj_unmap_all(&tk->obj_space, &kobj_list);
kobj_del_list_to_do(&kobj_list);
thread_t *restore_th;
thread_fast_ipc_item_t ipc_item;
slist_foreach(restore_th, &tk->nofity_theads_head, fast_ipc_node)
{
ret = thread_fast_ipc_pop(restore_th, &ipc_item);
if (ret >= 0)
{
// 还原栈和usp
restore_th->ipc_status = THREAD_NONE;
if (restore_th->status == THREAD_SUSPEND)
{
thread_ready(restore_th, TRUE);
}
restore_th->task = ipc_item.task_bk;
thread_user_pf_restore(restore_th, ipc_item.usp_backup);
pf_t *cur_pf = ((pf_t *)((char *)restore_th + CONFIG_THREAD_BLOCK_SIZE + 8)) - 1;
cur_pf->regs[5] = (umword_t)(thread_get_bind_task(restore_th)->mm_space.mm_block);
ref_counter_dec_and_release(&tk->ref_cn, &tk->kobj);
}
}
#if IS_ENABLED(CONFIG_MMU)
task_vma_clean(&tk->mm_space.mem_vma);
#endif
@@ -482,7 +551,7 @@ static void task_release_stage2(kobject_t *kobj)
// arch_to_sche();
// }
// mm_trace();
printk("release tk %x\n", tk);
printk("release tk %x, name is:%s\n", tk, kobject_get_name(&tk->kobj));
}
void task_kill(task_t *tk)
{

View File

@@ -32,6 +32,7 @@
#include "thread.h"
#include "thread_task_arch.h"
#include "types.h"
#include "sema.h"
#if IS_ENABLED(CONFIG_SMP)
#include <ipi.h>
#endif
@@ -120,11 +121,15 @@ void thread_init(thread_t *th, ram_limit_t *lim, umword_t flags)
sched_init(&th->sche);
slist_init(&th->futex_node);
slist_init(&th->wait_send_head);
slist_init(&th->fast_ipc_node);
spinlock_init(&th->recv_lock);
spinlock_init(&th->send_lock);
ref_counter_init(&th->ref);
ref_counter_inc(&th->ref);
thread_arch_init(th, flags);
stack_init(&th->fast_ipc_stack, &th->fast_ipc_stack_data,
ARRARY_LEN(th->fast_ipc_stack_data),
sizeof(th->fast_ipc_stack_data[0]));
th->cpu = arch_get_current_cpu_id();
th->lim = lim;
th->kobj.invoke_func = thread_syscall;
@@ -310,7 +315,7 @@ static void thread_release_stage2(kobject_t *kobj)
#else
mm_limit_free_align(th->lim, kobj, CONFIG_THREAD_BLOCK_SIZE);
// mm_trace();
// printk("release thread 0x%x\n", kobj);
printk("release thread 0x%x, name:%s\n", kobj, kobject_get_name(kobj));
#endif
}
@@ -322,9 +327,9 @@ static void thread_release_stage2(kobject_t *kobj)
* @param ip
*/
void thread_set_exc_regs(thread_t *th, umword_t pc, umword_t user_sp,
umword_t ram, umword_t stack)
umword_t ram)
{
thread_user_pf_set(th, (void *)pc, (void *)user_sp, (void *)ram, stack);
thread_user_pf_set(th, (void *)pc, (void *)user_sp, (void *)ram);
}
/**
* @brief 线程绑定到task
@@ -710,6 +715,41 @@ void thread_timeout_del_recv_remote(thread_t *th, bool_t is_sche)
thread_ready(th, is_sche); //!< 直接唤醒接受者
#endif
}
static int ipc_dat_copy_raw(obj_space_t *dst_obj, obj_space_t *src_obj, ram_limit_t *lim,
ipc_msg_t *dst_ipc, ipc_msg_t *src_ipc, msg_tag_t tag, int is_reply)
{
if (tag.map_buf_len > 0)
{
kobj_del_list_t del;
int map_len = tag.map_buf_len;
kobj_del_list_init(&del);
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) || is_reply)
{
ret = obj_map_src_dst(dst_obj, src_obj,
vpage_get_obj_handler(dst_page),
vpage_get_obj_handler(src_page), 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));
}
/**
* @brief ipc传输时的数据拷贝
*
@@ -730,38 +770,9 @@ static int ipc_data_copy(thread_t *dst_th, thread_t *src_th, msg_tag_t tag, int
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);
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) || is_reply)
{
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);
}
ipc_dat_copy_raw(&dst_tk->obj_space, &src_tk->obj_space, dst_tk->lim, dst_ipc, src_ipc, tag, is_reply);
dst_ipc->user[2] = task_pid_get(src_tk);
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;
}
@@ -918,10 +929,11 @@ again:;
if (to->ipc_status == THREAD_IPC_ABORT)
{
ref_counter_dec_and_release(&to->ref, &to->kobj);
spinlock_set(&to->recv_lock, status_lock2);
return -ECANCELED;
}
spinlock_set(&to->recv_lock, status_lock2);
thread_sched(TRUE);
spinlock_set(&to->recv_lock, status_lock2);
preemption();
goto again;
}
@@ -946,7 +958,6 @@ again:;
assert(to->status == THREAD_SUSPEND && to->ipc_status == THREAD_RECV);
thread_timeout_del_from_send_queue_remote(to);
}
// to->last_send_th = NULL;
ref_counter_dec_and_release(&to->ref, &to->kobj);
spinlock_set(&to->recv_lock, status_lock2);
return 0;
@@ -1225,43 +1236,84 @@ msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id)
{
case IPC_FAST_REPLAY:
{
thread_task_restore(cur_th); //!< 切换task到目的task并且进行备份
arch_set_user_sp((umword_t)(cur_th->usp_backup));
msg_tag_t in_tag = msg_tag_init(f->regs[0]);
task_t *old_task = thread_get_bind_task(cur_th);
//! 解锁bitmap
*(cur_task->nofity_bitmap) &= ~(1 << MIN(f->regs[2], cur_task->nofity_bitmap_len));
slist_del(&cur_th->fast_ipc_node);
ret = thread_fast_ipc_restore(cur_th); // 还原栈和usp
if (ret < 0)
{
mutex_unlock(&old_task->nofity_lock);
return msg_tag_init4(0, 0, 0, ret);
}
task_t *cur_task = thread_get_current_task();
ipc_msg_t *dst_ipc = (void *)cur_th->msg.msg;
ipc_msg_t *src_ipc = (void *)old_task->nofity_msg_buf;
ret = ipc_dat_copy_raw(&cur_task->obj_space, &old_task->obj_space, cur_task->lim,
dst_ipc, src_ipc, in_tag, FALSE);
if (ret < 0)
{
mutex_unlock(&old_task->nofity_lock);
return msg_tag_init4(0, 0, 0, ret);
}
mutex_unlock(&old_task->nofity_lock);
pf_t *cur_pf = ((pf_t *)((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE + 8)) - 1;
cur_pf->regs[5] = (umword_t)(thread_get_current_task()->mm_space.mm_block);
cur_pf->regs[5] = (umword_t)(cur_task->mm_space.mm_block);
extern void mpu_switch_to_task(struct task * tk);
mpu_switch_to_task(thread_get_current_task());
return msg_tag_init4(0, 0, 0, 0);
mpu_switch_to_task(cur_task);
ref_counter_dec_and_release(&old_task->ref_cn, &old_task->kobj);
return msg_tag_init4(0, 0, 0, ret);
}
break;
case IPC_FAST_CALL:
{
// 线程中的task
// 内核栈返回需要修改r9
// 还原用户站
msg_tag_t in_tag = msg_tag_init(f->regs[0]);
// 1.需要切换的资源有r9task和用户栈
// 2.在对方进程中被杀死,需要还原当前线程的状态,并返回一个错误
// 3.多线程访问时,服务端提供一个小的用户线程栈,然后内核到用户部分为临界区域,在服务端重新分配用户栈用,使用新的用户栈。
// 4.fastipc嵌套访问会有问题内核必须要提供一个软件上的调用栈。
task_t *to_task = thread_get_bind_task(to_th);
if (to_task->nofity_point == NULL)
{
return msg_tag_init4(0, 0, 0, -EIO);
}
thread_set_task_and_backup(cur_th, to_task); //!< 切换task到目的task并且进行备份
_to_unlock:
if (GET_LSB(*to_task->nofity_bitmap, to_task->nofity_bitmap_len) == GET_LSB((~0ULL), to_task->nofity_bitmap_len))
{
thread_sched(TRUE); /*TODO:应该挂起,并在释放时唤醒*/
preemption();
goto _to_unlock;
}
mutex_lock(&to_task->nofity_lock);
if (GET_LSB(*to_task->nofity_bitmap, to_task->nofity_bitmap_len) == GET_LSB((~0ULL), to_task->nofity_bitmap_len))
{
mutex_unlock(&to_task->nofity_lock);
thread_sched(TRUE); /*TODO:应该挂起,并在释放时唤醒*/
preemption();
goto _to_unlock;
}
ref_counter_inc((&to_task->ref_cn));
//!< 执行目标线程时用的是当前线程的资源,这里还需要备份当前线程的上下文。
void *prev_usp = (void *)arch_get_user_sp();
ret = thread_fast_ipc_save(cur_th, to_task, (void *)(to_task->nofity_stack - 4 * 8)); //!< 备份栈和usp
if (ret >= 0)
{
ipc_msg_t *dst_ipc = (void *)to_task->nofity_msg_buf;
ipc_msg_t *src_ipc = (void *)cur_th->msg.msg;
ret = ipc_dat_copy_raw(&to_task->obj_space, &cur_task->obj_space, to_task->lim,
dst_ipc, src_ipc, in_tag, FALSE);
if (ret >= 0)
{
dst_ipc->user[2] = task_pid_get(cur_task); // 设置pid
slist_add(&to_task->nofity_theads_head, &cur_th->fast_ipc_node);
cur_th->usp_backup = prev_usp;//!<保存之前的用户栈
arch_set_user_sp(to_task->nofity_stack - 32); //!<重新设置
pf_s_t *usr_stask_point = (void *)arch_get_user_sp();
// usr_stask_point->rg0[0] = 0x1111;
// usr_stask_point->rg0[1] = 0x2222;
// usr_stask_point->rg0[2] = 0x3333;
// usr_stask_point->rg0[3] = 0x4444;
usr_stask_point->r12 = 0x12121212;
usr_stask_point->xpsr = 0x01000000L;
usr_stask_point->lr = (umword_t)NULL; //!< 线程退出时调用的函数
@@ -1270,10 +1322,28 @@ msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id)
pf_t *cur_pf = ((pf_t *)((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE + 8)) - 1; //!< 获得内核栈栈顶
cur_pf->regs[5] = (umword_t)(to_task->mm_space.mm_block); // 重新设置r9寄存器
//! 寄存器传参数
f->regs[0] = in_tag.raw;
f->regs[1] = f->regs[2];
f->regs[2] = f->regs[3];
f->regs[3] = f->regs[4];
extern void mpu_switch_to_task(struct task * tk);
mpu_switch_to_task(to_task);
return msg_tag_init4(0, 0, 0, 0);
return in_tag;
}
else
{
ref_counter_dec_and_release(&to_task->ref_cn, &to_task->kobj);
mutex_unlock(&to_task->nofity_lock);
}
}
else
{
ref_counter_dec_and_release(&to_task->ref_cn, &to_task->kobj);
mutex_unlock(&to_task->nofity_lock);
}
return msg_tag_init4(0, 0, 0, ret);
}
break;
case IPC_CALL:
@@ -1376,14 +1446,7 @@ static void thread_syscall(kobject_t *kobj, syscall_prot_t sys_p,
{
case SET_EXEC_REGS:
{
umword_t stack_bottom = 0;
if (f->regs[4]) //!< cp_stack
{
stack_bottom = (umword_t)(thread_get_msg_buf(cur_th));
}
thread_set_exc_regs(tag_th, f->regs[1], f->regs[2], f->regs[3],
stack_bottom);
thread_set_exc_regs(tag_th, f->regs[1], f->regs[2], f->regs[3]);
tag = msg_tag_init4(0, 0, 0, 0);
}
break;

View File

@@ -72,9 +72,15 @@ static void knl_main(void)
msg_tag_t tag;
umword_t user_id;
ipc_msg_t *msg = (ipc_msg_t *)knl_msg_buf;
if (pos->pid != 0)
{
msg->msg_buf[0] = 1; /*KILL_TASK*/
msg->msg_buf[1] = pos->pid;
msg->msg_buf[2] = 0;
if (thread_get_ipc_state(init_thread) != THREAD_IPC_ABORT)
{
int ret = thread_ipc_call(init_thread, msg_tag_init4(0, 3, 0, 0x0005 /*PM_PROT*/),
&tag, ipc_timeout_create2(3000, 3000), &user_id, TRUE);
@@ -83,6 +89,8 @@ static void knl_main(void)
printk("%s:%d ret:%d\n", __func__, __LINE__, ret);
}
}
}
}
task_kill(pos);
pos = next;
}
@@ -151,7 +159,7 @@ static void knl_init_2(void)
cpio_get_size(cpio_images), (paddr_t)cpio_images, 0) >= 0);
thread_set_msg_buf(init_thread, (void *)init_msg_buf, (void *)CONFIG_MSG_BUF_VADDR);
thread_user_pf_set(init_thread, (void *)(entry), (void *)0xdeaddead,
NULL, 0);
NULL);
#else
app_info_t *app;
@@ -167,7 +175,7 @@ static void knl_init_2(void)
thread_set_msg_buf(init_thread, (char *)(init_task->mm_space.mm_block) + app->i.ram_size, (char *)(init_task->mm_space.mm_block) + app->i.ram_size);
thread_user_pf_set(init_thread, (void *)(app), (void *)((umword_t)sp_addr_top - 8),
init_task->mm_space.mm_block, 0);
init_task->mm_space.mm_block);
#endif
thread_bind(init_thread, &init_task->kobj);
assert(obj_map_root(&init_thread->kobj, &init_task->obj_space, &root_factory_get()->limit, vpage_create3(KOBJ_ALL_RIGHTS, 0, THREAD_PROT)));
@@ -180,7 +188,7 @@ static void knl_init_2(void)
assert(obj_map_root(kobj, &init_task->obj_space, &root_factory_get()->limit, vpage_create3(KOBJ_ALL_RIGHTS, 0, i)));
}
}
init_thread->sche.prio = 2;
init_thread->sche.prio = 15;
init_task->pid = 0;
thread_ready(init_thread, FALSE);
#endif
@@ -197,6 +205,7 @@ void task_knl_kill(thread_t *kill_thread, bool_t is_knl)
status2 = spinlock_lock(&del_lock);
thread_suspend(kill_thread);
kill_thread->ipc_status = THREAD_IPC_ABORT;
slist_add_append(&del_task_head, &task->del_node);
spinlock_set(&del_lock, status2);
}

37
mkrtos_knl/lib/stack.c Normal file
View File

@@ -0,0 +1,37 @@
#include "types.h"
#include <assert.h>
#include <string.h>
#include "stack.h"
void stack_init(stack_t *stack, void *stack_data, int len, int item_size)
{
assert(stack);
assert(stack_data);
memset(stack_data, 0, len * item_size);
stack->top = -1;
stack->len = len;
stack->item_size = item_size;
stack->data = stack_data;
}
int stack_push(stack_t *stack, void *item)
{
if (stack->top < stack->len)
{
++(stack->top);
memcpy((uint8_t *)(stack->data) + stack->top * stack->item_size,
item, stack->item_size);
return 0;
}
return -1;
}
int stack_pop(stack_t *stack, void *item)
{
if (stack->top != -1)
{
memcpy(item, (uint8_t *)(stack->data) + stack->top * stack->item_size, stack->item_size);
stack->top--;
return 0;
}
return -1;
}

View File

@@ -16,4 +16,9 @@ msg_tag_t task_unmap(obj_handler_t task_han, vpage_t vpage);
msg_tag_t task_alloc_ram_base(obj_handler_t task_han, umword_t size, addr_t *alloc_addr);
msg_tag_t task_copy_data(obj_handler_t task_obj, void *st_addr, umword_t size);
msg_tag_t task_copy_data_to(obj_handler_t task_obj, obj_handler_t dst_task_obj, void *st_addr, void *dst_addr, umword_t size);
msg_tag_t task_set_com_point(obj_handler_t task_obj, void *com_point_func, addr_t stack);
msg_tag_t task_set_com_point(obj_handler_t task_obj, void *com_point_func,
addr_t stack, umword_t stack_size,
void *bitmap, int bitmap_len,
void *msg_buf);
msg_tag_t task_com_unlock(obj_handler_t task_obj);
msg_tag_t task_com_lock(obj_handler_t task_obj);

View File

@@ -7,9 +7,9 @@
#define MSG_BUF_RECV_R_FLAGS 0x02U //!< 接收上次发送数据的接收者
#define MSG_BUF_REPLY_FLAGS 0x04U //!<
#define IPC_MSG_SIZE (CONFIG_THREAD_IPC_MSG_LEN * sizeof(void*))
#define MAP_BUF_SIZE (CONFIG_THREAD_MAP_BUF_LEN * sizeof(void*))
#define IPC_USER_SIZE (CONFIG_THREAD_USER_BUF_LEN * sizeof(void*))
#define IPC_MSG_SIZE (CONFIG_THREAD_IPC_MSG_LEN * sizeof(void *))
#define MAP_BUF_SIZE (CONFIG_THREAD_MAP_BUF_LEN * sizeof(void *))
#define IPC_USER_SIZE (CONFIG_THREAD_USER_BUF_LEN * sizeof(void *))
#if IS_ENABLED(CONFIG_VCPU)
#define IPC_VPUC_MSG_OFFSET (3 * 1024) //!< vcpu 传递消息的偏移量
@@ -71,8 +71,8 @@ msg_tag_t thread_ipc_wait(ipc_timeout_t timeout, umword_t *obj, obj_handler_t ip
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);
msg_tag_t thread_ipc_fast_call(msg_tag_t in_tag, obj_handler_t target_obj);
msg_tag_t thread_ipc_fast_replay(obj_handler_t target_obj);
msg_tag_t thread_ipc_fast_call(msg_tag_t in_tag, obj_handler_t target_obj, umword_t arg0, umword_t arg1, umword_t arg2);
msg_tag_t thread_ipc_fast_replay(msg_tag_t in_tag, obj_handler_t target_obj, int unlock_bitmap);
static inline ipc_msg_t *thread_get_cur_ipc_msg(void)
{

View File

@@ -14,7 +14,9 @@ enum task_op_code
TASK_COPY_DATA,
TASK_SET_OBJ_NAME,
TASK_COPY_DATA_TO, //!< 从当前task拷贝数据到目的task
TASK_SET_COM_POINT
TASK_SET_COM_POINT,
TASK_COM_UNLOCK,
TASK_COM_LOCK,
};
msg_tag_t task_set_obj_name(obj_handler_t dst_task, obj_handler_t obj, const char *name)
@@ -196,13 +198,50 @@ msg_tag_t task_copy_data_to(obj_handler_t task_obj, obj_handler_t dst_task_obj,
return msg_tag_init(r0);
}
msg_tag_t task_set_com_point(obj_handler_t task_obj, void *com_point_func, addr_t stack)
msg_tag_t task_set_com_point(obj_handler_t task_obj, void *com_point_func, addr_t stack, umword_t stack_size, void *bitmap, int bitmap_len, void *msg_buf)
{
register volatile umword_t r0 asm(ARCH_REG_0);
mk_syscall(syscall_prot_create(TASK_SET_COM_POINT, TASK_PROT, task_obj).raw,
com_point_func,
stack,
stack_size,
bitmap,
bitmap_len,
msg_buf);
asm __volatile__(""
:
:
: ARCH_REG_0, ARCH_REG_1);
return msg_tag_init(r0);
}
msg_tag_t task_com_unlock(obj_handler_t task_obj)
{
register volatile umword_t r0 asm(ARCH_REG_0);
mk_syscall(syscall_prot_create(TASK_COM_UNLOCK, TASK_PROT, task_obj).raw,
0,
0,
0,
0,
0,
0);
asm __volatile__(""
:
:
: ARCH_REG_0, ARCH_REG_1);
return msg_tag_init(r0);
}
msg_tag_t task_com_lock(obj_handler_t task_obj)
{
register volatile umword_t r0 asm(ARCH_REG_0);
mk_syscall(syscall_prot_create(TASK_COM_LOCK, TASK_PROT, task_obj).raw,
0,
0,
0,
0,
0,

View File

@@ -92,15 +92,15 @@ msg_tag_t thread_ipc_call(msg_tag_t in_tag, obj_handler_t target_th_obj, ipc_tim
: ARCH_REG_0);
return msg_tag_init(r0);
}
msg_tag_t thread_ipc_fast_call(msg_tag_t in_tag, obj_handler_t target_obj)
msg_tag_t thread_ipc_fast_call(msg_tag_t in_tag, obj_handler_t target_obj, umword_t arg0, umword_t arg1, umword_t arg2)
{
register volatile umword_t r0 asm(ARCH_REG_0);
mk_syscall(syscall_prot_create4(DO_IPC, THREAD_PROT, target_obj, TRUE).raw,
in_tag.raw,
IPC_FAST_CALL,
0,
0,
0,
arg0,
arg1,
arg2,
0);
asm __volatile__(""
:
@@ -108,13 +108,13 @@ msg_tag_t thread_ipc_fast_call(msg_tag_t in_tag, obj_handler_t target_obj)
: ARCH_REG_0);
return msg_tag_init(r0);
}
msg_tag_t thread_ipc_fast_replay(obj_handler_t target_obj)
msg_tag_t thread_ipc_fast_replay(msg_tag_t in_tag, obj_handler_t target_obj, int unlock_bitmap)
{
register volatile umword_t r0 asm(ARCH_REG_0);
mk_syscall(syscall_prot_create4(DO_IPC, THREAD_PROT, target_obj, TRUE).raw,
0,
in_tag.raw,
IPC_FAST_REPLAY,
0,
unlock_bitmap,
0,
0,
0);
@@ -147,7 +147,7 @@ msg_tag_t thread_msg_buf_set(obj_handler_t obj, void *msg)
register volatile umword_t r1 asm(ARCH_REG_1);
register volatile umword_t r2 asm(ARCH_REG_2);
mk_syscall(syscall_prot_create(MSG_BUG_SET, THREAD_PROT, obj).raw,
mk_syscall(syscall_prot_create4(MSG_BUG_SET, THREAD_PROT, obj, TRUE).raw,
0,
msg,
0,

View File

@@ -29,26 +29,81 @@
#include "parse_cfg.h"
#include <assert.h>
#include <stdio.h>
static ATTR_ALIGN(8) uint8_t cons_stack[2048];
#include <string.h>
#define DEFAULT_INIT_CFG "init.cfg"
static void init_com_point_test_func(int r0,int r1,int r2,int r3)
#define STACK_SIZE 2048
#define STASCK_NUM 4
static ATTR_ALIGN(8) uint8_t com_stack[512];
static ATTR_ALIGN(8) uint8_t cons_stack[STASCK_NUM][STACK_SIZE];
static uint8_t cons_msg_buf[STASCK_NUM][MSG_BUG_LEN];
static umword_t cons_stack_bitmap;
static uint8_t cons_msg_buf_main[MSG_BUG_LEN];
static inline umword_t arch_get_sp(void)
{
printf("comm r0:%d r1:%d r2:%d r3:%d\n", r0, r1, r2, r3);
printf("comm\n");
printf("comm\n");
printf("comm\n");
printf("comm\n");
thread_ipc_fast_replay(-1);
umword_t ret;
__asm__ __volatile__(
"mov %0, sp\n"
: "=r"(ret)
:
:);
return ret;
}
#define SET_SP(sp) \
do \
{ \
__asm__ __volatile__("mov sp, %0" ::"r"(sp)); \
__asm__ __volatile__("" \
: \
: \
: "sp"); \
} while (0)
int setsp(int i, void *stack, msg_tag_t tag, int arg0, int arg1);
void last_process(int j, msg_tag_t tag, int arg0, int arg1)
{
thread_msg_buf_set(-1, (void *)(cons_msg_buf[j]));
task_com_unlock(TASK_THIS);
// printf("j:%d sp:0x%x\n", j, arch_get_sp());
// printf("j:%d comm tag:%x r0:%d r1:%d\n", j, tag.raw, arg0, arg1);
// printf("%s\n", cons_msg_buf[j]);
// strcpy((void *)cons_msg_buf[j], "okay");
// u_sleep_ms(100);
// *((uint8_t *)0) = 0;
task_com_lock(TASK_THIS);
memcpy(cons_msg_buf_main, cons_msg_buf[j], MSG_BUG_LEN);
tag = msg_tag_init4(0, 2, 0, 0);
thread_ipc_fast_replay(tag, -1, j);
}
static void init_com_point_test_func(msg_tag_t tag, int arg0, int arg1, int arg2)
{
int i;
for (i = 0; i < STASCK_NUM; i++)
{
if ((cons_stack_bitmap & (1 << i)) == 0)
{
cons_stack_bitmap |= (1 << i);
break;
}
}
memcpy(cons_msg_buf[i], cons_msg_buf_main, MSG_BUG_LEN);
setsp(i, &cons_stack[i][STACK_SIZE - 8], tag, arg0, arg1);
}
int main(int argc, char *args[])
{
int ret;
uenv_t *env;
#if 1
#if 0
thread_run(-1, 4);
#endif
task_set_com_point(TASK_THIS,&init_com_point_test_func, (addr_t)(cons_stack + sizeof(cons_stack) - 8));
task_set_com_point(TASK_THIS, &init_com_point_test_func, (addr_t)com_stack,
sizeof(com_stack), &cons_stack_bitmap, STASCK_NUM, cons_msg_buf_main);
task_set_obj_name(TASK_THIS, TASK_THIS, "tk_init");
task_set_obj_name(TASK_THIS, THREAD_MAIN, "th_init");

View File

@@ -0,0 +1,12 @@
.syntax unified
@ .cpu cortex-m3
.thumb
.global setsp
.global last_process
/**
* @brief syscall结束时到这儿
*/
.type setsp, %function
setsp:
mov sp, r1
bl last_process

View File

@@ -9,14 +9,47 @@
#include <u_task.h>
#include <u_thread.h>
#include <u_env.h>
#include <pthread.h>
void *test_func(void *arg)
{
msg_tag_t tag;
ipc_msg_t *msg;
tag = thread_msg_buf_get(-1, (void *)(&msg), NULL);
strcpy((void *)msg->msg_buf, "hello");
for (int i = 0; i < 10000; i++)
{
thread_ipc_fast_call(msg_tag_init4(0, 2, 0, 0), u_get_global_env()->ns_hd, 1111, 2222, 3333);
// printf("%s\n", (void *)msg->msg_buf);
}
// while (1)
// {
// u_sleep_ms(100000);
// }
return NULL;
}
pthread_t pth1;
pthread_t pth2;
pthread_t pth3;
pthread_t pth4;
void fast_ipc_test(void)
{
pthread_create(&pth1, NULL, test_func, NULL);
pthread_create(&pth2, NULL, test_func, NULL);
pthread_create(&pth3, NULL, test_func, NULL);
pthread_create(&pth4, NULL, test_func, NULL);
}
int main(int argc, char *args[])
{
task_set_obj_name(TASK_THIS, TASK_THIS, "tk_sh");
task_set_obj_name(TASK_THIS, THREAD_MAIN, "th_sh");
#if 1
#if 0
thread_run(-1, 3);
#endif
// thread_ipc_fast_call(msg_tag_init(0), u_get_global_env()->ns_hd);
fast_ipc_test();
for (int i = 0; i < argc; i++)
{
printf("args[%d]:%s\n", i, args[i]);