From 8da8c49f395b0d7706efb4fe61cc22593b4eeeab Mon Sep 17 00:00:00 2001 From: winlin Date: Mon, 10 Nov 2014 11:49:14 +0800 Subject: [PATCH 1/2] research st, add comments --- trunk/research/st/sched.c | 2 +- trunk/research/st/stk.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/trunk/research/st/sched.c b/trunk/research/st/sched.c index 4252ede1a..0ec9559bf 100644 --- a/trunk/research/st/sched.c +++ b/trunk/research/st/sched.c @@ -564,7 +564,7 @@ _st_thread_t *st_thread_create(void *(*start)(void *arg), void *arg, int joinabl } stack->sp = sp - _ST_STACK_PAD_SIZE; #else - #error Unknown Stack Grown + #error "Only Supports Stack Grown Down" #endif memset(trd, 0, sizeof(_st_thread_t)); diff --git a/trunk/research/st/stk.c b/trunk/research/st/stk.c index 5f6790d7b..c26223ba5 100644 --- a/trunk/research/st/stk.c +++ b/trunk/research/st/stk.c @@ -138,7 +138,7 @@ static char *_st_new_stk_segment(int size) #ifdef MALLOC_STACK void *vaddr = malloc(size); #else - #error Unknown Stack Malloc + #error "Only Supports Malloc Stack" #endif return (char *)vaddr; From 2c01f7e943facb61c5c53ecacfd09524a91b23ab Mon Sep 17 00:00:00 2001 From: winlin Date: Mon, 10 Nov 2014 13:52:17 +0800 Subject: [PATCH 2/2] research st, expand MD_INIT_CONTEXT macro, the thread start. --- trunk/research/arm/jmp_sp.cpp | 41 ++++++++++++++++++++--------------- trunk/research/st/common.h | 9 -------- trunk/research/st/md.h | 14 ------------ trunk/research/st/sched.c | 29 +++++++++++++++++++++++-- trunk/research/st/srs.c | 24 +++++++++++++++++++- 5 files changed, 73 insertions(+), 44 deletions(-) diff --git a/trunk/research/arm/jmp_sp.cpp b/trunk/research/arm/jmp_sp.cpp index fb5df11c2..d5d1dea09 100644 --- a/trunk/research/arm/jmp_sp.cpp +++ b/trunk/research/arm/jmp_sp.cpp @@ -9,15 +9,20 @@ #include #include -jmp_buf env_func1; +jmp_buf context; void func1() { #if defined(__amd64__) || defined(__x86_64__) register long int rsp0 asm("rsp"); - int ret = setjmp(env_func1); - printf("setjmp func0 ret=%d, rsp=%#lx\n", ret, rsp0); + int ret = setjmp(context); + printf("setjmp func1 ret=%d, rsp=%#lx\n", ret, rsp0); + // enter by longjmp + if (ret != 0) { + printf("call by longjmp.\n"); + exit(0); + } #endif } @@ -49,15 +54,15 @@ void func0() // for glibc 2.4+, it's not possible to get and set the sp in jmp_buf /** for example, the following is show the jmp_buf when setjmp: - (gdb) x /64xb env_func1[0].__jmpbuf - 0x600ca0 : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 - 0x600ca8 : 0xf8 0xc1 0x71 0xe5 0xa8 0x88 0xb4 0x15 - 0x600cb0 : 0xa0 0x05 0x40 0x00 0x00 0x00 0x00 0x00 - 0x600cb8 : 0x90 0xe4 0xff 0xff 0xff 0x7f 0x00 0x00 - 0x600cc0 : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 - 0x600cc8 : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 - 0x600cd0 : 0xf8 0xc1 0x51 0xe5 0xa8 0x88 0xb4 0x15 - 0x600cd8 : 0xf8 0xc1 0xd9 0x2f 0xd7 0x77 0x4b 0xea + (gdb) x /64xb context[0].__jmpbuf + 0x600ca0 : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0x600ca8 : 0xf8 0xc1 0x71 0xe5 0xa8 0x88 0xb4 0x15 + 0x600cb0 : 0xa0 0x05 0x40 0x00 0x00 0x00 0x00 0x00 + 0x600cb8 : 0x90 0xe4 0xff 0xff 0xff 0x7f 0x00 0x00 + 0x600cc0 : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0x600cc8 : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0x600cd0 : 0xf8 0xc1 0x51 0xe5 0xa8 0x88 0xb4 0x15 + 0x600cd8 : 0xf8 0xc1 0xd9 0x2f 0xd7 0x77 0x4b 0xea (gdb) p /x $sp $4 = 0x7fffffffe380 we cannot finger the sp out. @@ -65,12 +70,12 @@ void func0() */ register long int rsp0 asm("rsp"); - int ret = setjmp(env_func1); + int ret = setjmp(context); printf("setjmp func0 ret=%d, rsp=%#lx\n", ret, rsp0); printf("after setjmp: "); for (int i = 0; i < 8; i++) { - printf("env[%d]=%#x, ", i, (int)env_func1[0].__jmpbuf[i]); + printf("env[%d]=%#x, ", i, (int)context[0].__jmpbuf[i]); } printf("\n"); @@ -100,7 +105,7 @@ void func0() */ /** For example, on raspberry-pi, armv6 cpu: - (gdb) x /64 env_func1[0].__jmpbuf + (gdb) x /64 context[0].__jmpbuf v1, 0: 0x00 0x00 0x00 0x00 v2, 1: 0x00 0x00 0x00 0x00 v3, 2: 0x2c 0x84 0x00 0x00 @@ -116,19 +121,18 @@ void func0() (gdb) p /x $pc $4 = 0x850c */ - int ret = setjmp(env_func1); + int ret = setjmp(context); printf("setjmp func1 ret=%d\n", ret); printf("after setjmp: "); for (int i = 0; i < 64; i++) { - printf("env[%d]=%#x, ", i, (int)env_func1[0].__jmpbuf[i]); + printf("env[%d]=%#x, ", i, (int)context[0].__jmpbuf[i]); } printf("func0 terminated\n"); #endif } -extern uintptr_t _jmpbuf_sp (__jmp_buf regs); int main(int argc, char** argv) { #if defined(__amd64__) || defined(__x86_64__) printf("x86_64 sizeof(long int)=%d, sizeof(long)=%d, " @@ -143,6 +147,7 @@ int main(int argc, char** argv) { #endif func0(); + longjmp(context, 1); printf("terminated\n"); diff --git a/trunk/research/st/common.h b/trunk/research/st/common.h index 46868556f..b83e575ca 100644 --- a/trunk/research/st/common.h +++ b/trunk/research/st/common.h @@ -410,15 +410,6 @@ extern _st_eventsys_t *_st_eventsys; MD_LONGJMP((_thread)->context, 1); \ ST_END_MACRO -/* - * Initialize the thread context preparing it to execute _main - */ -#ifdef MD_INIT_CONTEXT - #define _ST_INIT_CONTEXT MD_INIT_CONTEXT -#else - #error Unknown OS -#endif - /* * Number of bytes reserved under the stack "bottom" */ diff --git a/trunk/research/st/md.h b/trunk/research/st/md.h index 432d73a13..3088f3470 100644 --- a/trunk/research/st/md.h +++ b/trunk/research/st/md.h @@ -107,13 +107,6 @@ #if defined(__mips__) #define MD_STACK_GROWS_DOWN - - #define MD_INIT_CONTEXT(_thread, _sp, _main) \ - ST_BEGIN_MACRO \ - MD_SETJMP((_thread)->context); \ - _thread->context[0].__jmpbuf[0].__pc = (__ptr_t) _main; \ - _thread->context[0].__jmpbuf[0].__sp = _sp; \ - ST_END_MACRO #else /* Not or mips */ /* * On linux, there are a few styles of jmpbuf format. These vary based @@ -166,13 +159,6 @@ #else #error "Unknown CPU architecture" #endif /* Cases with common MD_INIT_CONTEXT and different SP locations */ - - #define MD_INIT_CONTEXT(_thread, _sp, _main) \ - ST_BEGIN_MACRO \ - if (MD_SETJMP((_thread)->context)) \ - _main(); \ - MD_GET_SP(_thread) = (long) (_sp); \ - ST_END_MACRO #endif /* Cases with different MD_INIT_CONTEXT */ #if defined(MD_USE_BUILTIN_SETJMP) && !defined(USE_LIBC_SETJMP) diff --git a/trunk/research/st/sched.c b/trunk/research/st/sched.c index 0ec9559bf..31a5ba23d 100644 --- a/trunk/research/st/sched.c +++ b/trunk/research/st/sched.c @@ -553,6 +553,20 @@ _st_thread_t *st_thread_create(void *(*start)(void *arg), void *arg, int joinabl * grows downward. Both stacks start in the middle and grow outward * from each other. */ + /** + The below comments is by winlin: + The Stack public structure: + +--------------------------------------------------------------+ + | stack | + +--------------------------------------------------------------+ + bottom top + The code bellow use the stack as: + +-----------------+-----------------+-------------+------------+ + | stack of thread |pad+align(128B+) |thread(336B) | keys(128B) | + +-----------------+-----------------+-------------+------------+ + bottom sp trd ptds top + (context[0].__jmpbuf.sp) (private_data) + */ sp = sp - (ST_KEYS_MAX * sizeof(void *)); ptds = (void **) sp; sp = sp - sizeof(_st_thread_t); @@ -575,8 +589,19 @@ _st_thread_t *st_thread_create(void *(*start)(void *arg), void *arg, int joinabl trd->stack = stack; trd->start = start; trd->arg = arg; - - _ST_INIT_CONTEXT(trd, stack->sp, _st_thread_main); + +// by winlin, expand macro MD_INIT_CONTEXT +#if defined(__mips__) + MD_SETJMP((trd)->context); + trd->context[0].__jmpbuf[0].__pc = (__ptr_t) _st_thread_main; + trd->context[0].__jmpbuf[0].__sp = stack->sp; +#else + int ret_setjmp = 0; + if ((ret_setjmp = MD_SETJMP((trd)->context)) != 0) { + _st_thread_main(); + } + MD_GET_SP(trd) = (long) (stack->sp); +#endif /* If thread is joinable, allocate a termination condition variable */ if (joinable) { diff --git a/trunk/research/st/srs.c b/trunk/research/st/srs.c index 7a011a640..a5aa003fb 100644 --- a/trunk/research/st/srs.c +++ b/trunk/research/st/srs.c @@ -46,6 +46,21 @@ int huge_stack_test() return 0; } +int sleep_test() +{ + srs_trace("==================================================="); + srs_trace("sleep test: start"); + + srs_trace("1. sleep..."); + + st_usleep(sleep_ms * 1000); + srs_trace("2. sleep ok"); + + srs_trace("sleep test: end"); + + return 0; +} + void* thread_func(void* arg) { srs_trace("1. thread run"); @@ -68,8 +83,10 @@ int thread_test() st_thread_join(trd, NULL); srs_trace("3. thread joined"); + st_thread_exit(NULL); + srs_trace("4. all thread completed"); + srs_trace("thread test: end"); - exit(0); return 0; } @@ -342,6 +359,11 @@ int main(int argc, char** argv) return -1; } + if (sleep_test() < 0) { + srs_trace("sleep_test failed"); + return -1; + } + if (thread_test() < 0) { srs_trace("thread_test failed"); return -1;