Added muthread and logging library components.
[ashd.git] / lib / mt.c
CommitLineData
ddf99192
FT
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#include <valgrind/memcheck.h>
29
30struct muth *current = NULL;
31static ucontext_t mainctxt;
32
33static void freemt(struct muth *muth)
34{
35 if(muth->running)
36 abort();
37#ifdef VALGRIND_STACK_DEREGISTER
38 VALGRIND_STACK_DEREGISTER(muth->vgid);
39#endif
40 free(muth->stack);
41 free(muth);
42}
43
44static void muboot(void)
45{
46 struct muth *muth;
47
48 muth = current;
49 muth->running = 1;
50 muth->entry(muth, *muth->arglist);
51 muth->running = 0;
52 swapcontext(&muth->ctxt, muth->last);
53}
54
55struct muth *mustart(void (*fn)(struct muth *muth, va_list args), ...)
56{
57 struct muth *muth, *last;
58 va_list args;
59
60 omalloc(muth);
61 getcontext(&muth->ctxt);
62 muth->ctxt.uc_link = &mainctxt;
63 muth->ctxt.uc_stack.ss_size = 65536;
64 muth->ctxt.uc_stack.ss_sp = muth->stack = smalloc(muth->ctxt.uc_stack.ss_size);
65#ifdef VALGRIND_STACK_REGISTER
66 muth->vgid = VALGRIND_STACK_REGISTER(muth->stack, muth->stack + 65536);
67#endif
68 va_start(args, fn);
69 muth->entry = fn;
70 muth->arglist = &args;
71 makecontext(&muth->ctxt, muboot, 0);
72 if(current == NULL)
73 muth->last = &mainctxt;
74 else
75 muth->last = &current->ctxt;
76 last = current;
77 current = muth;
78 swapcontext(muth->last, &muth->ctxt);
79 current = last;
80 va_end(args);
81 if(!muth->running)
82 freemt(muth);
83 return(muth);
84}
85
86int yield(void)
87{
88 ucontext_t *ret;
89
90 if((current == NULL) || (current->last == NULL))
91 abort();
92 ret = current->last;
93 current->last = NULL;
94 swapcontext(&current->ctxt, ret);
95 return(current->yr);
96}
97
98void resume(struct muth *muth, int ret)
99{
100 struct muth *last;
101
102 if(muth->last != NULL)
103 abort();
104 if(current == NULL)
105 muth->last = &mainctxt;
106 else
107 muth->last = &current->ctxt;
108 last = current;
109 current = muth;
110 muth->yr = ret;
111 swapcontext(muth->last, &current->ctxt);
112 current = last;
113 if(!muth->running)
114 freemt(muth);
115}