Fibers: stacks of their own size, not a thread's

A fiber's stack was a thread's, PTHREAD_STACK_MIN included: 128K on
arm64 glibc, which is there for a thread's signals, and a loop's thread
takes none. It is BASESTACKSIZE with the service's stacksize added, and
the room kept for wolfSSL's handshake (TLSSTACKSIZE), as a thread's but
for that. Only reserved either way: measured with OpenSSL, a fiber holds
8K to 12K of it, TLS handshakes included.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Vladimir Dubrovin 2026-10-27 19:46:10 +03:00
parent 7e3182ae89
commit 17a5287fce
3 changed files with 13 additions and 5 deletions

View File

@ -278,7 +278,7 @@ static int srvspawn(struct srvstart *s, SOCKET client_sock){
/* on a loop: what is posted to it made now, so that posting it, done
once the client is counted, cannot fail */
if(loopwanted(srv)) job = loopjobnew(need);
if(loopwanted(srv)) job = loopjobnew(srv->stacksize);
/* an idle worker if one has the stack this service needs */
_3proxy_mutex_lock(&tpool.mutex);

View File

@ -100,7 +100,15 @@ static int loopsfailed;
/* the loop of this thread, NULL but in a loop's thread */
static LTLS struct looper *curlooper;
static size_t fiberstack(size_t need){
/* A fiber's stack: a thread's, the service's stacksize added, with room
kept for wolfSSL (TLSSTACKSIZE), which unless built for a small stack
takes much of it in a handshake; reserved only, a page held as it is
used. Not PTHREAD_STACK_MIN, which is for a thread's signals: a loop's
thread takes none. What the C library would want a big stack for, its
resolver, runs on the thread's own (onthreadstack()). */
static size_t fiberstack(int extra){
size_t need = BASESTACKSIZE + TLSSTACKSIZE + (extra > 0? (size_t)extra : 0);
#ifdef _WIN32
/* only reserved: Windows commits as it is used, and takes some for
itself */
@ -1233,7 +1241,7 @@ static int loopwanted(struct srvparam *srv){
}
/* What srvspawn() hands to a loop, made before: posting cannot fail. */
static struct loopjob *loopjobnew(size_t stacksize){
static struct loopjob *loopjobnew(int stacksize){
struct loopjob *job = malloc(sizeof(*job));
if(job){
@ -1264,7 +1272,7 @@ static int onlooper(void){
static int loopwanted(struct srvparam *srv){
return 0;
}
static struct loopjob *loopjobnew(size_t stacksize){
static struct loopjob *loopjobnew(int stacksize){
return NULL;
}
static void loopspawn(struct loopjob *job, struct clientparam *param){

View File

@ -84,7 +84,7 @@ static int poolpark(struct clientparam *param);
static int srvspawn(struct srvstart *s, SOCKET client_sock);
struct loopjob;
static int loopwanted(struct srvparam *srv);
static struct loopjob *loopjobnew(size_t stacksize);
static struct loopjob *loopjobnew(int stacksize);
static void loopspawn(struct loopjob *job, struct clientparam *param);
static int onlooper(void);
static void filterswap(struct clientparam *param, unsigned char **cur, unsigned char *now);