增加简单的sema&mutex支持
This commit is contained in:
@@ -150,6 +150,7 @@ static void other_cpu_boot(void)
|
||||
arch_cpu_knl_init();
|
||||
while (1)
|
||||
{
|
||||
cpu_sleep();
|
||||
}
|
||||
}
|
||||
void dumpstack(void)
|
||||
|
||||
@@ -139,6 +139,7 @@ typedef struct sp_info
|
||||
#endif
|
||||
} sp_info_t;
|
||||
|
||||
#define cpu_sleep() asm volatile("wfi" : : : "memory")
|
||||
#define _barrier() __asm__ __volatile__("" : : : "memory")
|
||||
#define _dmb(ins) \
|
||||
asm volatile("dmb " #ins : : : "memory")
|
||||
|
||||
@@ -38,6 +38,7 @@ enum knl_obj_type {
|
||||
FUTEX_TYPE,
|
||||
SHARE_MEM_TYPE,
|
||||
VMAM_TYPE,
|
||||
SEMA_TYPE,
|
||||
};
|
||||
/**
|
||||
* @brief 以下信息用于调试
|
||||
|
||||
@@ -26,6 +26,7 @@ enum kobj_prot
|
||||
IRQ_PROT,
|
||||
SHARE_MEM_PROT, // 10
|
||||
VMA_PROT,
|
||||
SEMA_PROT,
|
||||
MAX_PROT,
|
||||
};
|
||||
|
||||
|
||||
32
mkrtos_knl/inc/knl/sema.h
Normal file
32
mkrtos_knl/inc/knl/sema.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <spinlock.h>
|
||||
#include <slist.h>
|
||||
|
||||
typedef struct sema
|
||||
{
|
||||
kobject_t kobj; //!< 内核对象节点
|
||||
spinlock_t lock; //!<
|
||||
int cnt; //!< 计数
|
||||
int max_cnt; //!< 最大计数
|
||||
slist_head_t suspend_head; //!< 挂起的线程
|
||||
} sema_t;
|
||||
|
||||
typedef sema_t mutex_t;
|
||||
|
||||
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)
|
||||
{
|
||||
sema_init(lock, 1, 1);
|
||||
}
|
||||
void mutex_lock(mutex_t *lock)
|
||||
{
|
||||
sema_down(lock);
|
||||
}
|
||||
void mutex_unlock(mutex_t *lock)
|
||||
{
|
||||
sema_up(lock);
|
||||
}
|
||||
@@ -29,7 +29,7 @@
|
||||
#define __WEAK__ __attribute__((weak))
|
||||
|
||||
#define container_of(ptr, type, member) \
|
||||
((type *)(((umword_t)(ptr)) - ((umword_t)(&(((type *)0)->member)))))
|
||||
((type *)(((unsigned long)(ptr)) - ((unsigned long)(&(((type *)0)->member)))))
|
||||
|
||||
|
||||
#define USED __attribute__((used))
|
||||
|
||||
205
mkrtos_knl/knl/sema.c
Normal file
205
mkrtos_knl/knl/sema.c
Normal file
@@ -0,0 +1,205 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "kobject.h"
|
||||
#include "spinlock.h"
|
||||
#include "atomics.h"
|
||||
#include "slist.h"
|
||||
#include "thread.h"
|
||||
#include "factory.h"
|
||||
#include "sema.h"
|
||||
#include "init.h"
|
||||
|
||||
#if IS_ENABLED(CONFIG_BUDDY_SLAB)
|
||||
#include <slab.h>
|
||||
static slab_t *sema_slab;
|
||||
#endif
|
||||
|
||||
enum SEMA_OP
|
||||
{
|
||||
SEMA_UP,
|
||||
SEMA_DOWN,
|
||||
};
|
||||
|
||||
static void sema_mem_init(void)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_BUDDY_SLAB)
|
||||
sema_slab = slab_create(sizeof(sema_t), "sema");
|
||||
assert(sema_slab);
|
||||
#endif
|
||||
}
|
||||
INIT_KOBJ_MEM(sema_mem_init);
|
||||
typedef struct sema_wait_item
|
||||
{
|
||||
slist_head_t node;
|
||||
thread_t *thread;
|
||||
} sema_wait_item_t;
|
||||
|
||||
static void sema_wait_item_init(sema_wait_item_t *obj, thread_t *th)
|
||||
{
|
||||
slist_init(&obj->node);
|
||||
obj->thread = th;
|
||||
}
|
||||
|
||||
void sema_up(sema_t *obj)
|
||||
{
|
||||
assert(obj);
|
||||
umword_t status;
|
||||
|
||||
status = spinlock_lock(&obj->lock);
|
||||
if (slist_is_empty(&obj->suspend_head))
|
||||
{
|
||||
if (obj->cnt < obj->max_cnt)
|
||||
{
|
||||
obj->cnt++;
|
||||
}
|
||||
// printk("up0 sema cnt:%d max:%d.\n", obj->cnt, obj->max_cnt);
|
||||
}
|
||||
else
|
||||
{
|
||||
slist_head_t *first_wait_node;
|
||||
sema_wait_item_t *first_wait;
|
||||
|
||||
first_wait_node = slist_first(&obj->suspend_head);
|
||||
first_wait = container_of(first_wait_node, sema_wait_item_t, node);
|
||||
slist_del(first_wait_node);
|
||||
thread_ready_remote(first_wait->thread, FALSE);
|
||||
if (obj->cnt < obj->max_cnt)
|
||||
{
|
||||
obj->cnt++;
|
||||
}
|
||||
// printk("up1 sema cnt:%d max:%d.\n", obj->cnt, obj->max_cnt);
|
||||
}
|
||||
spinlock_set(&obj->lock, status);
|
||||
}
|
||||
void sema_down(sema_t *obj)
|
||||
{
|
||||
assert(obj);
|
||||
thread_t *th = thread_get_current();
|
||||
umword_t status;
|
||||
sema_wait_item_t wait_item;
|
||||
again:
|
||||
status = spinlock_lock(&obj->lock);
|
||||
if (obj->cnt == 0)
|
||||
{
|
||||
sema_wait_item_init(&wait_item, th);
|
||||
slist_add_append(&obj->suspend_head, &wait_item.node);
|
||||
thread_suspend_sw(th, FALSE);
|
||||
spinlock_set(&obj->lock, status);
|
||||
goto again;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(obj->cnt > 0);
|
||||
obj->cnt--;
|
||||
// printk("down sema cnt:%d max:%d.\n", obj->cnt, obj->max_cnt);
|
||||
}
|
||||
spinlock_set(&obj->lock, status);
|
||||
}
|
||||
|
||||
static void sema_syscall(kobject_t *kobj, syscall_prot_t sys_p,
|
||||
msg_tag_t in_tag, entry_frame_t *f)
|
||||
{
|
||||
sema_t *sema = container_of(kobj, sema_t, kobj);
|
||||
msg_tag_t tag = msg_tag_init4(0, 0, 0, -EINVAL);
|
||||
task_t *task = thread_get_current_task();
|
||||
|
||||
if (sys_p.prot != SEMA_PROT)
|
||||
{
|
||||
f->regs[0] = msg_tag_init4(0, 0, 0, -EPROTO).raw;
|
||||
return;
|
||||
}
|
||||
switch (sys_p.op)
|
||||
{
|
||||
case SEMA_UP:
|
||||
{
|
||||
sema_up(sema);
|
||||
tag = msg_tag_init4(0, 0, 0, 0);
|
||||
}
|
||||
break;
|
||||
case SEMA_DOWN:
|
||||
{
|
||||
sema_down(sema);
|
||||
tag = msg_tag_init4(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
f->regs[0] = tag.raw;
|
||||
}
|
||||
static sema_t *sema_create(ram_limit_t *lim, umword_t cnt, umword_t max)
|
||||
{
|
||||
sema_t *kobj = NULL;
|
||||
|
||||
#if IS_ENABLED(CONFIG_BUDDY_SLAB)
|
||||
kobj = mm_limit_alloc_slab(sema_slab, lim);
|
||||
#else
|
||||
kobj = mm_limit_alloc(lim, sizeof(factory_t));
|
||||
#endif
|
||||
if (!kobj)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
sema_init(kobj, cnt, max);
|
||||
|
||||
return kobj;
|
||||
}
|
||||
static void sema_unmap(obj_space_t *obj_space, kobject_t *kobj)
|
||||
{
|
||||
}
|
||||
static void sema_release_stage1(kobject_t *kobj)
|
||||
{
|
||||
/*TODO:*/
|
||||
|
||||
sema_t *sm = container_of(kobj, sema_t, kobj);
|
||||
kobject_invalidate(kobj);
|
||||
}
|
||||
static void sema_release_stage2(kobject_t *kobj)
|
||||
{
|
||||
/*TODO:*/
|
||||
printk("sema 0x%x free.\n", kobj);
|
||||
}
|
||||
|
||||
void sema_init(sema_t *obj, int cnt, int max)
|
||||
{
|
||||
if (max <= 0)
|
||||
{
|
||||
max = 1;
|
||||
}
|
||||
if (cnt < 0)
|
||||
{
|
||||
cnt = 0;
|
||||
}
|
||||
if (cnt > max)
|
||||
{
|
||||
cnt = max;
|
||||
}
|
||||
obj->cnt = cnt;
|
||||
kobject_init(&obj->kobj, SEMA_TYPE);
|
||||
spinlock_init(&obj->lock);
|
||||
slist_init(&obj->suspend_head);
|
||||
obj->max_cnt = max <= 0 ? 1 : max;
|
||||
obj->kobj.invoke_func = sema_syscall;
|
||||
// obj->kobj.put_func = thread_put;
|
||||
obj->kobj.stage_1_func = sema_release_stage1;
|
||||
obj->kobj.stage_2_func = sema_release_stage2;
|
||||
|
||||
printk("sema init cnt:%d max:%d.\n", cnt, max);
|
||||
}
|
||||
static kobject_t *sema_func(ram_limit_t *lim, umword_t arg0, umword_t arg1,
|
||||
umword_t arg2, umword_t arg3)
|
||||
{
|
||||
sema_t *sema = sema_create(lim, arg0, arg1);
|
||||
if (!sema)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return &sema->kobj;
|
||||
}
|
||||
/**
|
||||
* @brief 工厂注册函数
|
||||
*
|
||||
*/
|
||||
static void sema_factory_register(void)
|
||||
{
|
||||
factory_register(sema_func, SEMA_PROT);
|
||||
}
|
||||
INIT_KOBJ(sema_factory_register);
|
||||
@@ -51,6 +51,7 @@ static void knl_main(void)
|
||||
task_t *pos;
|
||||
|
||||
if (slist_is_empty(&del_task_head)) {
|
||||
cpu_sleep();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,3 +11,4 @@ msg_tag_t factory_create_thread(obj_handler_t obj, vpage_t vpage);
|
||||
msg_tag_t factory_create_thread_vcpu(obj_handler_t obj, vpage_t vpage);
|
||||
msg_tag_t factory_create_task(obj_handler_t obj, vpage_t vpage);
|
||||
msg_tag_t facotry_create_share_mem(obj_handler_t obj, vpage_t vpage, umword_t size);
|
||||
msg_tag_t facotry_create_sema(obj_handler_t obj, vpage_t vpage, int cnt, int max);
|
||||
|
||||
@@ -15,6 +15,7 @@ enum kobj_prot
|
||||
IRQ_PROT,
|
||||
SHARE_MEM_PROT, // 10
|
||||
VMA_PROT,
|
||||
SEMA_PROT,
|
||||
MAX_PROT,
|
||||
};
|
||||
|
||||
|
||||
7
mkrtos_user/lib/sys/inc/u_sema.h
Normal file
7
mkrtos_user/lib/sys/inc/u_sema.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "u_prot.h"
|
||||
#include "u_hd_man.h"
|
||||
|
||||
msg_tag_t u_sema_up(obj_handler_t obj);
|
||||
msg_tag_t u_sema_down(obj_handler_t obj);
|
||||
@@ -105,3 +105,22 @@ msg_tag_t facotry_create_share_mem(obj_handler_t obj, vpage_t vpage, umword_t si
|
||||
|
||||
return tag;
|
||||
}
|
||||
msg_tag_t facotry_create_sema(obj_handler_t obj, vpage_t vpage, int cnt, int max)
|
||||
{
|
||||
register volatile umword_t r0 asm(ARCH_REG_0);
|
||||
|
||||
mk_syscall(syscall_prot_create(FACTORY_CREATE_KOBJ, FACTORY_PROT, obj).raw,
|
||||
0,
|
||||
SEMA_PROT,
|
||||
vpage.raw,
|
||||
cnt,
|
||||
max,
|
||||
0);
|
||||
asm __volatile__(""
|
||||
:
|
||||
:
|
||||
: ARCH_REG_0);
|
||||
msg_tag_t tag = msg_tag_init(r0);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
39
mkrtos_user/lib/sys/src/u_sema.c
Normal file
39
mkrtos_user/lib/sys/src/u_sema.c
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "u_types.h"
|
||||
#include "u_prot.h"
|
||||
#include "u_arch.h"
|
||||
|
||||
enum SEMA_OP
|
||||
{
|
||||
SEMA_UP,
|
||||
SEMA_DOWN,
|
||||
};
|
||||
msg_tag_t u_sema_up(obj_handler_t obj)
|
||||
{
|
||||
register volatile umword_t r0 asm(ARCH_REG_0);
|
||||
|
||||
mk_syscall(syscall_prot_create(SEMA_UP, SEMA_PROT, obj).raw,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
msg_tag_t tag = msg_tag_init(r0);
|
||||
|
||||
return tag;
|
||||
}
|
||||
msg_tag_t u_sema_down(obj_handler_t obj)
|
||||
{
|
||||
register volatile umword_t r0 asm(ARCH_REG_0);
|
||||
|
||||
mk_syscall(syscall_prot_create(SEMA_DOWN, SEMA_PROT, obj).raw,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
msg_tag_t tag = msg_tag_init(r0);
|
||||
|
||||
return tag;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
file(GLOB deps src/*.c src/*.S)
|
||||
file(GLOB deps src/*.c src/*.S src/test/*.c)
|
||||
file(GLOB arch_src src/test/${ARCH_NAME}/*.c src/test/${ARCH_NAME}/*.S)
|
||||
|
||||
add_executable(init.elf
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
static void test(void)
|
||||
{
|
||||
#if 0
|
||||
u_sema_test();
|
||||
u_sema_test2();
|
||||
ipi_test();
|
||||
ipc_test();
|
||||
ipc_test2();
|
||||
|
||||
@@ -1,197 +0,0 @@
|
||||
#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_task.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <u_sleep.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define DEBUG_IPC_CALL 1
|
||||
//! 读取系统寄存器
|
||||
#define read_sysreg(reg) ({ \
|
||||
unsigned long _val; \
|
||||
asm volatile("mrs %0, " #reg \
|
||||
: "=r"(_val)); \
|
||||
_val; \
|
||||
})
|
||||
static inline int get_cpu_id(void)
|
||||
{
|
||||
return read_sysreg(mpidr_el1) & 0xff; // 读取该寄存器获取处理器id
|
||||
}
|
||||
|
||||
static umword_t th1_hd = 0;
|
||||
static umword_t th2_hd = 0;
|
||||
static umword_t th3_hd = 0;
|
||||
static umword_t th4_hd = 0;
|
||||
|
||||
static __attribute__((aligned(4096))) char msg_buf0[4096];
|
||||
static __attribute__((aligned(4096))) char msg_buf1[4096];
|
||||
static __attribute__((aligned(4096))) char msg_buf2[4096];
|
||||
static __attribute__((aligned(4096))) char msg_buf3[4096];
|
||||
#define STACK_SIZE 2048
|
||||
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 __attribute__((aligned(8))) uint8_t stack3[STACK_SIZE];
|
||||
|
||||
static void hard_sleep(void)
|
||||
{
|
||||
|
||||
for (volatile int i; i < 10000000; i++)
|
||||
;
|
||||
}
|
||||
static int test_cn = 0;
|
||||
static int to_cpu[4];
|
||||
|
||||
static void thread_test_func(void)
|
||||
{
|
||||
char *buf;
|
||||
umword_t len;
|
||||
|
||||
printf("%s:%d thread 0 init.\n", __func__, __LINE__);
|
||||
while (1)
|
||||
{
|
||||
|
||||
to_cpu[0] = rand() % 4;
|
||||
|
||||
printf("thread 0 to %d cpu.\n", to_cpu[0]);
|
||||
thread_run_cpu(th1_hd, 2, to_cpu[0]);
|
||||
assert(to_cpu[0] == get_cpu_id());
|
||||
|
||||
test_cn++;
|
||||
}
|
||||
}
|
||||
static void thread_test_func2(void)
|
||||
{
|
||||
char *buf;
|
||||
umword_t len;
|
||||
|
||||
printf("%s:%d thread 1 init.\n", __func__, __LINE__);
|
||||
while (1)
|
||||
{
|
||||
to_cpu[1] = rand() % 4;
|
||||
|
||||
printf("thread 1 to %d cpu.\n", to_cpu[1]);
|
||||
thread_run_cpu(th2_hd, 2, to_cpu[1]);
|
||||
assert(to_cpu[1] == get_cpu_id());
|
||||
|
||||
test_cn++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void thread_test_func3(void)
|
||||
{
|
||||
|
||||
printf("%s:%d thread 2 init.\n", __func__, __LINE__);
|
||||
while (1)
|
||||
{
|
||||
to_cpu[2] = rand() % 4;
|
||||
|
||||
printf("thread 2 to %d cpu.\n", to_cpu[2]);
|
||||
thread_run_cpu(th3_hd, 2, to_cpu[2]);
|
||||
assert(to_cpu[2] == get_cpu_id());
|
||||
|
||||
test_cn++;
|
||||
|
||||
}
|
||||
}
|
||||
static void thread_test_func4(void)
|
||||
{
|
||||
|
||||
printf("%s:%d thread 3 init.\n", __func__, __LINE__);
|
||||
while (1)
|
||||
{
|
||||
to_cpu[3] = rand() % 4;
|
||||
|
||||
printf("thread 3 to %d cpu.\n", to_cpu[3]);
|
||||
thread_run_cpu(th4_hd, 2, to_cpu[3]);
|
||||
assert(to_cpu[3] == get_cpu_id());
|
||||
|
||||
test_cn++;
|
||||
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief 启动两个线程并进行ipc测试
|
||||
*
|
||||
*/
|
||||
void ipi_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);
|
||||
|
||||
memset(msg_buf0, 0, sizeof(msg_buf0));
|
||||
memset(msg_buf1, 0, sizeof(msg_buf1));
|
||||
memset(msg_buf2, 0, sizeof(msg_buf2));
|
||||
memset(msg_buf3, 0, sizeof(msg_buf3));
|
||||
|
||||
tag = factory_create_thread(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, th1_hd));
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_bind_task(th1_hd, TASK_THIS);
|
||||
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, TASK_RAM_BASE(), 0);
|
||||
task_set_obj_name(TASK_THIS, th1_hd, "cli_th");
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_run_cpu(th1_hd, 2, 0);
|
||||
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, th2_hd));
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_bind_task(th2_hd, TASK_THIS);
|
||||
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, TASK_RAM_BASE(), 0);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
task_set_obj_name(TASK_THIS, th2_hd, "cli0_th");
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_run_cpu(th2_hd, 2, 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_bind_task(th3_hd, TASK_THIS);
|
||||
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, TASK_RAM_BASE(), 0);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
task_set_obj_name(TASK_THIS, th3_hd, "cli1_th");
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_run_cpu(th3_hd, 2, 0);
|
||||
|
||||
tag = factory_create_thread(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, th4_hd));
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_bind_task(th4_hd, TASK_THIS);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_msg_buf_set(th4_hd, msg_buf3);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_exec_regs(th4_hd, (umword_t)thread_test_func4, (umword_t)stack3 + STACK_SIZE, TASK_RAM_BASE(), 0);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
task_set_obj_name(TASK_THIS, th4_hd, "cli2_th");
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = thread_run_cpu(th4_hd, 2, 0);
|
||||
|
||||
while (test_cn < 1000)
|
||||
;
|
||||
// task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th1_hd));
|
||||
// task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th2_hd));
|
||||
// task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th3_hd));
|
||||
// task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th4_hd));
|
||||
|
||||
}
|
||||
76
mkrtos_user/server/init/src/test/sema_test.c
Normal file
76
mkrtos_user/server/init/src/test/sema_test.c
Normal file
@@ -0,0 +1,76 @@
|
||||
|
||||
#include "u_factory.h"
|
||||
#include "u_sema.h"
|
||||
#include "u_hd_man.h"
|
||||
#include "u_task.h"
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
int u_sema_test(void)
|
||||
{
|
||||
msg_tag_t tag;
|
||||
obj_handler_t sema_hd;
|
||||
|
||||
sema_hd = handler_alloc();
|
||||
assert(sema_hd != HANDLER_INVALID);
|
||||
tag = facotry_create_sema(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, sema_hd), 0, 1);
|
||||
assert(msg_tag_get_val(tag) >= 0);
|
||||
|
||||
u_sema_up(sema_hd);
|
||||
u_sema_down(sema_hd);
|
||||
|
||||
handler_free_umap(sema_hd);
|
||||
return 0;
|
||||
}
|
||||
#include <u_sleep.h>
|
||||
static pthread_t pth1;
|
||||
static pthread_t pth2;
|
||||
static pthread_t pth3;
|
||||
static obj_handler_t sema_hd2;
|
||||
|
||||
static void *thread_th1(void *arg)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
printf("sema_up start\n");
|
||||
u_sema_up(sema_hd2);
|
||||
u_sleep_ms(100);
|
||||
printf("sema_up end\n");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static void *thread_th2(void *arg)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
printf("sema_down start\n");
|
||||
u_sema_down(sema_hd2);
|
||||
u_sleep_ms(50);
|
||||
printf("sema_down end\n");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static void *thread_th3(void *arg)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
printf("sema_down2 start\n");
|
||||
u_sema_down(sema_hd2);
|
||||
u_sleep_ms(50);
|
||||
printf("sema_down2 end\n");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
int u_sema_test2(void)
|
||||
{
|
||||
msg_tag_t tag;
|
||||
|
||||
sema_hd2 = handler_alloc();
|
||||
assert(sema_hd2 != HANDLER_INVALID);
|
||||
tag = facotry_create_sema(FACTORY_PROT,
|
||||
vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, sema_hd2), 0, 1);
|
||||
assert(msg_tag_get_val(tag) >= 0);
|
||||
pthread_create(&pth1, NULL, thread_th1, NULL);
|
||||
pthread_create(&pth1, NULL, thread_th2, NULL);
|
||||
pthread_create(&pth3, NULL, thread_th3, NULL);
|
||||
}
|
||||
@@ -23,3 +23,5 @@ void malloc_test(void);
|
||||
void thread_cpu_test(void);
|
||||
int thread_vcpu_test(void);
|
||||
void ipi_test(void);
|
||||
int u_sema_test(void);
|
||||
int u_sema_test2(void);
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
.text
|
||||
.global thread_vcpu_test_fn
|
||||
.type thread_vcpu_test_fn,%function
|
||||
thread_vcpu_test_fn:
|
||||
//mrs x0, ttbr0_el1
|
||||
mov x0,x0
|
||||
tlbi vmalle1 // Invalidate local TLB
|
||||
dsb nsh
|
||||
mov x0, #0x30000000
|
||||
msr vbar_el1, x0
|
||||
mov x0, #0x40000000
|
||||
msr ttbr0_el1, x0
|
||||
msr ttbr1_el1, x0
|
||||
isb
|
||||
mov x0, #0
|
||||
msr spsr_el1, x0
|
||||
|
||||
mov x0, #1
|
||||
mrs x1, SCTLR_EL1
|
||||
orr x1, x1, x0
|
||||
msr SCTLR_EL1, x1
|
||||
isb
|
||||
ic iallu
|
||||
dsb nsh
|
||||
isb
|
||||
mrs x0, CurrentEL
|
||||
|
||||
mov x0, #0
|
||||
msr spsr_el1, x0
|
||||
adr x0, el0_entry
|
||||
// mov x0, #0x80000
|
||||
msr elr_el1, x0
|
||||
eret
|
||||
el0_entry:
|
||||
//mrs x0, sp_el0
|
||||
mov x0, #0x10000000
|
||||
str x1, [x0]
|
||||
mrs x0, TTBR0_EL2
|
||||
mov x0, x1
|
||||
mov x0, x1
|
||||
mov x0, x1
|
||||
mov x0, x1
|
||||
mov x0, x1
|
||||
mov x0, x1
|
||||
mov x0, x1
|
||||
// wfe //!<陷入内核
|
||||
// wfi
|
||||
|
||||
b .
|
||||
|
||||
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
|
||||
#include <u_thread.h>
|
||||
#include <u_hd_man.h>
|
||||
#include <u_task.h>
|
||||
#include <errno.h>
|
||||
#include <u_prot.h>
|
||||
#include <u_factory.h>
|
||||
#include <u_vmam.h>
|
||||
#include <string.h>
|
||||
|
||||
#define STACK_SIZE 4096
|
||||
static __attribute__((aligned(8))) uint8_t stack0[STACK_SIZE];
|
||||
|
||||
extern void thread_vcpu_test_fn(void);
|
||||
|
||||
int thread_vcpu_test(void)
|
||||
{
|
||||
msg_tag_t tag;
|
||||
|
||||
obj_handler_t th1_hd;
|
||||
umword_t msg_buf_addr;
|
||||
int ret;
|
||||
|
||||
th1_hd = handler_alloc();
|
||||
if (th1_hd == HANDLER_INVALID)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
tag = factory_create_thread_vcpu(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, th1_hd));
|
||||
if (msg_tag_get_prot(tag) < 0)
|
||||
{
|
||||
handler_free(th1_hd);
|
||||
return msg_tag_get_prot(tag);
|
||||
}
|
||||
tag = u_vmam_alloc(VMA_PROT, vma_addr_create(VPAGE_PROT_RW, 0, 0),
|
||||
PAGE_SIZE, 0, (addr_t *)(&msg_buf_addr));
|
||||
if (msg_tag_get_val(tag) < 0)
|
||||
{
|
||||
ret = msg_tag_get_val(tag);
|
||||
goto end;
|
||||
}
|
||||
memset((void *)msg_buf_addr, 0, PAGE_SIZE);
|
||||
|
||||
tag = thread_exec_regs(th1_hd, (umword_t)thread_vcpu_test_fn,
|
||||
(umword_t)stack0 + STACK_SIZE - sizeof(void *),
|
||||
TASK_RAM_BASE(), 0);
|
||||
if (msg_tag_get_prot(tag) < 0)
|
||||
{
|
||||
ret = msg_tag_get_prot(tag);
|
||||
goto end_free_mm;
|
||||
}
|
||||
tag = thread_bind_task(th1_hd, TASK_THIS);
|
||||
if (msg_tag_get_prot(tag) < 0)
|
||||
{
|
||||
goto end_free_mm;
|
||||
}
|
||||
tag = thread_msg_buf_set(th1_hd, (void *)msg_buf_addr);
|
||||
if (msg_tag_get_prot(tag) < 0)
|
||||
{
|
||||
goto end_free_mm;
|
||||
}
|
||||
thread_run(th1_hd, 2); // 优先级默认为2
|
||||
ret = 0;
|
||||
goto end_ok;
|
||||
end_free_mm:
|
||||
u_vmam_free(VMA_PROT, msg_buf_addr, PAGE_SIZE);
|
||||
end:
|
||||
handler_free_umap(th1_hd);
|
||||
end_ok:
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user