doc: Made an actual INSTALL file.
[ashd.git] / lib / mt.c
... / ...
CommitLineData
1/*
2 ashd - A Sane HTTP Daemon
3 Copyright (C) 2008 Fredrik Tolf <fredrik@dolda2000.com>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#include <stdlib.h>
20#include <stdarg.h>
21#include <string.h>
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26#include <utils.h>
27#include <mt.h>
28
29#ifdef HAVE_VALGRIND
30#include <valgrind/memcheck.h>
31#endif
32
33struct muth *current = NULL;
34static ucontext_t mainctxt;
35
36static void freemt(struct muth *muth)
37{
38 if(muth->running)
39 abort();
40#ifdef VALGRIND_STACK_DEREGISTER
41 VALGRIND_STACK_DEREGISTER(muth->vgid);
42#endif
43 free(muth->stack);
44 free(muth);
45}
46
47static void muboot(void)
48{
49 struct muth *muth;
50
51 muth = current;
52 muth->running = 1;
53 muth->entry(muth, *muth->arglist);
54 muth->running = 0;
55 swapcontext(&muth->ctxt, muth->last);
56}
57
58struct muth *mustart(void (*fn)(struct muth *muth, va_list args), ...)
59{
60 struct muth *muth, *last;
61 va_list args;
62
63 omalloc(muth);
64 getcontext(&muth->ctxt);
65 muth->ctxt.uc_link = &mainctxt;
66 muth->ctxt.uc_stack.ss_size = 65536;
67 muth->ctxt.uc_stack.ss_sp = muth->stack = smalloc(muth->ctxt.uc_stack.ss_size);
68#ifdef VALGRIND_STACK_REGISTER
69 muth->vgid = VALGRIND_STACK_REGISTER(muth->stack, muth->stack + 65536);
70#endif
71 va_start(args, fn);
72 muth->entry = fn;
73 muth->arglist = &args;
74 makecontext(&muth->ctxt, muboot, 0);
75 if(current == NULL)
76 muth->last = &mainctxt;
77 else
78 muth->last = &current->ctxt;
79 last = current;
80 current = muth;
81 swapcontext(muth->last, &muth->ctxt);
82 current = last;
83 va_end(args);
84 if(!muth->running)
85 freemt(muth);
86 return(muth);
87}
88
89int yield(void)
90{
91 ucontext_t *ret;
92
93 if((current == NULL) || (current->last == NULL))
94 abort();
95 ret = current->last;
96 current->last = NULL;
97 swapcontext(&current->ctxt, ret);
98 return(current->yr);
99}
100
101void resume(struct muth *muth, int ret)
102{
103 struct muth *last;
104
105 if(muth->last != NULL)
106 abort();
107 if(current == NULL)
108 muth->last = &mainctxt;
109 else
110 muth->last = &current->ctxt;
111 last = current;
112 current = muth;
113 muth->yr = ret;
114 swapcontext(muth->last, &current->ctxt);
115 current = last;
116 if(!muth->running)
117 freemt(muth);
118}