Support sleep

This commit is contained in:
tuyuyang 2024-08-25 23:29:34 +08:00
parent 6ae8b6e160
commit 968d66e5a9
13 changed files with 123 additions and 5 deletions

View File

@ -74,7 +74,7 @@ Modification:
#include "cortex_a9.h"
#define NR_CPU 4
#define NR_CPU 1
__attribute__((always_inline, optimize("O0"))) static inline uint32_t user_mode()
{

View File

@ -43,9 +43,9 @@ INC_DIR = -I$(KERNEL_ROOT)/services/shell/letter-shell \
-I$(KERNEL_ROOT)/services/app
ifeq ($(BOARD), imx6q-sabrelite)
all: test_fault simple_client simple_server shell fs_server semaphore_server test_semaphore test_ipc_null test_thread test_irq_hdlr test_irq_block test_irq_send eth_driver epit_server test_net lwip readme.txt | bin
all: test_fault simple_client simple_server shell fs_server semaphore_server test_sleep test_semaphore test_ipc_null test_thread test_irq_hdlr test_irq_block test_irq_send eth_driver epit_server test_net lwip readme.txt | bin
else
all: test_fault simple_client simple_server shell fs_server semaphore_server test_ipc_null test_thread test_semaphore test_net lwip readme.txt eth_hal | bin
all: test_fault simple_client simple_server shell fs_server semaphore_server test_sleep test_ipc_null test_thread test_semaphore test_net lwip readme.txt eth_hal | bin
endif
../tools/mkfs/mkfs ./fs.img $^
@mv $(filter-out readme.txt, $^) bin
@ -69,6 +69,10 @@ epit_server: timer.o epit.o ccm_pll.o usyscall.o arch_usyscall.o libserial.o pri
@${objdump} -S $@ > $@.asm
endif
test_sleep: test_sleep.o libserial.o printf.o usyscall.o arch_usyscall.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm
test_semaphore: test_semaphore.o libserial.o printf.o usyscall.o arch_usyscall.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm

View File

@ -0,0 +1,24 @@
/*
* 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 "libserial.h"
#include "usyscall.h"
int main(int argc, char* argv[])
{
while (true) {
printf("sleep for 2 seconds\n");
sleep(2000);
}
exit(0);
}

View File

@ -154,3 +154,8 @@ bool semaphore_signal(int sem_id)
{
return syscall(SYSCALL_SEMAPHORE, (intptr_t)SYS_SEM_SIGNAL, (intptr_t)sem_id, 0, 0);
}
int sleep(intptr_t ms)
{
return syscall(SYSCALL_SLEEP, (intptr_t)ms, 0, 0, 0);
}

View File

@ -34,6 +34,7 @@
#define SYSCALL_KILL 12 // kill the task by id
#define SYSCALL_SEMAPHORE 13 // semaphore related operations
#define SYSCALL_SLEEP 14 // sleep
// clang-format on
typedef enum {
@ -106,3 +107,5 @@ int semaphore_new(int val);
bool semaphore_free(int sem_id);
bool semaphore_wait(int sem_id);
bool semaphore_signal(int sem_id);
int sleep(intptr_t ms);

View File

@ -48,6 +48,7 @@ Modification:
#define SYSCALL_KILL 12 // kill the task by id
#define SYSCALL_SEMAPHORE 13 // semaphore related operations
#define SYSCALL_SLEEP 14 // sleep
// clang-format on
#ifndef __ASSEMBLER__
@ -113,4 +114,5 @@ int sys_unbind_irq_all(struct Thread* task);
int sys_unbind_irq(struct Thread* task, int irq_num);
int sys_semaphore(sys_sem_option op, int sem_id);
int sys_sleep(intptr_t ms);
#endif

View File

@ -44,6 +44,7 @@ Modification:
#define TASK_MAX_PRIORITY 32
#define TASK_DEFAULT_PRIORITY 2
#define TASK_NAME_MAX_LEN 16
#define SLEEP_MONITOR_CORE 0
enum ProcState {
INIT = 0,
@ -51,6 +52,7 @@ enum ProcState {
RUNNING,
DEAD,
BLOCKED,
SLEEPING,
NEVER_RUN,
};
@ -72,6 +74,10 @@ struct ThreadContext {
struct trapframe* trapframe;
};
struct TaskSleepContext {
int64_t remain_ms;
};
/* Process Control Block */
struct Thread {
/* task name */
@ -97,6 +103,7 @@ struct Thread {
/* task schedule attributes */
struct double_list_node node;
struct TaskSleepContext sleep_context;
enum ProcState state;
int priority; // priority
int remain_tick;
@ -114,6 +121,7 @@ struct XiziTaskManager {
struct double_list_node task_list_head[TASK_MAX_PRIORITY]; /* list of task control blocks that are allocated */
struct double_list_node task_running_list_head;
struct double_list_node task_blocked_list_head;
struct double_list_node task_sleep_list_head;
struct XiziSemaphorePool semaphore_pool;
/* mem allocator */

View File

@ -1,6 +1,7 @@
SRC_FILES := syscall.c \
sys_spawn.c \
sys_thread.c \
sys_sleep.c \
sys_yield.c \
sys_register_as_server.c \
sys_connect_session.c \

View File

@ -0,0 +1,45 @@
/*
* 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.
*/
/**
* @file sys_sleep.c
* @brief task sleep
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.08.25
*/
/*************************************************
File name: sys_sleep.c
Description:
Others:
History:
1. Date: 2023-08-28
Author: AIIT XUOS Lab
Modification:
1. first version
*************************************************/
#include "multicores.h"
#include "syscall.h"
#include "task.h"
#include "assert.h"
int sys_sleep(intptr_t ms)
{
struct Thread* cur_task = cur_cpu()->task;
xizi_task_manager.task_yield_noschedule(cur_task, false);
xizi_task_manager.task_block(&xizi_task_manager.task_sleep_list_head, cur_task);
cur_task->state = SLEEPING;
cur_task->sleep_context.remain_ms = ms;
return 0;
}

View File

@ -91,6 +91,12 @@ void show_tasks(void)
SHOWTASK_TASK_BASE_INFO(task);
}
DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_sleep_list_head, node)
{
LOG_PRINTF("%-8s", "SLEEP");
SHOWTASK_TASK_BASE_INFO(task);
}
struct ksemaphore* sem = NULL;
DOUBLE_LIST_FOR_EACH_ENTRY(sem, &xizi_task_manager.semaphore_pool.sem_list_guard, sem_list_node)
{

View File

@ -80,6 +80,9 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u
case SYSCALL_SEMAPHORE:
ret = sys_semaphore((sys_sem_option)param1, (int)param2);
break;
case SYSCALL_SLEEP:
ret = sys_sleep((intptr_t)param1);
break;
default:
ERROR("Unsurport syscall(%d) right now\n", sys_num);
ret = -1;

View File

@ -38,6 +38,7 @@ Modification:
#include "scheduler.h"
#include "syscall.h"
#include "task.h"
#include "trap_common.h"
struct CPU global_cpus[NR_CPU];
uint32_t ready_task_priority;
@ -70,6 +71,7 @@ static void _task_manager_init()
}
doubleListNodeInit(&xizi_task_manager.task_blocked_list_head);
doubleListNodeInit(&xizi_task_manager.task_running_list_head);
doubleListNodeInit(&xizi_task_manager.task_sleep_list_head);
// init task (slab) allocator
slab_init(&xizi_task_manager.memspace_allocator, sizeof(struct MemSpace));
slab_init(&xizi_task_manager.task_allocator, sizeof(struct Thread));
@ -286,6 +288,7 @@ extern void context_switch(struct context**, struct context*);
static void _scheduler(struct SchedulerRightGroup right_group)
{
struct MmuCommonDone* p_mmu_driver = AchieveResource(&right_group.mmu_driver_tag);
struct XiziTrapDriver* p_intr_driver = AchieveResource(&right_group.intr_driver_tag);
struct Thread* next_task;
struct CPU* cpu = cur_cpu();
@ -347,7 +350,7 @@ static void _task_block(struct double_list_node* head, struct Thread* task)
static void _task_unblock(struct Thread* task)
{
assert(task != NULL);
assert(task->state == BLOCKED);
assert(task->state == BLOCKED || task->state == SLEEPING);
task_node_leave_list(task);
task->state = READY;
task_node_add_to_ready_list_back(task);

View File

@ -69,6 +69,8 @@ int xizi_clock_handler(int irq, void* tf, void* arg)
if (p_clock_driver->is_timer_expired()) {
p_clock_driver->clear_clock_intr();
global_tick++;
// handle current thread
struct Thread* current_task = cur_cpu()->task;
if (current_task) {
current_task->remain_tick--;
@ -77,6 +79,18 @@ int xizi_clock_handler(int irq, void* tf, void* arg)
xizi_task_manager.task_yield_noschedule(current_task, false);
}
}
// todo: cpu 0 will handle sleeping thread
struct Thread* thread = NULL;
DOUBLE_LIST_FOR_EACH_ENTRY(thread, &xizi_task_manager.task_sleep_list_head, node)
{
assert(thread->state == SLEEPING);
thread->sleep_context.remain_ms--;
if (thread->sleep_context.remain_ms <= 0) {
xizi_task_manager.task_unblock(thread);
break;
}
}
}
return 0;
}