]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/mtasker.hh
auth: switch circleci mssql image
[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 70 mthreads_t d_threads;
c4975eaf
RG
71 size_t d_stacksize;
72 size_t d_threadsCount;
35ce8576
BH
73 int d_tid;
74 int d_maxtid;
35ce8576
BH
75
76 EventVal d_waitval;
7f1fa77d 77 enum waitstatusenum {Error=-1,TimeOut=0,Answer} d_waitstatus;
35ce8576
BH
78
79public:
86c152f2
BH
80 struct Waiter
81 {
27af6ab1 82 EventKey key;
5cf909f3 83 std::shared_ptr<pdns_ucontext_t> context;
5b0ddd18 84 struct timeval ttd;
ec6eacbc 85 int tid;
86c152f2
BH
86 };
87
27af6ab1
BH
88 typedef multi_index_container<
89 Waiter,
90 indexed_by <
91 ordered_unique<member<Waiter,EventKey,&Waiter::key> >,
5b0ddd18 92 ordered_non_unique<tag<KeyTag>, member<Waiter,struct timeval,&Waiter::ttd> >
27af6ab1
BH
93 >
94 > waiters_t;
95
86c152f2 96 waiters_t d_waiters;
27af6ab1 97
9c811931
RG
98 void initMainStackBounds()
99 {
100#ifdef HAVE_FIBER_SANITIZER
101 pthread_attr_t attr;
102 pthread_attr_init(&attr);
103 pthread_getattr_np(pthread_self(), &attr);
104 pthread_attr_getstack(&attr, &t_mainStack, &t_mainStackSize);
105 pthread_attr_destroy(&attr);
106#endif /* HAVE_FIBER_SANITIZER */
107 }
108
86c152f2
BH
109 //! Constructor
110 /** Constructor with a small default stacksize. If any of your threads exceeds this stack, your application will crash.
111 This limit applies solely to the stack, the heap is not limited in any way. If threads need to allocate a lot of data,
112 the use of new/delete is suggested.
113 */
c4975eaf 114 MTasker(size_t stacksize=16*8192) : d_stacksize(stacksize), d_threadsCount(0), d_tid(0), d_maxtid(0), d_waitstatus(Error)
86c152f2 115 {
9c811931 116 initMainStackBounds();
aa1c91d9
PD
117
118 // make sure our stack is 16-byte aligned to make all the architectures happy
119 d_stacksize = d_stacksize >> 4 << 4;
86c152f2
BH
120 }
121
122 typedef void tfunc_t(void *); //!< type of the pointer that starts a thread
5b0ddd18 123 int waitEvent(EventKey &key, EventVal *val=0, unsigned int timeoutMsec=0, struct timeval* now=0);
86c152f2
BH
124 void yield();
125 int sendEvent(const EventKey& key, const EventVal* val=0);
126 void getEvents(std::vector<EventKey>& events);
d23a4bc7 127 void makeThread(tfunc_t *start, void* val);
5b0ddd18 128 bool schedule(struct timeval* now=0);
06857845
RG
129 bool noProcesses() const;
130 unsigned int numProcesses() const;
131 int getTid() const;
ec6eacbc 132 unsigned int getMaxStackUsage();
b80f25df 133 unsigned int getUsec();
9170fbaf 134
86c152f2 135private:
35ce8576 136 EventKey d_eventkey; // for waitEvent, contains exact key it was awoken for
86c152f2
BH
137};
138#include "mtasker.cc"
caa6eefa 139
caa6eefa
BH
140#endif // MTASKER_HH
141