sleep支持&mutex cond测试

This commit is contained in:
zhangzheng
2023-11-20 18:12:37 +08:00
parent 2c410d4000
commit 323e24049f
16 changed files with 242 additions and 114 deletions

View File

@@ -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 \
{ \

View File

@@ -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);
}

View File

@@ -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,

View File

@@ -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;
// 设置调用参数等

View File

@@ -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)

View File

@@ -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;

View File

@@ -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
}

View File

@@ -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");

View File

@@ -39,9 +39,9 @@ add_executable(
target_link_libraries(
rtthread_drv.elf
PUBLIC
start
muslc
--whole-archive
start
sys
sys_util
sys_svr

View File

@@ -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(

View File

@@ -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);

View 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;
}

View File

@@ -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);
}

View 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);
}

View File

@@ -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);