aboutsummaryrefslogtreecommitdiff
path: root/src/libthread/procstack.ch
blob: ccf81866cec7b4ab9ef08e695cc7a19b39c53331 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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;
}