]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/mtasker.hh
add 'speedtest' infrastructure
[thirdparty/pdns.git] / pdns / mtasker.hh
CommitLineData
86c152f2
BH
1/*
2 PowerDNS Versatile Database Driven Nameserver
a323a5c7 3 Copyright (C) 2002 - 2006 PowerDNS.COM BV
86c152f2
BH
4
5 This program is free software; you can redistribute it and/or modify
22dc646a
BH
6 it under the terms of the GNU General Public License version 2
7 as published by the Free Software Foundation
8
86c152f2
BH
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, write to the Free Software
06bd9ccf 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
86c152f2
BH
18*/
19#ifndef MTASKER_HH
20#define MTASKER_HH
caa6eefa
BH
21
22#ifdef WIN32
23# include "win32_mtasker.hh"
24#else
25
86c152f2
BH
26#include <signal.h>
27#include <ucontext.h>
28#include <queue>
29#include <vector>
30#include <map>
31#include <time.h>
27af6ab1
BH
32#include <boost/multi_index_container.hpp>
33#include <boost/multi_index/ordered_index.hpp>
34#include <boost/multi_index/key_extractors.hpp>
35using namespace boost;
36using namespace ::boost::multi_index;
86c152f2 37
b786789d
BH
38struct KeyTag {};
39
86c152f2
BH
40//! The main MTasker class
41/** The main MTasker class. See the main page for more information.
42 \param EventKey Type of the key with which events are to be identified. Defaults to int.
43 \param EventVal Type of the content or value of an event. Defaults to int. Cannot be set to void.
44 \note The EventKey needs to have an operator< defined because it is used as the key of an associative array
45*/
46template<class EventKey=int, class EventVal=int> class MTasker
47{
48private:
49 ucontext_t d_kernel;
50 std::queue<int> d_runQueue;
51 std::queue<int> d_zombiesQueue;
52
35ce8576
BH
53
54 typedef std::map<int, ucontext_t*> mthreads_t;
55 mthreads_t d_threads;
56 int d_tid;
57 int d_maxtid;
58 size_t d_stacksize;
59
60 EventVal d_waitval;
7f1fa77d 61 enum waitstatusenum {Error=-1,TimeOut=0,Answer} d_waitstatus;
35ce8576
BH
62
63public:
86c152f2
BH
64 struct Waiter
65 {
27af6ab1 66 EventKey key;
86c152f2
BH
67 ucontext_t *context;
68 time_t ttd;
69 int tid;
70 };
71
27af6ab1
BH
72 typedef multi_index_container<
73 Waiter,
74 indexed_by <
75 ordered_unique<member<Waiter,EventKey,&Waiter::key> >,
99173b8b 76 ordered_non_unique<tag<KeyTag>, member<Waiter,time_t,&Waiter::ttd> >
27af6ab1
BH
77 >
78 > waiters_t;
79
86c152f2 80 waiters_t d_waiters;
27af6ab1 81
86c152f2
BH
82 //! Constructor
83 /** Constructor with a small default stacksize. If any of your threads exceeds this stack, your application will crash.
84 This limit applies solely to the stack, the heap is not limited in any way. If threads need to allocate a lot of data,
85 the use of new/delete is suggested.
86 */
87 MTasker(size_t stacksize=8192) : d_stacksize(stacksize)
88 {
89 d_maxtid=0;
90 }
91
92 typedef void tfunc_t(void *); //!< type of the pointer that starts a thread
f6c254c1 93 int waitEvent(EventKey &key, EventVal *val=0, unsigned int timeout=0, unsigned int now=0);
86c152f2
BH
94 void yield();
95 int sendEvent(const EventKey& key, const EventVal* val=0);
96 void getEvents(std::vector<EventKey>& events);
d23a4bc7 97 void makeThread(tfunc_t *start, void* val);
f6c254c1 98 bool schedule(unsigned int now=0);
86c152f2 99 bool noProcesses();
e5d684f9 100 unsigned int numProcesses();
c836dc19 101 int getTid();
9170fbaf 102
86c152f2
BH
103private:
104 static void threadWrapper(MTasker *self, tfunc_t *tf, int tid, void* val);
35ce8576 105 EventKey d_eventkey; // for waitEvent, contains exact key it was awoken for
86c152f2
BH
106};
107#include "mtasker.cc"
caa6eefa
BH
108
109#endif // WIN32
110#endif // MTASKER_HH
111