From 323e24049f0fe95ab1f7e1df83a330be32489be4 Mon Sep 17 00:00:00 2001 From: zhangzheng <1358745329@qq.comwq> Date: Mon, 20 Nov 2023 18:12:37 +0800 Subject: [PATCH] =?UTF-8?q?sleep=E6=94=AF=E6=8C=81&mutex=20cond=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mkrtos_knl/knl/thread_knl.c | 2 +- .../lib/libc_backend/inc/syscall_backend.h | 9 ++ .../lib/libc_backend/src/misc_backend.c | 50 +++++++++- mkrtos_user/lib/libc_backend/src/mm_backend.c | 5 + .../lib/libc_backend/src/sys_backend.c | 1 + .../lib/mlibc/src/internal/pthread_impl.h | 4 +- .../lib/mlibc/src/thread/pthread_create.c | 4 +- .../lib/mlibc/src/time/clock_nanosleep.c | 37 +++++-- mkrtos_user/lib/sys_util/src/u_app_loader.c | 3 +- .../server/drv/rtthread_drv/CMakeLists.txt | 2 +- mkrtos_user/server/init/CMakeLists.txt | 2 + mkrtos_user/server/init/src/main.c | 3 +- .../init/src/test/pthread_cond_lock_test.c | 65 +++++++++++++ .../server/init/src/test/pthread_lock_test.c | 96 ------------------- .../init/src/test/pthread_mutex_lock_test.c | 72 ++++++++++++++ mkrtos_user/server/init/src/test/test.h | 1 + 16 files changed, 242 insertions(+), 114 deletions(-) create mode 100644 mkrtos_user/server/init/src/test/pthread_cond_lock_test.c delete mode 100644 mkrtos_user/server/init/src/test/pthread_lock_test.c create mode 100644 mkrtos_user/server/init/src/test/pthread_mutex_lock_test.c diff --git a/mkrtos_knl/knl/thread_knl.c b/mkrtos_knl/knl/thread_knl.c index 59cb58ebd..9af40c078 100755 --- a/mkrtos_knl/knl/thread_knl.c +++ b/mkrtos_knl/knl/thread_knl.c @@ -84,7 +84,7 @@ static void knl_init_2(void) assert(obj_map_root(kobj, &init_task->obj_space, &root_factory_get()->limit, vpage_create3(KOBJ_ALL_RIGHTS, 0, i))); } } - init_thread->sche.prio = 3; + init_thread->sche.prio = 2; thread_ready(init_thread, FALSE); } INIT_STAGE2(knl_init_2); diff --git a/mkrtos_user/lib/libc_backend/inc/syscall_backend.h b/mkrtos_user/lib/libc_backend/inc/syscall_backend.h index be1cf677a..80f06851d 100644 --- a/mkrtos_user/lib/libc_backend/inc/syscall_backend.h +++ b/mkrtos_user/lib/libc_backend/inc/syscall_backend.h @@ -27,6 +27,15 @@ arg2 = (type2)va_arg(ap, long); \ } while (0) +#define ARG_4_BE(ap, arg0, type0, arg1, type1, arg2, type2, arg3, type3) \ + do \ + { \ + arg0 = (type0)va_arg(ap, long); \ + arg1 = (type1)va_arg(ap, long); \ + arg2 = (type2)va_arg(ap, long); \ + arg3 = (type3)va_arg(ap, long); \ + } while (0) + #define ARG_6_BE(ap, arg0, type0, arg1, type1, arg2, type2, arg3, type3, arg4, type4, arg5, type5) \ do \ { \ diff --git a/mkrtos_user/lib/libc_backend/src/misc_backend.c b/mkrtos_user/lib/libc_backend/src/misc_backend.c index dcbab2d14..a13b32db3 100644 --- a/mkrtos_user/lib/libc_backend/src/misc_backend.c +++ b/mkrtos_user/lib/libc_backend/src/misc_backend.c @@ -7,7 +7,8 @@ #include "u_log.h" #include "u_thread.h" #include - +#include +#include long be_set_tid_address(int *val) { struct pthread *pt = pthread_self(); @@ -59,4 +60,51 @@ unsigned long get_thread_area(void) return i_msg->user[0]; } +long be_nanosleep( + const struct timespec *req, + struct timespec *rem) +{ + size_t ms; + if (req == NULL) + { + return -EFAULT; + } + if (req->tv_nsec < 0 || req->tv_nsec > 999999999 || req->tv_sec < 0) + { + return -EINVAL; + } + ms = (req->tv_sec * 1000) + (req->tv_nsec / 1000000); + u_sleep_ms(ms); + return 0; +} +long be_clock_nanosleep(clockid_t clock_id, + long flags, + const struct timespec *req, + struct timespec *rem) +{ + size_t ms; + + if (req == NULL) + { + return -EFAULT; + } + if (req->tv_nsec < 0 || req->tv_nsec > 999999999 || req->tv_sec < 0) + { + return -EINVAL; + } + ms = (req->tv_sec * 1000000) + (req->tv_nsec / 1000); + u_sleep_ms(ms); + return 0; +} +long sys_clock_nanosleep(va_list ap) +{ + clockid_t clock_id; + long flags; + const struct timespec *req; + struct timespec *rem; + + ARG_4_BE(ap, clock_id, clockid_t, flags, long, req, const struct timespec *, rem, struct timespec *); + + return be_clock_nanosleep(clock_id, flags, req, rem); +} \ No newline at end of file diff --git a/mkrtos_user/lib/libc_backend/src/mm_backend.c b/mkrtos_user/lib/libc_backend/src/mm_backend.c index 71c9b8ecb..cf4d4e58a 100644 --- a/mkrtos_user/lib/libc_backend/src/mm_backend.c +++ b/mkrtos_user/lib/libc_backend/src/mm_backend.c @@ -86,12 +86,17 @@ static void mm_page_free(int st, int nr) static int _sys_mmap2(void *start, size_t len, int prot, int flags, int fd, off_t _offset, umword_t *addr) { + assert(addr); if (fd >= 0) { return -ENOSYS; } len = ALIGN(len, PAGE_SIZE); *addr = (umword_t)mm_page_alloc(len / PAGE_SIZE); + if (*addr == 0) + { + return -ENOMEM; + } return 0; } umword_t be_mmap2(void *start, diff --git a/mkrtos_user/lib/libc_backend/src/sys_backend.c b/mkrtos_user/lib/libc_backend/src/sys_backend.c index b0caee49b..af5fb9599 100644 --- a/mkrtos_user/lib/libc_backend/src/sys_backend.c +++ b/mkrtos_user/lib/libc_backend/src/sys_backend.c @@ -76,6 +76,7 @@ int be_clone(int (*func)(void *), void *stack, int flags, void *args, pid_t *pti return msg_tag_get_prot(tag); } stack = (char *)stack - MSG_BUG_LEN; + stack = (void *)(((umword_t)stack - sizeof(void *)) & (~(sizeof(void *) * 2 - 1))); umword_t *stack_tmp = (umword_t *)stack; // 设置调用参数等 diff --git a/mkrtos_user/lib/mlibc/src/internal/pthread_impl.h b/mkrtos_user/lib/mlibc/src/internal/pthread_impl.h index 6cab3b39d..a9f26252b 100644 --- a/mkrtos_user/lib/mlibc/src/internal/pthread_impl.h +++ b/mkrtos_user/lib/mlibc/src/internal/pthread_impl.h @@ -215,8 +215,8 @@ extern hidden volatile int __abort_lock[1]; extern hidden unsigned __default_stacksize; extern hidden unsigned __default_guardsize; -#define DEFAULT_STACK_SIZE 131072 -#define DEFAULT_GUARD_SIZE 8192 +#define DEFAULT_STACK_SIZE 1536 +#define DEFAULT_GUARD_SIZE (64) #define DEFAULT_STACK_MAX (8 << 20) #define DEFAULT_GUARD_MAX (1 << 20) diff --git a/mkrtos_user/lib/mlibc/src/thread/pthread_create.c b/mkrtos_user/lib/mlibc/src/thread/pthread_create.c index a5cab63c5..50ca1a867 100644 --- a/mkrtos_user/lib/mlibc/src/thread/pthread_create.c +++ b/mkrtos_user/lib/mlibc/src/thread/pthread_create.c @@ -209,7 +209,7 @@ struct start_args volatile int control; unsigned long sig_mask[_NSIG / 8 / sizeof(long)]; void *tp; - void *none; + // void *none; }; #ifndef NO_LITTLE_MODE #include "syscall_backend.h" @@ -386,7 +386,7 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att /* Setup argument structure for the new thread on its stack. * It's safe to access from the caller only until the thread * list is unlocked. */ - stack -= (uintptr_t)stack % sizeof(uintptr_t); + stack -= (uintptr_t)stack % (sizeof(uintptr_t) << 1); stack -= sizeof(struct start_args); struct start_args *args = (void *)stack; args->start_func = entry; diff --git a/mkrtos_user/lib/mlibc/src/time/clock_nanosleep.c b/mkrtos_user/lib/mlibc/src/time/clock_nanosleep.c index e195499cc..c895a8504 100644 --- a/mkrtos_user/lib/mlibc/src/time/clock_nanosleep.c +++ b/mkrtos_user/lib/mlibc/src/time/clock_nanosleep.c @@ -1,29 +1,42 @@ #include #include #include "syscall.h" - -#define IS32BIT(x) !((x)+0x80000000ULL>>32) -#define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63)) +#ifndef NO_LITTLE_MODE +#include "syscall_backend.h" +#endif +#define IS32BIT(x) !((x) + 0x80000000ULL >> 32) +#define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU + ((0ULL + (x)) >> 63)) int __clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem) { - if (clk == CLOCK_THREAD_CPUTIME_ID) return EINVAL; + if (clk == CLOCK_THREAD_CPUTIME_ID) + return EINVAL; #ifdef SYS_clock_nanosleep_time64 time_t s = req->tv_sec; long ns = req->tv_nsec; int r = -ENOSYS; if (SYS_clock_nanosleep == SYS_clock_nanosleep_time64 || !IS32BIT(s)) r = __syscall_cp(SYS_clock_nanosleep_time64, clk, flags, - ((long long[]){s, ns}), rem); - if (SYS_clock_nanosleep == SYS_clock_nanosleep_time64 || r!=-ENOSYS) + ((long long[]){s, ns}), rem); + if (SYS_clock_nanosleep == SYS_clock_nanosleep_time64 || r != -ENOSYS) return -r; long long extra = s - CLAMP(s); - long ts32[2] = { CLAMP(s), ns }; + long ts32[2] = {CLAMP(s), ns}; if (clk == CLOCK_REALTIME && !flags) + { +#ifdef NO_LITTLE_MODE r = __syscall_cp(SYS_nanosleep, &ts32, &ts32); +#else + extern long be_nanosleep( + const struct timespec *req, + struct timespec *rem); + return -be_nanosleep(req, rem); +#endif + } else r = __syscall_cp(SYS_clock_nanosleep, clk, flags, &ts32, &ts32); - if (r==-EINTR && rem && !(flags & TIMER_ABSTIME)) { + if (r == -EINTR && rem && !(flags & TIMER_ABSTIME)) + { rem->tv_sec = ts32[0] + extra; rem->tv_nsec = ts32[1]; } @@ -31,7 +44,15 @@ int __clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, stru #else if (clk == CLOCK_REALTIME && !flags) return -__syscall_cp(SYS_nanosleep, req, rem); +#ifdef NO_LITTLE_MODE return -__syscall_cp(SYS_clock_nanosleep, clk, flags, req, rem); +#else + extern long be_clock_nanosleep(clockid_t clock_id, + long flags, + const struct timespec *req, + struct timespec *rem); + return -be_clock_nanosleep(clk, flags, req, rem); +#endif #endif } diff --git a/mkrtos_user/lib/sys_util/src/u_app_loader.c b/mkrtos_user/lib/sys_util/src/u_app_loader.c index 6477473d3..f21e295e0 100644 --- a/mkrtos_user/lib/sys_util/src/u_app_loader.c +++ b/mkrtos_user/lib/sys_util/src/u_app_loader.c @@ -191,13 +191,12 @@ int app_load(const char *name, uenv_t *cur_env) uenv->rev1 = HANDLER_INVALID; uenv->rev2 = HANDLER_INVALID; - tag = thread_exec_regs(hd_thread, (umword_t)addr, (umword_t)sp_addr_top, ram_base, 1); + tag = thread_exec_regs(hd_thread, (umword_t)addr, (umword_t)sp_addr_top - sizeof(void*), ram_base, 1); assert(msg_tag_get_prot(tag) >= 0); /*启动线程运行*/ tag = thread_run(hd_thread, 2); assert(msg_tag_get_prot(tag) >= 0); - // umword_t len; // thread_msg_buf_get(THREAD_MAIN, (umword_t *)(&buf), NULL); // strcpy((char *)buf, "hello shell.\n"); diff --git a/mkrtos_user/server/drv/rtthread_drv/CMakeLists.txt b/mkrtos_user/server/drv/rtthread_drv/CMakeLists.txt index a5c225d25..b6e5e6503 100644 --- a/mkrtos_user/server/drv/rtthread_drv/CMakeLists.txt +++ b/mkrtos_user/server/drv/rtthread_drv/CMakeLists.txt @@ -39,9 +39,9 @@ add_executable( target_link_libraries( rtthread_drv.elf PUBLIC - start muslc --whole-archive + start sys sys_util sys_svr diff --git a/mkrtos_user/server/init/CMakeLists.txt b/mkrtos_user/server/init/CMakeLists.txt index da6e9d021..af9e1757e 100644 --- a/mkrtos_user/server/init/CMakeLists.txt +++ b/mkrtos_user/server/init/CMakeLists.txt @@ -9,10 +9,12 @@ target_link_libraries(init.elf PUBLIC start_init muslc + --whole-archive sys sys_util sys_svr cpio + --no-whole-archive ${GCC_LIB_PATH}/libgcc.a ) target_include_directories( diff --git a/mkrtos_user/server/init/src/main.c b/mkrtos_user/server/init/src/main.c index e81507ced..06140535e 100644 --- a/mkrtos_user/server/init/src/main.c +++ b/mkrtos_user/server/init/src/main.c @@ -36,8 +36,9 @@ int main(int argc, char *args[]) thread_press_test(); kobj_create_press_test(); ipc_test(); -#endif + pthread_cond_lock_test(); pthread_lock_test(); +#endif uenv_t env = *u_get_global_env(); obj_handler_t ipc_hd; int ret = rpc_creaite_bind_ipc(THREAD_MAIN, NULL, &ipc_hd); diff --git a/mkrtos_user/server/init/src/test/pthread_cond_lock_test.c b/mkrtos_user/server/init/src/test/pthread_cond_lock_test.c new file mode 100644 index 000000000..8b7a05000 --- /dev/null +++ b/mkrtos_user/server/init/src/test/pthread_cond_lock_test.c @@ -0,0 +1,65 @@ +/* + * 结合使用条件变量和互斥锁进行线程同步 + */ + +#include +#include +#include +static pthread_cond_t cond; +static pthread_mutex_t mutex; +static int cond_value; +static int quit; + +void *thread_signal(void *arg) +{ + while (!quit) + { + pthread_mutex_lock(&mutex); + cond_value++; // 改变条件,使条件满足 + pthread_cond_signal(&cond); // 给线程发信号 + printf("signal send, cond_value: %d\n", cond_value); + pthread_mutex_unlock(&mutex); + sleep(1); + } +} + +void *thread_wait(void *arg) +{ + while (!quit) + { + pthread_mutex_lock(&mutex); + + /*通过while (cond is true)来保证从pthread_cond_wait成功返回时,调用线程会重新检查条件*/ + while (cond_value == 0) + pthread_cond_wait(&cond, &mutex); + + cond_value--; + printf("signal recv, cond_value: %d\n", cond_value); + + pthread_mutex_unlock(&mutex); + sleep(1); + } +} + +pthread_t tid1; +pthread_t tid2; +int pthread_cond_lock_test(void) +{ + + pthread_cond_init(&cond, NULL); + pthread_mutex_init(&mutex, NULL); + + pthread_create(&tid1, NULL, thread_signal, NULL); + pthread_create(&tid2, NULL, thread_wait, NULL); + + sleep(5); + quit = 1; + + pthread_join(tid1, NULL); + pthread_join(tid2, NULL); + + pthread_cond_destroy(&cond); + pthread_mutex_destroy(&mutex); + + return 0; +} diff --git a/mkrtos_user/server/init/src/test/pthread_lock_test.c b/mkrtos_user/server/init/src/test/pthread_lock_test.c deleted file mode 100644 index ca00a6e4a..000000000 --- a/mkrtos_user/server/init/src/test/pthread_lock_test.c +++ /dev/null @@ -1,96 +0,0 @@ -#include "u_types.h" -#include -#include -#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 -#include -#include -#define DEBUG_IPC_CALL 1 - -static pthread_mutex_t lock; -static pthread_t pth; -static pthread_t pth2; - -#define STACK_SIZE 2048 -static __attribute__((aligned(8))) uint8_t stack0[STACK_SIZE]; -static __attribute__((aligned(8))) uint8_t stack1[STACK_SIZE]; - -static void hard_sleep(void) -{ - for (volatile int i; i < 10000000; i++) - ; -} -static void *thread_test_func(void* arg) -{ - // while (1) - { - pthread_mutex_lock(&lock); - printf("thread 1 ..\n"); - pthread_mutex_unlock(&lock); - } - return NULL; -} -static void *thread_test_func2(void* arg) -{ - // while (1) - { - pthread_mutex_lock(&lock); - printf("thread 2 ..\n"); - pthread_mutex_unlock(&lock); - } - return NULL; -} - -/** - * - */ -void pthread_lock_test(void) -{ - pthread_attr_t attr; - - pthread_mutex_init(&lock, NULL); - pthread_attr_init(&attr); - pthread_attr_setstack(&attr, stack0, STACK_SIZE); - pthread_create(&pth, &attr, thread_test_func, NULL); - pthread_attr_setstack(&attr, stack1, STACK_SIZE); - pthread_create(&pth2, &attr, thread_test_func2, NULL); - - // th1_hd = handler_alloc(); - // assert(th1_hd != HANDLER_INVALID); - // th2_hd = handler_alloc(); - // assert(th2_hd != HANDLER_INVALID); - // ipc_hd = handler_alloc(); - // assert(ipc_hd != HANDLER_INVALID); - - // msg_tag_t tag = factory_create_ipc(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, ipc_hd)); - // assert(msg_tag_get_prot(tag) >= 0); - // tag = factory_create_thread(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, th1_hd)); - // assert(msg_tag_get_prot(tag) >= 0); - // ipc_bind(ipc_hd, th1_hd, 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, RAM_BASE(), 0); - // assert(msg_tag_get_prot(tag) >= 0); - // tag = thread_bind_task(th1_hd, TASK_THIS); - // assert(msg_tag_get_prot(tag) >= 0); - // tag = thread_run(th1_hd, 2); - - // 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_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, RAM_BASE(), 0); - // assert(msg_tag_get_prot(tag) >= 0); - // tag = thread_bind_task(th2_hd, TASK_THIS); - // assert(msg_tag_get_prot(tag) >= 0); - // tag = thread_run(th2_hd, 2); - // assert(msg_tag_get_prot(tag) >= 0); -} diff --git a/mkrtos_user/server/init/src/test/pthread_mutex_lock_test.c b/mkrtos_user/server/init/src/test/pthread_mutex_lock_test.c new file mode 100644 index 000000000..bdd032f49 --- /dev/null +++ b/mkrtos_user/server/init/src/test/pthread_mutex_lock_test.c @@ -0,0 +1,72 @@ +#include "u_types.h" +#include +#include +#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 +#include +#include +#include +#include +#define DEBUG_IPC_CALL 1 + +static pthread_mutex_t lock; +static pthread_t pth; +static pthread_t pth2; + +#define STACK_SIZE 2048 +static __attribute__((aligned(8))) uint8_t stack0[STACK_SIZE]; +static __attribute__((aligned(8))) uint8_t stack1[STACK_SIZE]; + +static void hard_sleep(void) +{ + for (volatile int i; i < 1000000000; i++) + ; +} +static void *thread_test_func(void *arg) +{ + int i = 5; + while (i--) + { + pthread_mutex_lock(&lock); + printf("thread 1 ..\n"); + usleep(200000); + pthread_mutex_unlock(&lock); + } + return NULL; +} +static void *thread_test_func2(void *arg) +{ + int i = 5; + while (i--) + { + pthread_mutex_lock(&lock); + printf("thread 2 ..\n"); + usleep(200000); + pthread_mutex_unlock(&lock); + } + return NULL; +} + +/** + * + */ +void pthread_lock_test(void) +{ + pthread_attr_t attr; + + pthread_mutex_init(&lock, NULL); + pthread_attr_init(&attr); + pthread_attr_setstack(&attr, stack0, STACK_SIZE); + pthread_create(&pth, &attr, thread_test_func, NULL); + pthread_attr_setstack(&attr, stack1, STACK_SIZE); + pthread_create(&pth2, &attr, thread_test_func2, NULL); + pthread_join(pth, NULL); + pthread_join(pth2, NULL); +} diff --git a/mkrtos_user/server/init/src/test/test.h b/mkrtos_user/server/init/src/test/test.h index d5513b2c6..edeb11b1d 100644 --- a/mkrtos_user/server/init/src/test/test.h +++ b/mkrtos_user/server/init/src/test/test.h @@ -17,3 +17,4 @@ void thread_press_test(void); void kobj_create_press_test(void); void sleep_tick(int tick); void pthread_lock_test(void); +int pthread_cond_lock_test(void);