增加简单的sema&mutex支持

This commit is contained in:
zhangzheng
2024-08-07 22:51:57 +08:00
parent 1132f9997e
commit 74f3c6760a
20 changed files with 391 additions and 322 deletions

View File

@@ -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);

View File

@@ -15,6 +15,7 @@ enum kobj_prot
IRQ_PROT,
SHARE_MEM_PROT, // 10
VMA_PROT,
SEMA_PROT,
MAX_PROT,
};

View 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);

View File

@@ -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;
}

View 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;
}

View File

@@ -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

View File

@@ -36,6 +36,8 @@
static void test(void)
{
#if 0
u_sema_test();
u_sema_test2();
ipi_test();
ipc_test();
ipc_test2();

View File

@@ -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));
}

View 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);
}

View File

@@ -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);

View File

@@ -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 .

View File

@@ -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;
}