diff --git a/Ubiquitous/XiZi_AIoT/services/app/Makefile b/Ubiquitous/XiZi_AIoT/services/app/Makefile index 1cab0da46..a7d4c0684 100644 --- a/Ubiquitous/XiZi_AIoT/services/app/Makefile +++ b/Ubiquitous/XiZi_AIoT/services/app/Makefile @@ -33,9 +33,9 @@ INC_DIR = -I$(KERNEL_ROOT)/services/shell/letter-shell \ -I$(KERNEL_ROOT)/services/app ifeq ($(BOARD), imx6q-sabrelite) -all: init test_fault simple_client simple_server shell fs_server semaphore_server test_ipc_null test_thread test_irq_hdlr test_irq_block test_irq_send eth_driver epit_server readme.txt | bin +all: init 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 readme.txt | bin else -all: init test_fault simple_client simple_server shell fs_server readme.txt | bin +all: init test_fault simple_client simple_server shell fs_server test_ipc_null test_thread test_semaphore readme.txt | bin endif ../tools/mkfs/mkfs ./fs.img $^ @mv $(filter-out readme.txt, $^) bin @@ -59,6 +59,10 @@ epit_server: timer.o epit.o ccm_pll.o usyscall.o arch_usyscall.o libserial.o pri @${objdump} -S $@ > $@.asm endif +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 + test_ipc_null: test_ipc_null.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 diff --git a/Ubiquitous/XiZi_AIoT/services/app/test_fault.c b/Ubiquitous/XiZi_AIoT/services/app/test_fault.c index 03d8e4b32..a38563c57 100644 --- a/Ubiquitous/XiZi_AIoT/services/app/test_fault.c +++ b/Ubiquitous/XiZi_AIoT/services/app/test_fault.c @@ -18,7 +18,6 @@ #include "libserial.h" #include "usyscall.h" -#define BLOCK_SIZE 256 int main(int argc, char* argv[]) { printf("Test memry error %s.\n", 0x50000000); diff --git a/Ubiquitous/XiZi_AIoT/services/app/test_semaphore.c b/Ubiquitous/XiZi_AIoT/services/app/test_semaphore.c new file mode 100644 index 000000000..a682ec11b --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/app/test_semaphore.c @@ -0,0 +1,71 @@ +/* + * 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 + +#include "libserial.h" +#include "usyscall.h" + +enum { + NR_THREADS = 16, + LOOP_TIMES = 0x1000000, +}; + +static int sem_id = -1; +static uint32_t sum = 0; +static int nr_thds = NR_THREADS; + +int do_calculation(int argc, char** argv) +{ + for (uint32_t i = 0; i < LOOP_TIMES; i++) { + sum++; + } + + printf("test semaphore thd signal.\n"); + semaphore_signal(sem_id); + + char* params[] = { "do_cal", NULL }; + if (nr_thds != 0) { + int tid = thread(do_calculation, "test_sem_thd", params); + nr_thds--; + } + + exit(0); + return 0; +} + +int main(int argc, char** argv) +{ + printf("Test Semaphore.\n"); + sem_id = semaphore_new(0); + if (sem_id < 0) { + printf("new a kernel sem failed.\n"); + exit(1); + } + + sum = 0; + + nr_thds = NR_THREADS; + char* params[] = { "do_cal", NULL }; + if (nr_thds != 0) { + int tid = thread(do_calculation, "test_sem_thd", params); + nr_thds--; + } + + for (int i = 0; i < NR_THREADS; i++) { + semaphore_wait(sem_id); + } + + printf("test thread sum after %d signal: 0x%x\n", NR_THREADS, sum); + + exit(0); + return 0; +} diff --git a/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.c b/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.c index 1e3d2da9b..9331c8546 100644 --- a/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.c +++ b/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.c @@ -109,4 +109,24 @@ int mmap(uintptr_t vaddr, uintptr_t paddr, int len, bool is_dev) int register_irq(int irq, int opcode) { return syscall(SYSCALL_REGISTER_IRQ, (intptr_t)irq, (intptr_t)opcode, 0, 0); +} + +int semaphore_new(int val) +{ + return syscall(SYSCALL_SEMAPHORE, (intptr_t)SYS_SEM_NEW, (intptr_t)val, 0, 0); +} + +bool semaphore_free(int sem_id) +{ + return syscall(SYSCALL_SEMAPHORE, (intptr_t)SYS_SEM_FREE, (intptr_t)sem_id, 0, 0); +} + +bool semaphore_wait(int sem_id) +{ + return syscall(SYSCALL_SEMAPHORE, (intptr_t)SYS_SEM_WAIT, (intptr_t)sem_id, 0, 0); +} + +bool semaphore_signal(int sem_id) +{ + return syscall(SYSCALL_SEMAPHORE, (intptr_t)SYS_SEM_SIGNAL, (intptr_t)sem_id, 0, 0); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.h b/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.h index eda606788..8c6822ede 100644 --- a/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.h +++ b/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.h @@ -32,6 +32,8 @@ #define SYSCALL_REGISTER_IRQ 11 // #define SYSCALL_KILL 12 // kill the task by id + +#define SYSCALL_SEMAPHORE 13 // semaphore related operations // clang-format on typedef enum { @@ -58,6 +60,13 @@ typedef union { int priority; } sys_state_info; +typedef enum { + SYS_SEM_NEW = 0, + SYS_SEM_FREE, + SYS_SEM_SIGNAL, + SYS_SEM_WAIT, +} sys_sem_option; + typedef int (*ipc_read_fn)(struct Session* session, int fd, char* dst, int offset, int len); typedef int (*ipc_fsize_fn)(struct Session* session, int fd); typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offset, int len); @@ -69,15 +78,23 @@ int thread(void* entry, char* name, char** argv); void exit(int status); int yield(task_yield_reason reason); int kill(int pid); + int register_server(char* name); int session(char* path, int capacity, struct Session* user_session); int poll_session(struct Session* userland_session_arr, int arr_capacity); int close_session(struct Session* session); +int register_irq(int irq, int opcode); + +int mmap(uintptr_t vaddr, uintptr_t paddr, int len, bool is_dev); + int task_heap_base(); int get_memblock_info(sys_state_info* info); int set_priority(sys_state_info* info); int show_task(); int show_mem(); int show_cpu(); -int mmap(uintptr_t vaddr, uintptr_t paddr, int len, bool is_dev); -int register_irq(int irq, int opcode); \ No newline at end of file + +int semaphore_new(int val); +bool semaphore_free(int sem_id); +bool semaphore_wait(int sem_id); +bool semaphore_signal(int sem_id); \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/ksemaphore.h b/Ubiquitous/XiZi_AIoT/softkernel/include/ksemaphore.h new file mode 100644 index 000000000..99efd6523 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/ksemaphore.h @@ -0,0 +1,51 @@ +/* + * 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 semaphore.h + * @brief semaphore implementation + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2024.05.28 + */ +#pragma once + +#include +#include + +#include "list.h" +#include "object_allocator.h" + +/// @warning this is no in use +enum { + KSEM_NOWAIT = -1, +}; + +struct ksemaphore { + uint32_t id; + int val; + /* list of waiting threads */ + struct double_list_node wait_list_guard; + /* list to manage semaphores */ + /// @todo Use RB-Tree to manage all semaphores + struct double_list_node sem_list_node; +}; + +struct XiziSemaphorePool { + uint32_t next_sem_id; + struct slab_allocator allocator; + struct double_list_node sem_list_guard; +}; + +void semaphore_pool_init(struct XiziSemaphorePool* sem_pool); +int ksemaphore_alloc(struct XiziSemaphorePool* sem_pool, int val); +bool ksemaphore_free(struct XiziSemaphorePool* sem_pool, uint32_t sem_id); +bool ksemaphore_signal(struct XiziSemaphorePool* sem_pool, uint32_t sem_id); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h b/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h index 96dac0b89..4e1ba2a7a 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h @@ -46,6 +46,8 @@ Modification: #define SYSCALL_REGISTER_IRQ 11 // #define SYSCALL_KILL 12 // kill the task by id + +#define SYSCALL_SEMAPHORE 13 // semaphore related operations // clang-format on #ifndef __ASSEMBLER__ @@ -78,9 +80,12 @@ typedef union { int priority; } sys_state_info; -/* fn pointer to access user server */ -typedef int (*ipc_read_fn)(struct Session* session, int fd, char* dst, int offset, int len); -typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offset, int len); +typedef enum { + SYS_SEM_NEW = 0, + SYS_SEM_FREE, + SYS_SEM_SIGNAL, + SYS_SEM_WAIT, +} sys_sem_option; int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4); @@ -102,4 +107,6 @@ int sys_mmap(uintptr_t vaddr, uintptr_t paddr, int len, int is_dev); int sys_register_irq(int irq_num, int irq_opcode); 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); #endif diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h index b7cf198b4..56320be0f 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h @@ -33,6 +33,7 @@ Modification: #include "bitmap64.h" #include "buddy.h" +#include "ksemaphore.h" #include "list.h" #include "object_allocator.h" #include "pagetable.h" @@ -121,9 +122,11 @@ struct SchedulerRightGroup { }; struct XiziTaskManager { + /* thead schedule lists */ 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 XiziSemaphorePool semaphore_pool; /* mem allocator */ struct slab_allocator memspace_allocator; @@ -149,7 +152,7 @@ struct XiziTaskManager { /* call to yield current use task */ void (*task_yield_noschedule)(struct Thread* task, bool is_blocking); /* block and unblock task */ - void (*task_block)(struct Thread* task); + void (*task_block)(struct double_list_node* head, struct Thread* task); void (*task_unblock)(struct Thread* task); /* set task priority */ void (*set_cur_task_priority)(int priority); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/Makefile b/Ubiquitous/XiZi_AIoT/softkernel/syscall/Makefile index 8fac5ddff..4adbb947d 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/Makefile +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/Makefile @@ -10,6 +10,7 @@ SRC_FILES := syscall.c \ sys_exit.c \ sys_state.c \ sys_mmap.c \ - sys_kill.c + sys_kill.c \ + sys_semaphore.c include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c index 2d893be8a..35cde916d 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c @@ -121,7 +121,7 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity) userland_session_arr[session_idx].buf = NULL; if (!has_middle_delete && nr_sessions_need_to_handle == 0) { xizi_task_manager.task_yield_noschedule(cur_task, false); - xizi_task_manager.task_block(cur_task); + xizi_task_manager.task_block(&xizi_task_manager.task_blocked_list_head, cur_task); } } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_semaphore.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_semaphore.c new file mode 100644 index 000000000..18c0fd7e7 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_semaphore.c @@ -0,0 +1,53 @@ +/* + * 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_semaphore.c + * @brief support semaphore for userland + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2024.05.29 + */ + +#include "ksemaphore.h" +#include "multicores.h" +#include "syscall.h" +#include "task.h" + +extern bool ksemaphore_wait(struct XiziSemaphorePool* sem_pool, struct Thread* thd, uint32_t sem_id); +int sys_semaphore(sys_sem_option op, int param) +{ + bool ret = false; + switch (op) { + case SYS_SEM_NEW: { + // here, param is treat as val + return ksemaphore_alloc(&xizi_task_manager.semaphore_pool, param); + } + case SYS_SEM_FREE: { + // here, param is treat as sem_id + ret = ksemaphore_free(&xizi_task_manager.semaphore_pool, param); + break; + } + case SYS_SEM_SIGNAL: { + ret = ksemaphore_signal(&xizi_task_manager.semaphore_pool, param); + break; + } + case SYS_SEM_WAIT: { + ret = ksemaphore_wait(&xizi_task_manager.semaphore_pool, cur_cpu()->task, param); + break; + } + } + + if (LIKELY(ret)) { + return 0; + } + return -1; +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c index 7c95474d8..ddc3f5f69 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c @@ -91,6 +91,17 @@ void show_tasks(void) 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) + { + task = NULL; + DOUBLE_LIST_FOR_EACH_ENTRY(task, &sem->wait_list_guard, node) + { + LOG_PRINTF("%-8s", "BLOCK"); + SHOWTASK_TASK_BASE_INFO(task); + } + } + SHOWINFO_BORDER_LINE(); return; } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c index 6c58e508a..0db107e04 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c @@ -43,7 +43,7 @@ int sys_yield(task_yield_reason reason) if (cur_task->current_ipc_handled) { cur_task->current_ipc_handled = false; } else { - xizi_task_manager.task_block(cur_task); + xizi_task_manager.task_block(&xizi_task_manager.task_blocked_list_head, cur_task); } } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c index 8c5891584..4a15e6389 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c @@ -77,7 +77,9 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u case SYSCALL_KILL: ret = sys_kill((int)param1); break; - + case SYSCALL_SEMAPHORE: + ret = sys_semaphore((sys_sem_option)param1, (int)param2); + break; default: ERROR("Unsurport syscall(%d) right now\n", sys_num); ret = -1; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile b/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile index d5673c163..b2e54c9c1 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile @@ -1,3 +1,6 @@ -SRC_FILES := task.c schedule.c memspace.c +SRC_FILES := task.c \ + schedule.c \ + memspace.c \ + semaphore.c include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/semaphore.c b/Ubiquitous/XiZi_AIoT/softkernel/task/semaphore.c new file mode 100644 index 000000000..575e1aa7d --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/semaphore.c @@ -0,0 +1,134 @@ +/* + * 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 semaphore.c + * @brief semaphore implementation + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2024.05.28 + */ + +#include "assert.h" +#include "ksemaphore.h" +#include "task.h" + +void semaphore_pool_init(struct XiziSemaphorePool* sem_pool) +{ + assert(sem_pool != NULL); + sem_pool->next_sem_id = 1; + slab_init(&sem_pool->allocator, sizeof(struct ksemaphore)); + doubleListNodeInit(&sem_pool->sem_list_guard); +} + +static inline struct ksemaphore* ksemaphore_get_by_id(struct XiziSemaphorePool* sem_pool, int sem_id) +{ + struct ksemaphore* sem = NULL; + DOUBLE_LIST_FOR_EACH_ENTRY(sem, &sem_pool->sem_list_guard, sem_list_node) + { + if (sem->id == sem_id) { + break; + } + } + return sem; +} + +int ksemaphore_alloc(struct XiziSemaphorePool* sem_pool, int val) +{ + struct ksemaphore* sem = (struct ksemaphore*)slab_alloc(&sem_pool->allocator); + if (sem == NULL) { + ERROR("No memeory to alloc new semaphore.\n"); + return -1; + } + + /* No error down here */ + /* init ksemaphore since here */ + /// @warning sem->id could overflow + sem->id = sem_pool->next_sem_id++; + if (UNLIKELY(sem->id == 0)) { + slab_free(&sem_pool->allocator, sem); + return -1; + } + sem->val = val; + doubleListNodeInit(&sem->sem_list_node); + doubleListNodeInit(&sem->wait_list_guard); + + /* list sem to sem_pool */ + doubleListAddOnHead(&sem->sem_list_node, &sem_pool->sem_list_guard); + + return sem->id; +} + +bool ksemaphore_wait(struct XiziSemaphorePool* sem_pool, struct Thread* thd, uint32_t sem_id) +{ + assert(thd != NULL); + assert(thd->state == RUNNING); + /* find sem */ + struct ksemaphore* sem = ksemaphore_get_by_id(sem_pool, sem_id); + // invalid sem id + if (sem == NULL) { + return false; + } + + // no need to wait + if (sem->val > 0) { + sem->val--; + return true; + } + + // waiting at the sem + sem->val--; + xizi_task_manager.task_yield_noschedule(thd, false); + xizi_task_manager.task_block(&sem->wait_list_guard, thd); + return true; +} + +bool ksemaphore_signal(struct XiziSemaphorePool* sem_pool, uint32_t sem_id) +{ + /* find sem */ + struct ksemaphore* sem = ksemaphore_get_by_id(sem_pool, sem_id); + // invalid sem id + if (sem == NULL) { + return false; + } + + if (sem->val < 0) { + if (!IS_DOUBLE_LIST_EMPTY(&sem->wait_list_guard)) { + assert(sem->wait_list_guard.next != NULL); + xizi_task_manager.task_unblock(CONTAINER_OF(sem->wait_list_guard.next, struct Thread, node)); + } + } + + sem->val++; + return true; +} + +bool ksemaphore_free(struct XiziSemaphorePool* sem_pool, uint32_t sem_id) +{ + /* find sem */ + struct ksemaphore* sem = ksemaphore_get_by_id(sem_pool, sem_id); + // invalid sem id + if (sem == NULL) { + return false; + } + + struct Thread* thd = NULL; + DOUBLE_LIST_FOR_EACH_ENTRY(thd, &sem->wait_list_guard, node) + { + assert(thd != NULL); + xizi_task_manager.task_unblock(thd); + } + + doubleListDel(&sem->sem_list_node); + slab_free(&sem_pool->allocator, sem); + + return true; +} diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index 55cb2d2c6..4f9756e1d 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -74,6 +74,7 @@ static void _task_manager_init() slab_init(&xizi_task_manager.memspace_allocator, sizeof(struct MemSpace)); slab_init(&xizi_task_manager.task_allocator, sizeof(struct Thread)); slab_init(&xizi_task_manager.task_buddy_allocator, sizeof(struct KBuddy)); + semaphore_pool_init(&xizi_task_manager.semaphore_pool); // tid pool xizi_task_manager.next_pid = 0; @@ -321,13 +322,14 @@ static void _task_yield_noschedule(struct Thread* task, bool blocking) task_node_add_to_ready_list_back(task); } -static void _task_block(struct Thread* task) +static void _task_block(struct double_list_node* head, struct Thread* task) { + assert(head != NULL); assert(task != NULL); assert(task->state != RUNNING); task_node_leave_list(task); task->state = BLOCKED; - doubleListAddOnHead(&task->node, &xizi_task_manager.task_blocked_list_head); + doubleListAddOnHead(&task->node, head); } static void _task_unblock(struct Thread* task)