]>
Commit | Line | Data |
---|---|---|
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 | 37 | using namespace ::boost::multi_index; |
86c152f2 | 38 | |
b80f25df | 39 | // #define MTASKERTIMING 1 |
40 | ||
b786789d BH |
41 | struct 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 |
50 | template<class EventKey=int, class EventVal=int> class MTasker |
51 | { | |
52 | private: | |
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 | |
78 | public: | |
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 | */ | |
65542558 | 113 | MTasker(size_t stacksize=16*8192) : d_tid(0), d_maxtid(0), d_stacksize(stacksize), d_waitstatus(Error) |
86c152f2 | 114 | { |
9c811931 | 115 | initMainStackBounds(); |
86c152f2 BH |
116 | } |
117 | ||
118 | typedef void tfunc_t(void *); //!< type of the pointer that starts a thread | |
5b0ddd18 | 119 | int waitEvent(EventKey &key, EventVal *val=0, unsigned int timeoutMsec=0, struct timeval* now=0); |
86c152f2 BH |
120 | void yield(); |
121 | int sendEvent(const EventKey& key, const EventVal* val=0); | |
122 | void getEvents(std::vector<EventKey>& events); | |
d23a4bc7 | 123 | void makeThread(tfunc_t *start, void* val); |
5b0ddd18 | 124 | bool schedule(struct timeval* now=0); |
06857845 RG |
125 | bool noProcesses() const; |
126 | unsigned int numProcesses() const; | |
127 | int getTid() const; | |
ec6eacbc | 128 | unsigned int getMaxStackUsage(); |
b80f25df | 129 | unsigned int getUsec(); |
9170fbaf | 130 | |
86c152f2 | 131 | private: |
35ce8576 | 132 | EventKey d_eventkey; // for waitEvent, contains exact key it was awoken for |
86c152f2 BH |
133 | }; |
134 | #include "mtasker.cc" | |
caa6eefa | 135 | |
caa6eefa BH |
136 | #endif // MTASKER_HH |
137 |