正在显示
6 个修改的文件
包含
75 行增加
和
46 行删除
@@ -9,15 +9,20 @@ | @@ -9,15 +9,20 @@ | ||
9 | #include <stdlib.h> | 9 | #include <stdlib.h> |
10 | #include <setjmp.h> | 10 | #include <setjmp.h> |
11 | 11 | ||
12 | -jmp_buf env_func1; | 12 | +jmp_buf context; |
13 | 13 | ||
14 | void func1() | 14 | void func1() |
15 | { | 15 | { |
16 | #if defined(__amd64__) || defined(__x86_64__) | 16 | #if defined(__amd64__) || defined(__x86_64__) |
17 | register long int rsp0 asm("rsp"); | 17 | register long int rsp0 asm("rsp"); |
18 | 18 | ||
19 | - int ret = setjmp(env_func1); | ||
20 | - printf("setjmp func0 ret=%d, rsp=%#lx\n", ret, rsp0); | 19 | + int ret = setjmp(context); |
20 | + printf("setjmp func1 ret=%d, rsp=%#lx\n", ret, rsp0); | ||
21 | + // enter by longjmp | ||
22 | + if (ret != 0) { | ||
23 | + printf("call by longjmp.\n"); | ||
24 | + exit(0); | ||
25 | + } | ||
21 | #endif | 26 | #endif |
22 | } | 27 | } |
23 | 28 | ||
@@ -49,15 +54,15 @@ void func0() | @@ -49,15 +54,15 @@ void func0() | ||
49 | // for glibc 2.4+, it's not possible to get and set the sp in jmp_buf | 54 | // for glibc 2.4+, it's not possible to get and set the sp in jmp_buf |
50 | /** | 55 | /** |
51 | for example, the following is show the jmp_buf when setjmp: | 56 | for example, the following is show the jmp_buf when setjmp: |
52 | - (gdb) x /64xb env_func1[0].__jmpbuf | ||
53 | - 0x600ca0 <env_func1>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 | ||
54 | - 0x600ca8 <env_func1+8>: 0xf8 0xc1 0x71 0xe5 0xa8 0x88 0xb4 0x15 | ||
55 | - 0x600cb0 <env_func1+16>: 0xa0 0x05 0x40 0x00 0x00 0x00 0x00 0x00 | ||
56 | - 0x600cb8 <env_func1+24>: 0x90 0xe4 0xff 0xff 0xff 0x7f 0x00 0x00 | ||
57 | - 0x600cc0 <env_func1+32>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 | ||
58 | - 0x600cc8 <env_func1+40>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 | ||
59 | - 0x600cd0 <env_func1+48>: 0xf8 0xc1 0x51 0xe5 0xa8 0x88 0xb4 0x15 | ||
60 | - 0x600cd8 <env_func1+56>: 0xf8 0xc1 0xd9 0x2f 0xd7 0x77 0x4b 0xea | 57 | + (gdb) x /64xb context[0].__jmpbuf |
58 | + 0x600ca0 <context>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 | ||
59 | + 0x600ca8 <context+8>: 0xf8 0xc1 0x71 0xe5 0xa8 0x88 0xb4 0x15 | ||
60 | + 0x600cb0 <context+16>: 0xa0 0x05 0x40 0x00 0x00 0x00 0x00 0x00 | ||
61 | + 0x600cb8 <context+24>: 0x90 0xe4 0xff 0xff 0xff 0x7f 0x00 0x00 | ||
62 | + 0x600cc0 <context+32>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 | ||
63 | + 0x600cc8 <context+40>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 | ||
64 | + 0x600cd0 <context+48>: 0xf8 0xc1 0x51 0xe5 0xa8 0x88 0xb4 0x15 | ||
65 | + 0x600cd8 <context+56>: 0xf8 0xc1 0xd9 0x2f 0xd7 0x77 0x4b 0xea | ||
61 | (gdb) p /x $sp | 66 | (gdb) p /x $sp |
62 | $4 = 0x7fffffffe380 | 67 | $4 = 0x7fffffffe380 |
63 | we cannot finger the sp out. | 68 | we cannot finger the sp out. |
@@ -65,12 +70,12 @@ void func0() | @@ -65,12 +70,12 @@ void func0() | ||
65 | */ | 70 | */ |
66 | register long int rsp0 asm("rsp"); | 71 | register long int rsp0 asm("rsp"); |
67 | 72 | ||
68 | - int ret = setjmp(env_func1); | 73 | + int ret = setjmp(context); |
69 | printf("setjmp func0 ret=%d, rsp=%#lx\n", ret, rsp0); | 74 | printf("setjmp func0 ret=%d, rsp=%#lx\n", ret, rsp0); |
70 | 75 | ||
71 | printf("after setjmp: "); | 76 | printf("after setjmp: "); |
72 | for (int i = 0; i < 8; i++) { | 77 | for (int i = 0; i < 8; i++) { |
73 | - printf("env[%d]=%#x, ", i, (int)env_func1[0].__jmpbuf[i]); | 78 | + printf("env[%d]=%#x, ", i, (int)context[0].__jmpbuf[i]); |
74 | } | 79 | } |
75 | printf("\n"); | 80 | printf("\n"); |
76 | 81 | ||
@@ -100,7 +105,7 @@ void func0() | @@ -100,7 +105,7 @@ void func0() | ||
100 | */ | 105 | */ |
101 | /** | 106 | /** |
102 | For example, on raspberry-pi, armv6 cpu: | 107 | For example, on raspberry-pi, armv6 cpu: |
103 | - (gdb) x /64 env_func1[0].__jmpbuf | 108 | + (gdb) x /64 context[0].__jmpbuf |
104 | v1, 0: 0x00 0x00 0x00 0x00 | 109 | v1, 0: 0x00 0x00 0x00 0x00 |
105 | v2, 1: 0x00 0x00 0x00 0x00 | 110 | v2, 1: 0x00 0x00 0x00 0x00 |
106 | v3, 2: 0x2c 0x84 0x00 0x00 | 111 | v3, 2: 0x2c 0x84 0x00 0x00 |
@@ -116,19 +121,18 @@ void func0() | @@ -116,19 +121,18 @@ void func0() | ||
116 | (gdb) p /x $pc | 121 | (gdb) p /x $pc |
117 | $4 = 0x850c | 122 | $4 = 0x850c |
118 | */ | 123 | */ |
119 | - int ret = setjmp(env_func1); | 124 | + int ret = setjmp(context); |
120 | printf("setjmp func1 ret=%d\n", ret); | 125 | printf("setjmp func1 ret=%d\n", ret); |
121 | 126 | ||
122 | printf("after setjmp: "); | 127 | printf("after setjmp: "); |
123 | for (int i = 0; i < 64; i++) { | 128 | for (int i = 0; i < 64; i++) { |
124 | - printf("env[%d]=%#x, ", i, (int)env_func1[0].__jmpbuf[i]); | 129 | + printf("env[%d]=%#x, ", i, (int)context[0].__jmpbuf[i]); |
125 | } | 130 | } |
126 | 131 | ||
127 | printf("func0 terminated\n"); | 132 | printf("func0 terminated\n"); |
128 | #endif | 133 | #endif |
129 | } | 134 | } |
130 | 135 | ||
131 | -extern uintptr_t _jmpbuf_sp (__jmp_buf regs); | ||
132 | int main(int argc, char** argv) { | 136 | int main(int argc, char** argv) { |
133 | #if defined(__amd64__) || defined(__x86_64__) | 137 | #if defined(__amd64__) || defined(__x86_64__) |
134 | printf("x86_64 sizeof(long int)=%d, sizeof(long)=%d, " | 138 | printf("x86_64 sizeof(long int)=%d, sizeof(long)=%d, " |
@@ -143,6 +147,7 @@ int main(int argc, char** argv) { | @@ -143,6 +147,7 @@ int main(int argc, char** argv) { | ||
143 | #endif | 147 | #endif |
144 | 148 | ||
145 | func0(); | 149 | func0(); |
150 | + longjmp(context, 1); | ||
146 | 151 | ||
147 | printf("terminated\n"); | 152 | printf("terminated\n"); |
148 | 153 |
@@ -411,15 +411,6 @@ extern _st_eventsys_t *_st_eventsys; | @@ -411,15 +411,6 @@ extern _st_eventsys_t *_st_eventsys; | ||
411 | ST_END_MACRO | 411 | ST_END_MACRO |
412 | 412 | ||
413 | /* | 413 | /* |
414 | - * Initialize the thread context preparing it to execute _main | ||
415 | - */ | ||
416 | -#ifdef MD_INIT_CONTEXT | ||
417 | - #define _ST_INIT_CONTEXT MD_INIT_CONTEXT | ||
418 | -#else | ||
419 | - #error Unknown OS | ||
420 | -#endif | ||
421 | - | ||
422 | -/* | ||
423 | * Number of bytes reserved under the stack "bottom" | 414 | * Number of bytes reserved under the stack "bottom" |
424 | */ | 415 | */ |
425 | #define _ST_STACK_PAD_SIZE MD_STACK_PAD_SIZE | 416 | #define _ST_STACK_PAD_SIZE MD_STACK_PAD_SIZE |
@@ -107,13 +107,6 @@ | @@ -107,13 +107,6 @@ | ||
107 | 107 | ||
108 | #if defined(__mips__) | 108 | #if defined(__mips__) |
109 | #define MD_STACK_GROWS_DOWN | 109 | #define MD_STACK_GROWS_DOWN |
110 | - | ||
111 | - #define MD_INIT_CONTEXT(_thread, _sp, _main) \ | ||
112 | - ST_BEGIN_MACRO \ | ||
113 | - MD_SETJMP((_thread)->context); \ | ||
114 | - _thread->context[0].__jmpbuf[0].__pc = (__ptr_t) _main; \ | ||
115 | - _thread->context[0].__jmpbuf[0].__sp = _sp; \ | ||
116 | - ST_END_MACRO | ||
117 | #else /* Not or mips */ | 110 | #else /* Not or mips */ |
118 | /* | 111 | /* |
119 | * On linux, there are a few styles of jmpbuf format. These vary based | 112 | * On linux, there are a few styles of jmpbuf format. These vary based |
@@ -166,13 +159,6 @@ | @@ -166,13 +159,6 @@ | ||
166 | #else | 159 | #else |
167 | #error "Unknown CPU architecture" | 160 | #error "Unknown CPU architecture" |
168 | #endif /* Cases with common MD_INIT_CONTEXT and different SP locations */ | 161 | #endif /* Cases with common MD_INIT_CONTEXT and different SP locations */ |
169 | - | ||
170 | - #define MD_INIT_CONTEXT(_thread, _sp, _main) \ | ||
171 | - ST_BEGIN_MACRO \ | ||
172 | - if (MD_SETJMP((_thread)->context)) \ | ||
173 | - _main(); \ | ||
174 | - MD_GET_SP(_thread) = (long) (_sp); \ | ||
175 | - ST_END_MACRO | ||
176 | #endif /* Cases with different MD_INIT_CONTEXT */ | 162 | #endif /* Cases with different MD_INIT_CONTEXT */ |
177 | 163 | ||
178 | #if defined(MD_USE_BUILTIN_SETJMP) && !defined(USE_LIBC_SETJMP) | 164 | #if defined(MD_USE_BUILTIN_SETJMP) && !defined(USE_LIBC_SETJMP) |
@@ -553,6 +553,20 @@ _st_thread_t *st_thread_create(void *(*start)(void *arg), void *arg, int joinabl | @@ -553,6 +553,20 @@ _st_thread_t *st_thread_create(void *(*start)(void *arg), void *arg, int joinabl | ||
553 | * grows downward. Both stacks start in the middle and grow outward | 553 | * grows downward. Both stacks start in the middle and grow outward |
554 | * from each other. | 554 | * from each other. |
555 | */ | 555 | */ |
556 | + /** | ||
557 | + The below comments is by winlin: | ||
558 | + The Stack public structure: | ||
559 | + +--------------------------------------------------------------+ | ||
560 | + | stack | | ||
561 | + +--------------------------------------------------------------+ | ||
562 | + bottom top | ||
563 | + The code bellow use the stack as: | ||
564 | + +-----------------+-----------------+-------------+------------+ | ||
565 | + | stack of thread |pad+align(128B+) |thread(336B) | keys(128B) | | ||
566 | + +-----------------+-----------------+-------------+------------+ | ||
567 | + bottom sp trd ptds top | ||
568 | + (context[0].__jmpbuf.sp) (private_data) | ||
569 | + */ | ||
556 | sp = sp - (ST_KEYS_MAX * sizeof(void *)); | 570 | sp = sp - (ST_KEYS_MAX * sizeof(void *)); |
557 | ptds = (void **) sp; | 571 | ptds = (void **) sp; |
558 | sp = sp - sizeof(_st_thread_t); | 572 | sp = sp - sizeof(_st_thread_t); |
@@ -564,7 +578,7 @@ _st_thread_t *st_thread_create(void *(*start)(void *arg), void *arg, int joinabl | @@ -564,7 +578,7 @@ _st_thread_t *st_thread_create(void *(*start)(void *arg), void *arg, int joinabl | ||
564 | } | 578 | } |
565 | stack->sp = sp - _ST_STACK_PAD_SIZE; | 579 | stack->sp = sp - _ST_STACK_PAD_SIZE; |
566 | #else | 580 | #else |
567 | - #error Unknown Stack Grown | 581 | + #error "Only Supports Stack Grown Down" |
568 | #endif | 582 | #endif |
569 | 583 | ||
570 | memset(trd, 0, sizeof(_st_thread_t)); | 584 | memset(trd, 0, sizeof(_st_thread_t)); |
@@ -575,8 +589,19 @@ _st_thread_t *st_thread_create(void *(*start)(void *arg), void *arg, int joinabl | @@ -575,8 +589,19 @@ _st_thread_t *st_thread_create(void *(*start)(void *arg), void *arg, int joinabl | ||
575 | trd->stack = stack; | 589 | trd->stack = stack; |
576 | trd->start = start; | 590 | trd->start = start; |
577 | trd->arg = arg; | 591 | trd->arg = arg; |
578 | - | ||
579 | - _ST_INIT_CONTEXT(trd, stack->sp, _st_thread_main); | 592 | + |
593 | +// by winlin, expand macro MD_INIT_CONTEXT | ||
594 | +#if defined(__mips__) | ||
595 | + MD_SETJMP((trd)->context); | ||
596 | + trd->context[0].__jmpbuf[0].__pc = (__ptr_t) _st_thread_main; | ||
597 | + trd->context[0].__jmpbuf[0].__sp = stack->sp; | ||
598 | +#else | ||
599 | + int ret_setjmp = 0; | ||
600 | + if ((ret_setjmp = MD_SETJMP((trd)->context)) != 0) { | ||
601 | + _st_thread_main(); | ||
602 | + } | ||
603 | + MD_GET_SP(trd) = (long) (stack->sp); | ||
604 | +#endif | ||
580 | 605 | ||
581 | /* If thread is joinable, allocate a termination condition variable */ | 606 | /* If thread is joinable, allocate a termination condition variable */ |
582 | if (joinable) { | 607 | if (joinable) { |
@@ -46,6 +46,21 @@ int huge_stack_test() | @@ -46,6 +46,21 @@ int huge_stack_test() | ||
46 | return 0; | 46 | return 0; |
47 | } | 47 | } |
48 | 48 | ||
49 | +int sleep_test() | ||
50 | +{ | ||
51 | + srs_trace("==================================================="); | ||
52 | + srs_trace("sleep test: start"); | ||
53 | + | ||
54 | + srs_trace("1. sleep..."); | ||
55 | + | ||
56 | + st_usleep(sleep_ms * 1000); | ||
57 | + srs_trace("2. sleep ok"); | ||
58 | + | ||
59 | + srs_trace("sleep test: end"); | ||
60 | + | ||
61 | + return 0; | ||
62 | +} | ||
63 | + | ||
49 | void* thread_func(void* arg) | 64 | void* thread_func(void* arg) |
50 | { | 65 | { |
51 | srs_trace("1. thread run"); | 66 | srs_trace("1. thread run"); |
@@ -68,8 +83,10 @@ int thread_test() | @@ -68,8 +83,10 @@ int thread_test() | ||
68 | st_thread_join(trd, NULL); | 83 | st_thread_join(trd, NULL); |
69 | srs_trace("3. thread joined"); | 84 | srs_trace("3. thread joined"); |
70 | 85 | ||
86 | + st_thread_exit(NULL); | ||
87 | + srs_trace("4. all thread completed"); | ||
88 | + | ||
71 | srs_trace("thread test: end"); | 89 | srs_trace("thread test: end"); |
72 | - exit(0); | ||
73 | 90 | ||
74 | return 0; | 91 | return 0; |
75 | } | 92 | } |
@@ -342,6 +359,11 @@ int main(int argc, char** argv) | @@ -342,6 +359,11 @@ int main(int argc, char** argv) | ||
342 | return -1; | 359 | return -1; |
343 | } | 360 | } |
344 | 361 | ||
362 | + if (sleep_test() < 0) { | ||
363 | + srs_trace("sleep_test failed"); | ||
364 | + return -1; | ||
365 | + } | ||
366 | + | ||
345 | if (thread_test() < 0) { | 367 | if (thread_test() < 0) { |
346 | srs_trace("thread_test failed"); | 368 | srs_trace("thread_test failed"); |
347 | return -1; | 369 | return -1; |
@@ -138,7 +138,7 @@ static char *_st_new_stk_segment(int size) | @@ -138,7 +138,7 @@ static char *_st_new_stk_segment(int size) | ||
138 | #ifdef MALLOC_STACK | 138 | #ifdef MALLOC_STACK |
139 | void *vaddr = malloc(size); | 139 | void *vaddr = malloc(size); |
140 | #else | 140 | #else |
141 | - #error Unknown Stack Malloc | 141 | + #error "Only Supports Malloc Stack" |
142 | #endif | 142 | #endif |
143 | 143 | ||
144 | return (char *)vaddr; | 144 | return (char *)vaddr; |
-
请 注册 或 登录 后发表评论