| static int fforkstacksize = 16384; |
| |
| typedef struct Stack Stack; |
| struct Stack |
| { |
| Stack *next; |
| Stack *fnext; |
| int pid; |
| }; |
| |
| static Lock stacklock; |
| static Stack *freestacks; |
| static Stack *allstacks; |
| static int stackmallocs; |
| static void gc(void); |
| |
| static void* |
| mallocstack(void) |
| { |
| Stack *p; |
| |
| lock(&stacklock); |
| top: |
| p = freestacks; |
| if(p) |
| freestacks = p->fnext; |
| else{ |
| if(stackmallocs++%1 == 0) |
| gc(); |
| if(freestacks) |
| goto top; |
| p = malloc(fforkstacksize); |
| p->next = allstacks; |
| allstacks = p; |
| } |
| if(p) |
| p->pid = 1; |
| unlock(&stacklock); |
| return p; |
| } |
| |
| static void |
| gc(void) |
| { |
| Stack *p; |
| |
| for(p=allstacks; p; p=p->next){ |
| if(p->pid > 1 && procexited(p->pid)){ |
| if(0) fprint(2, "reclaim stack from %d\n", p->pid); |
| p->pid = 0; |
| } |
| if(p->pid == 0){ |
| p->fnext = freestacks; |
| freestacks = p; |
| } |
| } |
| } |
| |
| static void |
| freestack(void *v) |
| { |
| Stack *p; |
| |
| p = v; |
| if(p == nil) |
| return; |
| lock(&stacklock); |
| p->fnext = freestacks; |
| p->pid = 0; |
| freestacks = p; |
| unlock(&stacklock); |
| return; |
| } |
| |
| |