sleep支持&mutex cond测试
This commit is contained in:
@@ -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 \
|
||||
{ \
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
#include "u_log.h"
|
||||
#include "u_thread.h"
|
||||
#include <pthread_impl.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <u_sleep.h>
|
||||
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);
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
// 设置调用参数等
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,29 +1,42 @@
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#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
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -39,9 +39,9 @@ add_executable(
|
||||
target_link_libraries(
|
||||
rtthread_drv.elf
|
||||
PUBLIC
|
||||
start
|
||||
muslc
|
||||
--whole-archive
|
||||
start
|
||||
sys
|
||||
sys_util
|
||||
sys_svr
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
|
||||
65
mkrtos_user/server/init/src/test/pthread_cond_lock_test.c
Normal file
65
mkrtos_user/server/init/src/test/pthread_cond_lock_test.c
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 结合使用条件变量和互斥锁进行线程同步
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
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;
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
#include "u_types.h"
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#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 <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#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);
|
||||
}
|
||||
72
mkrtos_user/server/init/src/test/pthread_mutex_lock_test.c
Normal file
72
mkrtos_user/server/init/src/test/pthread_mutex_lock_test.c
Normal file
@@ -0,0 +1,72 @@
|
||||
#include "u_types.h"
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#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 <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user