Support Userland semaphore server

This commit is contained in:
TXuian 2024-05-20 14:29:22 +08:00
parent 29f1df2eea
commit f4e193a738
21 changed files with 313 additions and 34 deletions

View File

@ -1,8 +1,7 @@
export CROSS_COMPILE ?= arm-none-eabi-
export DEVICE = -march=armv7-a -mtune=cortex-a9 -mfpu=vfpv3-d16 -ftree-vectorize -ffast-math -mfloat-abi=softfp
# export CFLAGS := $(DEVICE) -std=c11 -Wall -O2 -g -gdwarf-2 -Wnull-dereference -Waddress -Warray-bounds -Wchar-subscripts -Wimplicit-int -Wimplicit-function-declaration -Wcomment -Wformat -Wmissing-braces -Wnonnull -Wparentheses -Wpointer-sign -Wreturn-type -Wsequence-point -Wstrict-aliasing -Wstrict-overflow=1 -Wswitch -Wtrigraphs -Wuninitialized -Wunknown-pragmas -Wunused-function -Wunused-label -Wunused-value -Wunused-variable -Wunused-function
# export CFLAGS := $(DEVICE) -std=c11 -Wall -O2 -g -gdwarf-2 -Waddress -Warray-bounds -Wchar-subscripts -Wimplicit-int -Wimplicit-function-declaration -Wcomment -Wformat -Wmissing-braces -Wnonnull -Wparentheses -Wpointer-sign -Wreturn-type -Wsequence-point -Wstrict-aliasing -Wstrict-overflow=1 -Wswitch -Wtrigraphs -Wuninitialized -Wunknown-pragmas -Wunused-function -Wunused-label -Wunused-value -Wunused-variable -Wunused-function
export CFLAGS := $(DEVICE) -std=c11 -Wall -O0 -g -gdwarf-2 -Waddress -Warray-bounds -Wchar-subscripts -Wimplicit-int -Wimplicit-function-declaration -Wcomment -Wformat -Wmissing-braces -Wnonnull -Wparentheses -Wpointer-sign -Wreturn-type -Wsequence-point -Wstrict-aliasing -Wstrict-overflow=1 -Wswitch -Wtrigraphs -Wuninitialized -Wunknown-pragmas -Wunused-function -Wunused-label -Wunused-value -Wunused-variable -Wunused-function
export CFLAGS := $(DEVICE) -std=c11 -Wall -O2 -g -gdwarf-2 -Waddress -Warray-bounds -Wchar-subscripts -Wimplicit-int -Wimplicit-function-declaration -Wcomment -Wformat -Wmissing-braces -Wnonnull -Wparentheses -Wpointer-sign -Wreturn-type -Wsequence-point -Wstrict-aliasing -Wstrict-overflow=1 -Wswitch -Wtrigraphs -Wuninitialized -Wunknown-pragmas -Wunused-function -Wunused-label -Wunused-value -Wunused-variable -Wunused-function
export AFLAGS := -c $(DEVICE) -x assembler-with-cpp -D__ASSEMBLY__ -gdwarf-2
# export LFLAGS := $(DEVICE) -Wl,-Map=XiZi-imx6q-sabrelite.map,-cref,-u,_boot_start -T $(KERNEL_ROOT)/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/nxp_imx6q_sabrelite.lds
export LFLAGS := $(DEVICE) --specs=nosys.specs -Wl,-Map=XiZi-imx6q-sabrelite.map,-cref,-u,_boot_start -T $(KERNEL_ROOT)/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/nxp_imx6q_sabrelite.lds

View File

@ -1,5 +1,5 @@
SRC_DIR := fs shell lib boards drivers tools app
SRC_DIR := fs shell lib boards drivers semaphore tools app
include $(KERNEL_ROOT)/compiler.mk

View File

@ -22,11 +22,12 @@ INC_DIR = -I$(KERNEL_ROOT)/services/shell/letter-shell \
-I$(KERNEL_ROOT)/services/lib/serial \
-I$(KERNEL_ROOT)/services/lib/usyscall \
-I$(KERNEL_ROOT)/services/fs/libfs \
-I$(KERNEL_ROOT)/services/semaphore \
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \
-I$(KERNEL_ROOT)/services/app
ifeq ($(BOARD), imx6q-sabrelite)
all: init test_fs simple_client simple_server shell fs_server test_thread test_irq_hdlr test_irq_block test_irq_send eth_driver epit_server readme.txt | bin
all: init test_fs simple_client simple_server shell fs_server semaphore_server test_thread test_irq_hdlr test_irq_block test_irq_send eth_driver epit_server readme.txt | bin
else
all: init test_fs simple_client simple_server shell fs_server test_irq_hdlr readme.txt | bin
endif
@ -52,7 +53,11 @@ epit_server: timer.o epit.o ccm_pll.o usyscall.o arch_usyscall.o libserial.o pri
@${objdump} -S $@ > $@.asm
endif
test_thread: test_thread.o libserial.o printf.o usyscall.o arch_usyscall.o
semaphore_server: semaphore_server.o libserial.o printf.o usyscall.o arch_usyscall.o libipc.o session.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm
test_thread: test_thread.o libserial.o printf.o usyscall.o arch_usyscall.o libfs.o libsemaphore.o libipc.o session.o libmem.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm
@ -64,19 +69,19 @@ test_irq_hdlr: test_irq_handler.o libserial.o printf.o libipc.o session.o usysca
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm
shell: shell_port.o libserial.o printf.o shell_cmd_list.o shell.o shell_ext.o libfs_to_client.o libipc.o session.o usyscall.o arch_usyscall.o libmem.o
shell: shell_port.o libserial.o printf.o shell_cmd_list.o shell.o shell_ext.o libfs.o libipc.o session.o usyscall.o arch_usyscall.o libmem.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm
init: init.o libfs_to_client.o libipc.o session.o libserial.o printf.o usyscall.o arch_usyscall.o libmem.o
init: init.o libfs.o libipc.o session.o libserial.o printf.o usyscall.o arch_usyscall.o libmem.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm
test_fs: test_fs.o libfs_to_client.o libipc.o session.o libserial.o printf.o usyscall.o arch_usyscall.o libmem.o
test_fs: test_fs.o libfs.o libipc.o session.o libserial.o printf.o usyscall.o arch_usyscall.o libmem.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm
simple_client: simple_client.o libserial.o printf.o libipc.o session.o simple_service.o libfs_to_client.o usyscall.o arch_usyscall.o libmem.o
simple_client: simple_client.o libserial.o printf.o libipc.o session.o simple_service.o libfs.o usyscall.o arch_usyscall.o libmem.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm
@ -84,7 +89,7 @@ simple_server: simple_server.o libserial.o printf.o libipc.o session.o simple_se
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm
fs_server: fs_server.o libfs_to_client.o fs.o libserial.o printf.o libipc.o session.o block_io.o usyscall.o arch_usyscall.o libmem.o
fs_server: fs_server.o libfs.o fs.o libserial.o printf.o libipc.o session.o block_io.o usyscall.o arch_usyscall.o libmem.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm

View File

@ -12,7 +12,7 @@
// init: The initial user-level program
#include <stdbool.h>
#include "libfs_to_client.h"
#include "libfs.h"
#include "libserial.h"
#include "usyscall.h"

View File

@ -14,7 +14,7 @@
#include <stdint.h>
#include <stdlib.h>
#include "libfs_to_client.h"
#include "libfs.h"
#include "libserial.h"
#include "simple_service.h"
#include "usyscall.h"

View File

@ -15,8 +15,8 @@
#include <stdbool.h>
#include <string.h>
#include "libfs.h"
#include "libserial.h"
#include "libfs_to_client.h"
#include "usyscall.h"
#define BLOCK_SIZE 256

View File

@ -10,38 +10,91 @@
* See the Mulan PSL v2 for more details.
*/
#include "libfs.h"
#include "libsemaphore.h"
#include "libserial.h"
#include "usyscall.h"
static int global_value;
static sem_t sem;
static char sem_server_name[] = "SemTestServer";
int sub_thread_entry(int argc, char** argv)
{
for (int i = 0; i < 1000; i++) {
for (int i = 0; i < 100; i++) {
global_value++;
printf("[gval]: %d\n", global_value);
}
struct Session sem_session;
while (connect_session(&sem_session, sem_server_name, 4096) < 0) {
yield(SYS_TASK_YIELD_NO_REASON);
}
printf("Thread signal sem.\n");
sem_signal(&sem_session, &sem);
exit(0);
return 0;
}
static char sem_file_name[] = "/semaphore_server";
int main(int argc, char** argv)
{
global_value = 0;
for (int i = 0; i < 10; i++) {
global_value++;
printf("|gval|: %d\n", global_value);
}
printf("Test Create Semaphore.\n");
struct Session sem_session;
bool spawn_sem_server = false;
while (connect_session(&sem_session, sem_server_name, 4096) < 0) {
if (!spawn_sem_server) {
struct Session fs_session;
printf("Connect FS.\n");
if (connect_session(&fs_session, "MemFS", 8192) < 0) {
printf("Connect FS failed.\n");
exit(1);
}
printf("Loading semaphore server.\n");
int fd = -1;
if ((fd = open(&fs_session, sem_file_name)) < 0) {
printf("Open %s failed.\n", sem_file_name);
free_session(&fs_session);
exit(1);
}
printf("Spawn semaphore server.\n");
char* sem_server_params[] = { sem_server_name, sem_server_name, NULL };
if (spawn(&fs_session, fd, read, fsize, sem_server_name, sem_server_params) < 0) {
printf("Spawn %s failed.\n", sem_file_name);
free_session(&fs_session);
exit(1);
}
spawn_sem_server = true;
free_session(&fs_session);
}
}
printf("Create new sem.\n");
sem_create(&sem_session, &sem, 0);
printf("Create new thread.\n");
char* task_param[2] = { "add_gval", NULL };
int tid = thread(sub_thread_entry, "add_gval", task_param);
for (int i = 0; i < 1000; i++) {
global_value++;
printf("|gval|: %d\n", global_value);
int nr_thread = 0;
for (int i = 0; i < 128; i++) {
int tid = thread(sub_thread_entry, "add_gval", task_param);
if (tid > 0) {
nr_thread++;
}
}
printf("Main thread waiting for sem for %d times.\n", nr_thread);
for (int i = 0; i < nr_thread; i++) {
int sem_wait_ret = sem_wait(&sem_session, &sem, 0);
}
printf("Main thread sem %d wait return, global val: %d.\n", sem, global_value);
sem_delete(&sem_session, &sem);
free_session(&sem_session);
exit(0);
return 0;
}

View File

@ -25,7 +25,7 @@ INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \
-I$(KERNEL_ROOT)/services/app
board: libserial.o stub.o arch_usyscall.o
@mv $^ ../../app
@mv $^ $(KERNEL_ROOT)/services/app
%.o: %.c
@echo "cc $^"

View File

@ -14,7 +14,7 @@
#include "block_io.h"
#include "fs.h"
#include "libfs_to_client.h"
#include "libfs.h"
#include "libserial.h"
#include "usyscall.h"

View File

@ -23,8 +23,8 @@ INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \
-I$(KERNEL_ROOT)/services/app
fs_server: libfs_to_client.o
@mv $^ ../../app
fs_server: libfs.o
@mv $^ $(KERNEL_ROOT)/services/app
%.o: %.c
@echo "cc $^"

View File

@ -9,7 +9,7 @@
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "libfs_to_client.h"
#include "libfs.h"
IPC_INTERFACE(Ipc_ls, 1, path, strlen(path) + 1);
int ls(struct Session* session, char* path)

View File

@ -23,7 +23,7 @@ INC_DIR = -I$(KERNEL_ROOT)/services/lib/ipc \
-I$(KERNEL_ROOT)/services/app
all: libipc.o session.o
@mv $^ ../../app
@mv $^ $(KERNEL_ROOT)/services/app
%.o: %.c
@echo "cc $^"

View File

@ -21,7 +21,7 @@ INC_DIR = -I$(KERNEL_ROOT)/services/app \
-I$(KERNEL_ROOT)/services/lib/ipc
all: libmem.o
@mv $^ ../../app
@mv $^ $(KERNEL_ROOT)/services/app
%.o: %.c
@echo "cc $^"

View File

@ -21,7 +21,7 @@ INC_DIR = -I$(KERNEL_ROOT)/services/app \
-I$(KERNEL_ROOT)/services/lib/ipc
all: usyscall.o
@mv $^ ../../app
@mv $^ $(KERNEL_ROOT)/services/app
%.o: %.c
@echo "cc $^"

View File

@ -0,0 +1,29 @@
ifeq ($(BOARD), imx6q-sabrelite)
toolchain ?= arm-none-eabi-
user_ldflags = -N -Ttext 0
cflags = -std=c11 -march=armv7-a -mtune=cortex-a9 -nostdlib -nodefaultlibs -mfloat-abi=soft -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -ggdb -Wno-unused -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie
endif
ifeq ($(BOARD), zynq7000-zc702)
toolchain ?= arm-xilinx-eabi-
user_ldflags = --start-group,-lgcc,-lc,--end-group
cflags = -std=c11 -march=armv7-a -mtune=cortex-a9 -nostdlib -nodefaultlibs -mfloat-abi=soft -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -ggdb -Wno-unused -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie
#cflags = -Wall -g -std=c11
endif
cc = ${toolchain}gcc
ld = ${toolchain}g++
objdump = ${toolchain}objdump
c_useropts = -O2
INC_DIR = -I$(KERNEL_ROOT)/services/lib/ipc \
-I$(KERNEL_ROOT)/services/lib/serial \
-I$(KERNEL_ROOT)/services/lib/usyscall \
-I$(KERNEL_ROOT)/services/semaphore \
-I$(KERNEL_ROOT)/services/app
fs_server: libsemaphore.o semaphore_server.o
@mv $^ $(KERNEL_ROOT)/services/app
%.o: %.c
@echo "cc $^"
@${cc} ${cflags} ${c_useropts} ${INC_DIR} -o $@ -c $^

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "libsemaphore.h"
IPC_INTERFACE(Ipc_sem_create, 2, sem, count, sizeof(sem_t), sizeof(int));
sem_err_t sem_create(struct Session* session, sem_t* sem, int count)
{
return IPC_CALL(Ipc_sem_create)(session, sem, &count);
}
IPC_INTERFACE(Ipc_sem_delete, 1, sem, sizeof(sem_t));
sem_err_t sem_delete(struct Session* session, sem_t* sem)
{
return IPC_CALL(Ipc_sem_delete)(session, sem);
}
IPC_INTERFACE(Ipc_sem_signal, 1, sem, sizeof(sem_t));
int sem_signal(struct Session* session, sem_t* sem)
{
return IPC_CALL(Ipc_sem_signal)(session, sem);
}
IPC_INTERFACE(Ipc_sem_wait, 2, sem, timeout, sizeof(sem_t), sizeof(int));
int sem_wait(struct Session* session, sem_t* sem, int timeout)
{
return IPC_CALL(Ipc_sem_wait)(session, sem, &timeout);
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "libipc.h"
#define MAX_SUPPORT_SEMAPHORES NR_MAX_SESSION
typedef uint32_t sem_t;
typedef int sem_err_t;
enum {
SEMAPHORE_ERR = -1,
SEMAPHORE_SUC = 1,
};
IPC_SERVICES(IpcSemaphoreServer, Ipc_sem_create, Ipc_sem_delete, Ipc_sem_signal, Ipc_sem_wait);
sem_err_t sem_create(struct Session* session, sem_t* sem, int count);
sem_err_t sem_delete(struct Session* session, sem_t* sem);
int sem_signal(struct Session* session, sem_t* sem);
int sem_wait(struct Session* session, sem_t* sem, int timeout);

View File

@ -0,0 +1,121 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "libsemaphore.h"
#include "libserial.h"
#include "usyscall.h"
struct Semaphore {
bool valid;
int count;
};
struct Semaphore sem_pool[MAX_SUPPORT_SEMAPHORES];
int IPC_DO_SERVE_FUNC(Ipc_sem_create)(sem_t* sem, int* count)
{
int idx = 0;
for (idx = 0; idx < MAX_SUPPORT_SEMAPHORES; idx++) {
if (!sem_pool[idx].valid) {
break;
}
}
if (idx == MAX_SUPPORT_SEMAPHORES) {
return SEMAPHORE_ERR;
}
sem_pool[idx].valid = true;
sem_pool[idx].count = *count;
*sem = idx;
return SEMAPHORE_SUC;
}
int IPC_DO_SERVE_FUNC(Ipc_sem_delete)(sem_t* sem)
{
if (*sem < 0 || *sem > MAX_SUPPORT_SEMAPHORES) {
return SEMAPHORE_ERR;
}
if (!sem_pool[*sem].valid) {
return SEMAPHORE_ERR;
}
sem_pool[*sem].valid = false;
return SEMAPHORE_SUC;
}
int IPC_DO_SERVE_FUNC(Ipc_sem_wait)(sem_t* sem, int* timeout)
{
if (*sem < 0 || *sem > MAX_SUPPORT_SEMAPHORES) {
return SEMAPHORE_ERR;
}
/// @todo support timeout
// return if sem is freed(no valid) or sem count is sufficient
if (!sem_pool[*sem].valid || sem_pool[*sem].count > 0) {
sem_pool[*sem].count--;
return SEMAPHORE_SUC;
}
// block current session
delay_session();
return SEMAPHORE_ERR;
}
int IPC_DO_SERVE_FUNC(Ipc_sem_signal)(sem_t* sem)
{
if (*sem < 0 || *sem >= MAX_SUPPORT_SEMAPHORES) {
return SEMAPHORE_ERR;
}
if (!sem_pool[*sem].valid) {
return SEMAPHORE_ERR;
}
sem_pool[*sem].count++;
return SEMAPHORE_SUC;
}
IPC_SERVER_INTERFACE(Ipc_sem_create, 2);
IPC_SERVER_INTERFACE(Ipc_sem_delete, 1);
IPC_SERVER_INTERFACE(Ipc_sem_signal, 1);
IPC_SERVER_INTERFACE(Ipc_sem_wait, 2);
IPC_SERVER_REGISTER_INTERFACES(IpcSemaphoreServer, 4, //
Ipc_sem_create, Ipc_sem_delete, Ipc_sem_signal, Ipc_sem_wait);
int main(int argc, char** argv)
{
/// @todo support custom server name
static char default_server_name[] = "DefaultSemaphoreServer";
char* server_name = default_server_name;
if (argc == 2) {
server_name = argv[1];
}
if (register_server(server_name) < 0) {
printf("[%s] Register server failed.\n", server_name);
exit(1);
}
for (int idx = 0; idx < MAX_SUPPORT_SEMAPHORES; idx++) {
sem_pool[idx].valid = false;
}
ipc_server_loop(&IpcSemaphoreServer);
// never reaching here
exit(0);
return 0;
}

View File

@ -24,7 +24,7 @@ INC_DIR = -I$(KERNEL_ROOT)/services/app \
-I$(KERNEL_ROOT)/services/boards/$(BOARD)
all: shell_cmd_list.o shell_ext.o shell.o
@mv $^ ../../app
@mv $^ $(KERNEL_ROOT)/services/app
shell_cmd_list.o: shell_cmd_list.c
@echo "cc shell_cmd_list"

View File

@ -17,7 +17,7 @@
#include "shell_cfg.h"
#include "shell_ext.h"
#include "libfs_to_client.h"
#include "libfs.h"
#include "libipc.h"
#if SHELL_USING_CMD_EXPORT == 1