]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/mtasker.hh
rec: Make sure that distribution-load-factor is >= 1.0 if set
[thirdparty/pdns.git] / pdns / mtasker.hh
CommitLineData
86c152f2 1/*
12471842
PL
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
86c152f2
BH
22#ifndef MTASKER_HH
23#define MTASKER_HH
15a0aaef 24#include <stdint.h>
86c152f2 25#include <queue>
76473b92 26#include <vector>
86c152f2
BH
27#include <map>
28#include <time.h>
27af6ab1
BH
29#include <boost/multi_index_container.hpp>
30#include <boost/multi_index/ordered_index.hpp>
31#include <boost/multi_index/key_extractors.hpp>
61b26744 32#include "namespaces.hh"
b80f25df 33#include "misc.hh"
5cf909f3
AN
34#include "mtasker_context.hh"
35#include <memory>
abc75058 36#include <boost/function.hpp>
27af6ab1 37using namespace ::boost::multi_index;
86c152f2 38
b80f25df 39// #define MTASKERTIMING 1
40
b786789d
BH
41struct KeyTag {};
42
86c152f2
BH
43//! The main MTasker class
44/** The main MTasker class. See the main page for more information.
16276aa8
RK
45 \tparam EventKey Type of the key with which events are to be identified. Defaults to int.
46 \tparam EventVal Type of the content or value of an event. Defaults to int. Cannot be set to void.
86c152f2
BH
47 \note The EventKey needs to have an operator< defined because it is used as the key of an associative array
48*/
5cf909f3 49
86c152f2
BH
50template<class EventKey=int, class EventVal=int> class MTasker
51{
52private:
5cf909f3 53 pdns_ucontext_t d_kernel;
86c152f2
BH
54 std::queue<int> d_runQueue;
55 std::queue<int> d_zombiesQueue;
56
ec6eacbc
BH
57 struct ThreadInfo
58 {
5cf909f3 59 std::shared_ptr<pdns_ucontext_t> context;
abc75058 60 boost::function<void(void)> start;
ec6eacbc
BH
61 char* startOfStack;
62 char* highestStackSeen;
b80f25df 63#ifdef MTASKERTIMING
64 CPUTime dt;
65 unsigned int totTime;
66#endif
ec6eacbc 67 };
35ce8576 68
ec6eacbc 69 typedef std::map<int, ThreadInfo> mthreads_t;
35ce8576
BH
70 mthreads_t d_threads;
71 int d_tid;
72 int d_maxtid;
73 size_t d_stacksize;
74
75 EventVal d_waitval;
7f1fa77d 76 enum waitstatusenum {Error=-1,TimeOut=0,Answer} d_waitstatus;
35ce8576
BH
77
78public:
86c152f2
BH
79 struct Waiter
80 {
27af6ab1 81 EventKey key;
5cf909f3 82 std::shared_ptr<pdns_ucontext_t> context;
5b0ddd18 83 struct timeval ttd;
ec6eacbc 84 int tid;
86c152f2
BH
85 };
86
27af6ab1
BH
87 typedef multi_index_container<
88 Waiter,
89 indexed_by <
90 ordered_unique<member<Waiter,EventKey,&Waiter::key> >,
5b0ddd18 91 ordered_non_unique<tag<KeyTag>, member<Waiter,struct timeval,&Waiter::ttd> >
27af6ab1
BH
92 >
93 > waiters_t;
94
86c152f2 95 waiters_t d_waiters;
27af6ab1 96
9c811931
RG
97 void initMainStackBounds()
98 {
99#ifdef HAVE_FIBER_SANITIZER
100 pthread_attr_t attr;
101 pthread_attr_init(&attr);
102 pthread_getattr_np(pthread_self(), &attr);
103 pthread_attr_getstack(&attr, &t_mainStack, &t_mainStackSize);
104 pthread_attr_destroy(&attr);
105#endif /* HAVE_FIBER_SANITIZER */
106 }
107
86c152f2
BH
108 //! Constructor
109 /** Constructor with a small default stacksize. If any of your threads exceeds this stack, your application will crash.
110 This limit applies solely to the stack, the heap is not limited in any way. If threads need to allocate a lot of data,
111 the use of new/delete is suggested.
112 */
e27e7823 113 MTasker(size_t stacksize=16*8192) : d_tid(0), d_maxtid(0), d_stacksize(stacksize), d_waitstatus(Error)
86c152f2 114 {
9c811931 115 initMainStackBounds();
aa1c91d9
PD
116
117 // make sure our stack is 16-byte aligned to make all the architectures happy
118 d_stacksize = d_stacksize >> 4 << 4;
86c152f2
BH
119 }
120
121 typedef void tfunc_t(void *); //!< type of the pointer that starts a thread
5b0ddd18 122 int waitEvent(EventKey &key, EventVal *val=0, unsigned int timeoutMsec=0, struct timeval* now=0);
86c152f2
BH
123 void yield();
124 int sendEvent(const EventKey& key, const EventVal* val=0);
125 void getEvents(std::vector<EventKey>& events);
d23a4bc7 126 void makeThread(tfunc_t *start, void* val);
5b0ddd18 127 bool schedule(struct timeval* now=0);
06857845
RG
128 bool noProcesses() const;
129 unsigned int numProcesses() const;
130 int getTid() const;
ec6eacbc 131 unsigned int getMaxStackUsage();
b80f25df 132 unsigned int getUsec();
9170fbaf 133
86c152f2 134private:
35ce8576 135 EventKey d_eventkey; // for waitEvent, contains exact key it was awoken for
86c152f2
BH
136};
137#include "mtasker.cc"
caa6eefa 138
caa6eefa
BH
139#endif // MTASKER_HH
140