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