1 /* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 #ifndef ndb_mt_hpp
24 #define ndb_mt_hpp
25 
26 #include <kernel_types.h>
27 #include <ndb_limits.h>
28 #include <TransporterDefinitions.hpp>
29 #include <portlib/NdbTick.h>
30 #include <SimulatedBlock.hpp>
31 #include <util/Bitmask.hpp>
32 
33 #define JAM_FILE_ID 275
34 
35 
36 #define NUM_MAIN_THREADS 2 // except receiver
37 /*
38   MAX_BLOCK_THREADS need not include the send threads since it's
39   used to set size of arrays used by all threads that contains a
40   job buffer and executes signals. The send threads only sends
41   messages directed to other nodes and contains no blocks and
42   executes thus no signals.
43 */
44 #define MAX_BLOCK_THREADS (NUM_MAIN_THREADS +       \
45                            MAX_NDBMT_LQH_THREADS +  \
46                            MAX_NDBMT_TC_THREADS +   \
47                            MAX_NDBMT_RECEIVE_THREADS)
48 
49 static_assert(MAX_BLOCK_THREADS == NDB_MAX_BLOCK_THREADS, "");
50 
51 Uint32 mt_get_instance_count(Uint32 block);
52 
53 /* Assign block instances to thread */
54 void mt_init_thr_map();
55 void mt_add_thr_map(Uint32 block, Uint32 instance);
56 void mt_finalize_thr_map();
57 
58 void sendlocal(Uint32 self, const struct SignalHeader *s,
59                const Uint32 *data, const Uint32 secPtr[3]);
60 void sendprioa(Uint32 self, const struct SignalHeader *s,
61                const Uint32 *data, const Uint32 secPtr[3]);
62 void senddelay(Uint32 thr_no, const struct SignalHeader*, Uint32 delay);
63 void mt_execSTOP_FOR_CRASH();
64 
65 /**
66  * Interface methods to SimulatedBlock for ndbtmd.
67  */
68 void mt_getSendBufferLevel(Uint32 self, NodeId node, SB_LevelType &level);
69 Uint32 mt_getSignalsInJBB(Uint32 self);
70 NDB_TICKS mt_getHighResTimer(Uint32 self);
71 void mt_setNoSend(Uint32 self);
72 void mt_startChangeNeighbourNode();
73 void mt_setNeighbourNode(NodeId node);
74 void mt_endChangeNeighbourNode();
75 void mt_setWakeupThread(Uint32 self, Uint32 wakeup_instance);
76 void mt_setOverloadStatus(Uint32 self,
77                          OverloadStatus new_status);
78 void mt_setNodeOverloadStatus(Uint32 self,
79                              OverloadStatus new_status);
80 void mt_setSendNodeOverloadStatus(OverloadStatus new_status);
81 void mt_getPerformanceTimers(Uint32 self,
82                              Uint64 & micros_sleep,
83                              Uint64 & spin_time,
84                              Uint64 & buffer_full_sleep,
85                              Uint64 & micros_send);
86 
87 Uint32 mt_getConfiguredSpintime(Uint32 self);
88 void mt_setSpintime(Uint32 self, Uint32 new_spintime);
89 Uint32 mt_getWakeupLatency(void);
90 void mt_setWakeupLatency(Uint32);
91 
92 const char *mt_getThreadName(Uint32 self);
93 const char *mt_getThreadDescription(Uint32 self);
94 void mt_getSendPerformanceTimers(Uint32 send_instance,
95                                  Uint64 & exec_time,
96                                  Uint64 & sleep_time,
97                                  Uint64 & spin_time,
98                                  Uint64 & user_time_os,
99                                  Uint64 & kernel_time_os,
100                                  Uint64 & elapsed_time_os);
101 Uint32 mt_getNumSendThreads();
102 Uint32 mt_getNumThreads();
103 void mt_flush_send_buffers(Uint32 self);
104 void mt_set_watchdog_counter(Uint32 self);
105 void mt_assign_recv_thread_new_trp(Uint32 trp_id);
106 void mt_assign_multi_trps_to_send_threads();
107 bool mt_epoll_add_trp(Uint32 self, NodeId node_id, TrpId trp_id);
108 bool mt_is_recv_thread_for_new_trp(Uint32 self,
109                                    NodeId node_id,
110                                    TrpId trp_id);
111 
112 SendStatus mt_send_remote(Uint32 self, const SignalHeader *sh, Uint8 prio,
113                           const Uint32 *data, NodeId nodeId,
114                           const LinearSectionPtr ptr[3]);
115 SendStatus mt_send_remote(Uint32 self, const SignalHeader *sh, Uint8 prio,
116                           const Uint32 *data, NodeId nodeId,
117                           class SectionSegmentPool *thePool,
118                           const SegmentedSectionPtr ptr[3]);
119 
120 #ifdef ERROR_INSERT
121 void mt_set_delayed_prepare(Uint32 self);
122 #endif
123 
124 /**
125  * Lock/unlock pools for long signal section(s)
126  */
127 void mt_section_lock();
128 void mt_section_unlock();
129 
130 int mt_checkDoJob(Uint32 receiver_thread_idx);
131 
132 /**
133  * Are we (not) multi threaded
134  */
135 bool NdbIsMultiThreaded();
136 
137 /**
138  * Get a bitset with a set bit for each thread holding an instance of any block
139  * in blocks[], not looking at proxy block instances.
140  */
141 Uint32 mt_get_threads_for_blocks_no_proxy(const Uint32 blocks[],
142                                           BlockThreadBitmask& mask);
143 
144 /**
145  * Get a bitset with a set bit for each thread that given thread can send
146  * signals too.
147  */
148 Uint32 mt_get_addressable_threads(const Uint32 my_thr_no,
149                                   BlockThreadBitmask& mask);
150 
151 /**
152  * wakeup thread running block
153  */
154 void mt_wakeup(class SimulatedBlock*);
155 
156 #ifdef VM_TRACE
157 /**
158  * Assert that thread calling this function is "owner" of block instance
159  */
160 void mt_assert_own_thread(class SimulatedBlock*);
161 #endif
162 
163 /**
164  * return list of references running in this thread
165  */
166 Uint32
167 mt_get_blocklist(class SimulatedBlock*, Uint32 dst[], Uint32 len);
168 
169 
170 struct ndb_thr_stat
171 {
172   Uint32 thr_no;
173   Uint64 os_tid;
174   const char * name;
175   Uint64 loop_cnt;
176   Uint64 exec_cnt;
177   Uint64 wait_cnt;
178   Uint64 local_sent_prioa;
179   Uint64 local_sent_priob;
180   Uint64 remote_sent_prioa;
181   Uint64 remote_sent_priob;
182 };
183 
184 
185 void
186 mt_get_thr_stat(class SimulatedBlock *, ndb_thr_stat* dst);
187 
188 #define NUM_SPIN_INTERVALS 16
189 struct ndb_spin_stat
190 {
191   Uint32 m_sleep_longer_spin_time;
192   Uint32 m_sleep_shorter_spin_time;
193   Uint32 m_num_waits;
194   Uint32 m_micros_sleep_times[NUM_SPIN_INTERVALS];
195   Uint32 m_spin_interval[NUM_SPIN_INTERVALS];
196 };
197 
198 void
199 mt_get_spin_stat(class SimulatedBlock *, ndb_spin_stat *dst);
200 
201 void
202 mt_set_spin_stat(class SimulatedBlock *, ndb_spin_stat *dst);
203 
204 /**
205  * Get TransporterReceiveHandle for a specific trpman instance
206  *   Currently used for error insert that block/unblock traffic
207  */
208 class TransporterReceiveHandle *
209 mt_get_trp_receive_handle(unsigned instance);
210 
211 /**
212  * return receiver thread handling a particular node
213  *   returned number is indexed from 0 and upwards to #receiver threads
214  *   (or MAX_NODES is none)
215  */
216 Uint32
217 mt_get_recv_thread_idx(TrpId trp_id);
218 
219 #if defined(USE_INIT_GLOBAL_VARIABLES)
220 void mt_enable_global_variables(Uint32 self);
221 void mt_disable_global_variables(Uint32 self);
222 void mt_init_global_variables_ptr_instances(Uint32,void**,size_t);
223 void mt_init_global_variables_uint32_ptr_instances(Uint32,void**,size_t);
224 void mt_init_global_variables_uint32_instances(Uint32,void**,size_t);
225 #endif
226 
227 #undef JAM_FILE_ID
228 
229 #endif
230