diff --git a/Makefile b/Makefile index cc3fedf..14d4658 100644 --- a/Makefile +++ b/Makefile @@ -191,6 +191,9 @@ endif # # make EXTRA_CFLAGS=-DDEBUG_STATS # +# or cache the stack and reuse it: +# make EXTRA_CFLAGS=-DMD_CACHE_STACK +# # or enable the coverage for utest: # make UTEST_FLAGS="-fprofile-arcs -ftest-coverage" # diff --git a/README.md b/README.md index 67d224a..e1959a7 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,7 @@ The branch [srs](https://github.com/ossrs/state-threads/tree/srs) was patched an - [x] Check capability for backtrack. - [x] Support set specifics for any thread. - [x] Support st_destroy to free resources for asan. +- [x] Support free the stack, [#38](https://github.com/ossrs/state-threads/issues/38). - [ ] System: Support sendmmsg for UDP, [#12](https://github.com/ossrs/state-threads/issues/12). ## GDB Tools diff --git a/stk.c b/stk.c index a81bee0..02088a4 100644 --- a/stk.c +++ b/stk.c @@ -57,13 +57,16 @@ __thread int _st_num_free_stacks = 0; __thread int _st_randomize_stacks = 0; static char *_st_new_stk_segment(int size); +static void _st_delete_stk_segment(char *vaddr, int size); _st_stack_t *_st_stack_new(int stack_size) { _st_clist_t *qp; _st_stack_t *ts; int extra; - + + /* If cache stack, we try to use stack from the cache list. */ +#ifdef MD_CACHE_STACK for (qp = _st_free_stacks.next; qp != &_st_free_stacks; qp = qp->next) { ts = _ST_THREAD_STACK_PTR(qp); if (ts->stk_size >= stack_size) { @@ -75,11 +78,34 @@ _st_stack_t *_st_stack_new(int stack_size) return ts; } } +#endif + + extra = _st_randomize_stacks ? _ST_PAGE_SIZE : 0; + /* If not cache stack, we will free all stack in the list, which contains the stack to be freed. + * Note that we should never directly free it at _st_stack_free, because it is still be used, + * and will cause crash. */ +#ifndef MD_CACHE_STACK + for (qp = _st_free_stacks.next; qp != &_st_free_stacks;) { + ts = _ST_THREAD_STACK_PTR(qp); + /* Before qp is freed, move to next one, because the qp will be freed when free the ts. */ + qp = qp->next; + + ST_REMOVE_LINK(&ts->links); + _st_num_free_stacks--; + +#if defined(DEBUG) && !defined(MD_NO_PROTECT) + mprotect(ts->vaddr, REDZONE, PROT_READ | PROT_WRITE); + mprotect(ts->stk_top + extra, REDZONE, PROT_READ | PROT_WRITE); +#endif + + _st_delete_stk_segment(ts->vaddr, ts->vaddr_size); + free(ts); + } +#endif /* Make a new thread stack object. */ if ((ts = (_st_stack_t *)calloc(1, sizeof(_st_stack_t))) == NULL) return NULL; - extra = _st_randomize_stacks ? _ST_PAGE_SIZE : 0; ts->vaddr_size = stack_size + 2*REDZONE + extra; ts->vaddr = _st_new_stk_segment(ts->vaddr_size); if (!ts->vaddr) { @@ -114,7 +140,7 @@ void _st_stack_free(_st_stack_t *ts) { if (!ts) return; - + /* Put the stack on the free list */ ST_APPEND_LINK(&ts->links, _st_free_stacks.prev); _st_num_free_stacks++; @@ -152,8 +178,6 @@ static char *_st_new_stk_segment(int size) } -/* Not used */ -#if 0 void _st_delete_stk_segment(char *vaddr, int size) { #ifdef MALLOC_STACK @@ -162,7 +186,6 @@ void _st_delete_stk_segment(char *vaddr, int size) (void) munmap(vaddr, size); #endif } -#endif int st_randomize_stacks(int on) { diff --git a/tools/backtrace/backtrace.c b/tools/backtrace/backtrace.c index 4332497..0af24cf 100644 --- a/tools/backtrace/backtrace.c +++ b/tools/backtrace/backtrace.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: MIT */ -/* Copyright (c) 2013-2022 Winlin */ +/* Copyright (c) 2013-2024 The SRS Authors */ #ifdef __linux__ #define _GNU_SOURCE diff --git a/tools/helloworld/helloworld.c b/tools/helloworld/helloworld.c index 7787044..5c30d69 100644 --- a/tools/helloworld/helloworld.c +++ b/tools/helloworld/helloworld.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: MIT */ -/* Copyright (c) 2013-2022 Winlin */ +/* Copyright (c) 2013-2024 The SRS Authors */ #include diff --git a/tools/porting/porting.c b/tools/porting/porting.c index 24cfc84..7267ac7 100644 --- a/tools/porting/porting.c +++ b/tools/porting/porting.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: MIT */ -/* Copyright (c) 2013-2022 Winlin */ +/* Copyright (c) 2013-2024 The SRS Authors */ #include #include diff --git a/tools/verify/verify.c b/tools/verify/verify.c index e59bc31..ea96e23 100644 --- a/tools/verify/verify.c +++ b/tools/verify/verify.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: MIT */ -/* Copyright (c) 2013-2022 Winlin */ +/* Copyright (c) 2013-2024 The SRS Authors */ #include diff --git a/utest/st_utest.cpp b/utest/st_utest.cpp index 568897f..4571bfb 100644 --- a/utest/st_utest.cpp +++ b/utest/st_utest.cpp @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: MIT */ -/* Copyright (c) 2013-2022 Winlin */ +/* Copyright (c) 2013-2024 The SRS Authors */ #include diff --git a/utest/st_utest.hpp b/utest/st_utest.hpp index e260cd0..470b9ed 100644 --- a/utest/st_utest.hpp +++ b/utest/st_utest.hpp @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: MIT */ -/* Copyright (c) 2013-2022 Winlin */ +/* Copyright (c) 2013-2024 The SRS Authors */ #ifndef ST_UTEST_PUBLIC_HPP #define ST_UTEST_PUBLIC_HPP diff --git a/utest/st_utest_coroutines.cpp b/utest/st_utest_coroutines.cpp index 03570df..fe57aa7 100644 --- a/utest/st_utest_coroutines.cpp +++ b/utest/st_utest_coroutines.cpp @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: MIT */ -/* Copyright (c) 2013-2022 Winlin */ +/* Copyright (c) 2013-2024 The SRS Authors */ #include diff --git a/utest/st_utest_tcp.cpp b/utest/st_utest_tcp.cpp index fce8cb9..ecbd839 100644 --- a/utest/st_utest_tcp.cpp +++ b/utest/st_utest_tcp.cpp @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: MIT */ -/* Copyright (c) 2013-2022 Winlin */ +/* Copyright (c) 2013-2024 The SRS Authors */ #include