1 /*
2 Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #ifndef SIMULATEDBLOCK_H
26 #define SIMULATEDBLOCK_H
27
28 #include <new>
29
30 #include <NdbTick.h>
31 #include <kernel_types.h>
32 #include <util/version.h>
33 #include <ndb_limits.h>
34
35 #include "VMSignal.hpp"
36 #include <RefConvert.hpp>
37 #include <BlockNumbers.h>
38 #include <GlobalSignalNumbers.h>
39
40 #include "pc.hpp"
41 #include "Pool.hpp"
42 #include <NodeInfo.hpp>
43 #include <NodeState.hpp>
44 #include "OutputStream.hpp"
45 #include "GlobalData.hpp"
46 #include "LongSignal.hpp"
47 #include <SignalLoggerManager.hpp>
48
49 #include <ErrorReporter.hpp>
50 #include <ErrorHandlingMacros.hpp>
51
52 #include "IntrusiveList.hpp"
53 #include "DLHashTable.hpp"
54 #include "WOPool.hpp"
55 #include "RWPool.hpp"
56 #include "Callback.hpp"
57 #include "SafeCounter.hpp"
58
59 #include <mgmapi.h>
60 #include <mgmapi_config_parameters.h>
61 #include <mgmapi_config_parameters_debug.h>
62 #include <kernel_config_parameters.h>
63 #include <Configuration.hpp>
64
65 #include <signaldata/ReadConfig.hpp>
66 #include "ndbd_malloc_impl.hpp"
67 #include <blocks/record_types.hpp>
68
69 #include "Ndbinfo.hpp"
70 #include "portlib/NdbMem.h"
71 #include <ndb_global.h>
72 #include "BlockThreadBitmask.hpp"
73
74 struct CHARSET_INFO;
75
76 #define JAM_FILE_ID 248
77
78
79 #ifdef VM_TRACE
80 #define D(x) \
81 do { \
82 char buf[200]; \
83 if (!debugOutOn()) break; \
84 debugOutLock(); \
85 debugOutStream() << debugOutTag(buf, __LINE__) << x << dec << "\n"; \
86 debugOutUnlock(); \
87 } while (0)
88 #define V(x) " " << #x << ":" << (x)
89 #else
90 #define D(x) do { } while(0)
91 #undef V
92 #endif
93
94 /**
95 * LCP scans and Backup scans always use batch size 16, there are even
96 * optimisations in allocation and handling LCP scans and Backup scans
97 * keeping proper rates using this particular batch size. This is also
98 * true for Node recovery scans as started by COPY_FRAGREQ.
99 */
100 #define ZRESERVED_SCAN_BATCH_SIZE 16
101 /**
102 * Something for filesystem access
103 */
104 struct NewBaseAddrBits /* 32 bits */
105 {
106 unsigned int q : 4; /* Highest index - 2log */
107 /* Strings are treated as 16 bit indexed */
108 /* variables with the number of characters in */
109 /* index 0, byte 0 */
110 unsigned int v : 3; /* Size in bits - 2log */
111 unsigned int unused : 25 ;
112 };
113
114 typedef struct NewVar
115 {
116 Uint32 * WA;
117 Uint32 nrr;
118 Uint32 ClusterSize; /* Real Cluster size */
119 NewBaseAddrBits bits;
120 } NewVARIABLE; /* 128 bits */
121
122 struct Block_context
123 {
Block_contextBlock_context124 Block_context(class Configuration& cfg, class Ndbd_mem_manager& mm)
125 : m_config(cfg), m_mm(mm) {}
126 class Configuration& m_config;
127 class Ndbd_mem_manager& m_mm;
128 };
129
130 struct PackedWordsContainer
131 {
132 BlockReference hostBlockRef;
133 Uint32 noOfPackedWords;
134 Uint32 packedWords[30];
135 }; // 128 bytes
136
137 #define LIGHT_LOAD_CONST 0
138 #define MEDIUM_LOAD_CONST 1
139 #define OVERLOAD_CONST 2
140 enum OverloadStatus
141 {
142 LIGHT_LOAD = LIGHT_LOAD_CONST,
143 MEDIUM_LOAD = MEDIUM_LOAD_CONST,
144 OVERLOAD = OVERLOAD_CONST
145 };
146
147 /**
148 Description of NDB Software Architecture
149 ----------------------------------------
150
151 The NDB software architecture has two foundations, blocks and signals.
152 The base object for the blocks is the below SimulatedBlock class and
153 the signal object is the base class Signal defined in VMSignal.hpp.
154
155 Blocks are intended as software units that owns its own data and it
156 communicates with other blocks only through signals. Each block owns
157 its own set of data which it entirely controls. There has been some
158 optimisations where blocks always executing in the same thread can do
159 some shortcuts by calling functions in a different block directly.
160 There is even some code to call functions in a block in a different
161 thread, in this case however some mutex is required to protect the
162 data.
163
164 Blocks are gathered together in threads. Threads are gathered into nodes.
165 So when sending a signal you need to send it to an address. The address is
166 a 32-bit word. It is a bit similar to IPv4 addresses. The address is
167 setup in the following manner:
168
169 -- Bit 0-8 ------- Bit 9-15 ------ Bit 16-31 ------
170 | Block number | Thread id | NodeId |
171 ---------------------------------------------------
172
173 So when delivering a signal we start by checking the node id. If the node
174 id is our own node id, then we will continue checking thread id. If it
175 is destined to another node, then we move the signal sending to the module
176 that takes care of transporting the signal to another node in the cluster.
177
178 Each other node is found using a socket over TCP/IP. The architecture
179 supports also other ways to transport signals such as using some form
180 of shared memory between processes on the same or different machines.
181 It would also be possible to extend the architecture such that we
182 might use different sockets for different threads in the node.
183
184 If the signal is destined for a different thread then we transport the
185 signal to that thread, we use a separate memory buffer for each two
186 threads that communicate such that the communication between threads is
187 completely lock-free.
188
189 One block number can be used in several threads. So e.g. the LDM threads
190 all contain its own instance of the DBLQH block. The method instance()
191 gets the instance number of the currently executing block. The method
192 reference() gets the block reference of the currently executing block.
193
194 If we send to ourselves we put the signal in the memory buffer for
195 communication with our own thread.
196
197 The current limits of the architecture is a maximum of 512 block numbers.
198 We currently use less than 25 of those numbers. The maximum number of
199 threads are 128 threads. We currently can use at most 72 threads.
200 The current node limit is 255 nodes and node id 0 is a special case.
201
202 So there is still a lot of space in the addressing mechanism for growth
203 in terms of number of threads, blocks and nodes and even for introduction
204 of new addressable units like subthreads or similar things.
205
206 The software architecture also contains a structure for how signals are
207 structured. Each signal is sent at a certain priority level. Finally also
208 there is a concept of sending delayed signals to blocks within the same
209 thread.
210
211 Priority level on signals
212 -------------------------
213 So starting with priority level a signal can be sent on high priority
214 (JBA) and normal priority (JBB). The priority level can be used also when
215 sending to other nodes. The priority will however not be used to prioritise
216 the signal in sending it over the socket to the receiving node.
217
218 Each thread has its own buffer for A-priority signals. In the scheduler
219 we will always execute all signals in the A-priority buffer first. If
220 new A-priority signals are sent during these signals, then they will also
221 be executed until no more signals exist on A-priority level. So it's not
222 allowed to have a flow of signals all executing at A-level. We always have
223 to insert a signal in the flow that either goes down to B-level or use some
224 form of delayed signal.
225
226 If an A-level signal is sent from a B-level signal it will be handled
227 differently in the single threaded ndbd and the multi-threaded ndbmtd. In
228 ndbmtd it will be executed after executing up to 128 B-level signals. In
229 ndbd it will be executed as the next signal. So one cannot assume that an
230 A-level signal will be executed before a specific B-level signal. A B-level
231 signal can even be executed before an A-level signal although it was sent
232 after the A-level signal.
233
234 Delayed signals
235 ---------------
236 Delayed signals are used to create threads of activities that execute without
237 consuming too much CPU activity. Delayed signals can only be sent internally
238 within the same thread. When the signal has been delayed and is taken out of
239 its timer queue its inserted into the priority A buffer.
240
241 Bounded delay signals
242 ---------------------
243 A special form of delayed signal also exists, this is sent with delay equal to
244 the constant BOUNDED_DELAY. This means that the signal will be executed as a
245 priority A task as soon as the current set of B-level tasks are done. This is
246 similar to sending an A-level signal from a B-level job in ndbmtd. However for
247 ndbd it's not the same thing and also when sending an A-level signal from an
248 A-level signal it is also not the same thing.
249
250 So a delayed signal with delay BOUNDED_DELAY is a special type of signal
251 with a bounded delay. The bound is that no more than 100 B-level signals will
252 be executed before this signal is executed. Given our design requirements
253 a B-level signal should mostly be executed within at most 5-10 microseconds
254 or so, mostly much shorter than this even, so a normal execution time of
255 a signal would be below 1 microsecond. So 100 signals should almost never
256 execute for more than 1000 microseconds and rarely go beyond even 100
257 microseconds.
258
259 So these bounded delay signals are a good tool to ensure that activitites
260 such as backups, checkpoints, node recovery activities, altering of tables
261 and similar things gets executed at a certain rate. Without any possibility
262 of bounded delay signals it is very hard to implement an activity that gets
263 executed at a certain rate.
264
265 So in a sense we're using the bounded delay signals to implement a form of
266 time-sharing priority, certain activities are allowed to use a proportion
267 of the available CPU resources, not too much, but also not too little. If
268 an LCP gets bogged down by user transactions then the system will eventually
269 run out of REDO log space. If a node recovery activity gets bogged down by
270 user transactions then we will run for too long with only one replica in the
271 node group which is bad for system availability.
272
273 Execute direct signals
274 ----------------------
275 If the receiving block is within the same thread, then it is possible to
276 send the signal using the method EXECUTE_DIRECT. This execution will
277 happen immediately and won't be scheduled for later, it will be done in
278 the same fashion as a function call.
279
280 Signals
281 -------
282 Signals are carried with a certain structure:
283 1) Each signal has a signal number. This number also is mapped to a name.
284 When executing a signal with a certain number which e.g. has the name
285 TCKEYREQ, then this signal is implemented by a method called
286 execTCKEYREQ in the receiving block. More than one block could have
287 such a method since a signal is not tied to a certain block.
288
289 2) Each signal has 4 areas that can be sent in the signal. The first is
290 always sent in the signal, this is the fixed part. The fixed part
291 consists of at least 1 and at most 25 32-bit words. Many signals have
292 a class that defines this part of the signal. This is however not
293 absolutely necessary. Then there are up to 3 sections that can carry
294 longer information bits. So e.g. a TCKEYREQ has one section that contains
295 the primary key and another part that contains the attribute information.
296 The attribute information could be seen as a program sent to MySQL
297 Cluster data nodes to read, update the row specified in the key
298 section. The attribute information could also contain interpreted
299 programs that can do things like increment, decrement, conditional
300 update and so forth.
301
302 3) As mentioned above each signal carries a certain priority level to
303 execute it on. It is currently not possible to check the prio
304 level you're currently executing on, but it would be real simple
305 to add this capability if necessary.
306
307 4) When executing a certain signal it gets a signal id, this id is
308 local to the thread and is incremented by one each new signal that
309 is executed. This signal id is available in the Signal class and
310 can e.g. be used to deduce if the thread is currently at high load.
311
312 A signal is sent over the socket using a special protocol that is called
313 Protocol6. This is not discussed more here, it is a feature of the
314 transport mechanisms of the NDB Software Architecture.
315
316 CONTINUEB
317 ---------
318 CONTINUEB is a special signal used by almost all blocks. This signal is
319 used to handle background thread activities. Often the CONTINUEB signals
320 are used as part of implementing a more complex action. One example is
321 when DBDIH starts up a new LCP. It sends various forms of CONTINUEB
322 signals to itself to move ahead through the LCP actions it needs to do
323 as part of starting up a new LCP. The first word contains the type of
324 CONTINUEB signal, so this is in a sense a bit like a second level of
325 signal number. Based on this number the CONTINUEB data is treated
326 differently.
327
328 Common patterns of signals
329 --------------------------
330 There is no absolute patterns for how signal data looks like. But it is
331 very common that a signal at least contains the destination object id,
332 the senders object id and the senders block reference. The senders block
333 reference is actually also available in the Signal class when executing
334 a signal. But we can use various forms of software routing of the
335 signal, so the senders block reference is the originator of the signal,
336 not necessarily the same as the sender of the signal since it could be
337 routed through several blocks on the way.
338
339 The basic data type in the NDB signals are unsigned 32-bit integers. So
340 all addressing is using a special form of pointers. The pointers always
341 refers to a special class of objects and the pointer is the index in an
342 array of objects of this kind. So we can have up to 4 billion objects of
343 most kinds. If one needs to send strings and 64-bit integers one follows
344 various techniques to do this. Signals are sent in the endian order of
345 the machine they were generated, so machines in a cluster has to be
346 of the same type of endian.
347
348 ROUTE_SIGNAL
349 ------------
350 ROUTE_SIGNAL is a special signal that can be used to carry a signal
351 in a special path to ensure that it arrives in the correct order to
352 the receiving block.
353
354 Signal order guarantees
355 -----------------------
356 The following signal order guarantees are maintained.
357
358 1) Sending signals at the same priority level to the same block reference
359 from one block will arrive in the order they were sent.
360
361 It is not guaranteed if the priority level is different for the signals,
362 it is also not guaranteed if they are sent through different paths.
363 Not even sending in the following pattern has a guarantee on the
364 delivery order. Signal 1: Block A -> Block B, Signal 2: Block A ->
365 Block C -> Block B. Although the signal 2 uses a longer path and is
366 destined to the same block it can still arrive before signal 1 at
367 Block B. The reason is that we execute signals from one sender at a
368 time, so we might be executing in Block C very quickly whereas the
369 thread executing Block B might be stalled and then when Block C has
370 sent its signal the thread executing Block B wakes up and decides
371 to execute signals from Block C before signals from Block A.
372
373 So as can be seen there is very little support for signal orders in the
374 NDB software architecture and so most protocols have to take into
375 account that signals can arrive in many different orders.
376
377 Fragmented signals
378 ------------------
379 It is possible to send really long signals. These signals cannot be
380 sent as one signal though. They are sent as one signal, then they will
381 be split up into multiple signals. The fixed part is the same in all
382 signals. What mainly differs is that they each contain a part of each
383 segment.
384
385 When receiving such a signal one should always call assembleFragments()
386 at first to see if the entire signal has arrived first. The signal
387 executor method is executed once for each signal fragment that is sent.
388 When all fragments have arrived then they will contain the full signal
389 with up to 3 sections that can much longer than the normal sized signals
390 that have limitations on the size of the signals.
391
392 Tracing infrastructure
393 ----------------------
394 All signals are sent through memory buffers. At crashes these memory
395 buffers can be used to print the last executed signals in each thread.
396 This will aid in looking for reasons for the crash. There will be one
397 file generated for each thread in the ndbmtd, in the case of ndbd there
398 will be only one file since there is only one file.
399
400 Jams
401 ----
402 jam() and its cousins is a set of macros used for tracing what happened
403 at the point of a crash. Each jam call executes a set of instructions
404 that inserts the line number of the jam macro into an array kept per
405 thread. There is some overhead in the jams, but it helps quite a lot in
406 debugging crashes of the NDB data nodes. At crash time we can see a few
407 thousand of the last decisions made just before the crash. This together
408 with the signal logs makes for a powerful tool to root out bugs in NDB
409 data nodes.
410
411 Trace Id
412 --------
413 Each signal also carries a signal id, this id can be used to trace certain
414 activities that go on for a longer time. This tracing can happen even in a
415 live system.
416 */
417
418 class alignas(NDB_CL) SimulatedBlock :
419 public SegmentUtils /* SimulatedBlock implements the Interface */
420 {
421 friend class TraceLCP;
422 friend class SafeCounter;
423 friend class SafeCounterManager;
424 friend class AsyncFile;
425 friend class PosixAsyncFile; // FIXME
426 friend class Win32AsyncFile;
427 friend class Pgman;
428 friend class Page_cache_client;
429 friend class Lgman;
430 friend class Logfile_client;
431 friend class Tablespace_client;
432 friend class Dbtup_client;
433 friend struct Pool_context;
434 friend struct SectionHandle;
435 friend class LockQueue;
436 friend class SimplePropertiesSectionWriter;
437 friend class SegmentedSectionGuard;
438 friend class DynArr256Pool; // for cerrorInsert
439 public:
440 friend class BlockComponent;
441 virtual ~SimulatedBlock();
442
operator new(size_t sz)443 static void * operator new (size_t sz)
444 {
445 void* ptr = NdbMem_AlignedAlloc(NDB_CL, sz);
446 require(ptr != NULL);
447 #ifdef VM_TRACE
448 #ifndef NDB_PURIFY
449 #ifdef VM_TRACE
450 const int initValue = 0xf3;
451 #else
452 const int initValue = 0x0;
453 #endif
454
455 char* charptr = (char*)ptr;
456 const int p = (sz / 4096);
457 const int r = (sz % 4096);
458
459 for(int i = 0; i<p; i++)
460 memset(charptr+(i*4096), initValue, 4096);
461
462 if(r > 0)
463 memset(charptr+p*4096, initValue, r);
464 #endif
465 #endif
466 return ptr;
467 }
operator delete(void * ptr)468 static void operator delete ( void* ptr )
469 {
470 NdbMem_AlignedFree(ptr);
471 }
472
473 static const Uint32 BOUNDED_DELAY = 0xFFFFFF00;
474 protected:
475 /**
476 * Constructor
477 */
478 SimulatedBlock(BlockNumber blockNumber,
479 struct Block_context & ctx,
480 Uint32 instanceNumber = 0);
481
482 /**********************************************************
483 * Handling of execFunctions
484 */
485 typedef void (SimulatedBlock::* ExecFunction)(Signal* signal);
486 void addRecSignalImpl(GlobalSignalNumber g, ExecFunction fun, bool f =false);
487 void installSimulatedBlockFunctions();
488 ExecFunction theExecArray[MAX_GSN+1];
489 void handle_execute_error(GlobalSignalNumber gsn);
490
491 void initCommon();
492
493 inline void executeFunction(GlobalSignalNumber gsn,
494 Signal* signal,
495 ExecFunction f);
496
497 inline void executeFunction(GlobalSignalNumber gsn,
498 Signal* signal,
499 ExecFunction f,
500 BlockReference ref,
501 Uint32 len);
502
503 public:
504 typedef void (SimulatedBlock::* CallbackFunction)(class Signal*,
505 Uint32 callbackData,
506 Uint32 returnCode);
507 struct Callback {
508 CallbackFunction m_callbackFunction;
509 Uint32 m_callbackData;
510 };
511
512 inline void executeFunction(GlobalSignalNumber gsn, Signal* signal);
513 inline void executeFunction_async(GlobalSignalNumber gsn, Signal* signal);
514
515 /* Multiple block instances */
instance() const516 Uint32 instance() const {
517 return theInstance;
518 }
519
getExecuteFunction(GlobalSignalNumber gsn)520 ExecFunction getExecuteFunction(GlobalSignalNumber gsn)
521 {
522 return theExecArray[gsn];
523 }
524
getInstance(Uint32 instanceNumber)525 SimulatedBlock* getInstance(Uint32 instanceNumber) {
526 ndbrequire(theInstance == 0); // valid only on main instance
527 if (instanceNumber == 0)
528 return this;
529 ndbrequire(instanceNumber < MaxInstances);
530 if (theInstanceList != 0)
531 return theInstanceList[instanceNumber];
532 return 0;
533 }
534 void addInstance(SimulatedBlock* b, Uint32 theInstanceNo);
loadWorkers()535 virtual void loadWorkers() {}
prepare_scan_ctx(Uint32 scanPtrI)536 virtual void prepare_scan_ctx(Uint32 scanPtrI) {}
537
538 struct ThreadContext
539 {
540 Uint32 threadId;
541 EmulatedJamBuffer* jamBuffer;
542 Uint32 * watchDogCounter;
543 SectionSegmentPool::Cache * sectionPoolCache;
544 NDB_TICKS* pHighResTimer;
545 };
546 /* Setup state of a block object for executing in a particular thread. */
547 void assignToThread(ThreadContext ctx);
548 /* For multithreaded ndbd, get the id of owning thread. */
getThreadId() const549 uint32 getThreadId() const { return m_threadId; }
550 /**
551 * To call EXECUTE_DIRECT on THRMAN we need to get its instance number.
552 * Its instance number is always 1 higher than the thread id since 0
553 * is used for the proxy instance and then there is one instance per
554 * thread.
555 */
getThrmanInstance() const556 Uint32 getThrmanInstance() const
557 {
558 if (isNdbMt())
559 {
560 return m_threadId + 1;
561 }
562 else
563 {
564 return 0;
565 }
566 }
567 static bool isMultiThreaded();
568
569 /* Configuration based alternative. Applies only to this node */
isNdbMt()570 static bool isNdbMt() { return globalData.isNdbMt; }
isNdbMtLqh()571 static bool isNdbMtLqh() { return globalData.isNdbMtLqh; }
getLqhWorkers()572 static Uint32 getLqhWorkers() { return globalData.ndbMtLqhWorkers; }
573
574 /**
575 * Assert that thread calling this function is "owner" of block instance
576 */
577 #ifdef VM_TRACE
578 void assertOwnThread();
579 #else
assertOwnThread()580 void assertOwnThread(){ }
581 #endif
582
583 /*
584 * Instance key (1-4) is used only when sending a signal. Receiver
585 * maps it to actual instance (0, if receiver is not MT LQH).
586 *
587 * For performance reason, DBTC gets instance key directly from DBDIH
588 * via DI*GET*NODES*REQ signals.
589 */
590 static Uint32 getInstanceKey(Uint32 tabId, Uint32 fragId);
591 static Uint32 getInstanceKeyCanFail(Uint32 tabId, Uint32 fragId);
592 static Uint32 getInstanceFromKey(Uint32 instanceKey); // local use only
593
594 /**
595 * This method will make sure that when callback in called each
596 * thread running an instance any of the threads in blocks[]
597 * will have executed a signal
598 */
599 void synchronize_threads(Signal * signal,
600 const BlockThreadBitmask& threads,
601 const Callback & cb,
602 JobBufferLevel req_prio,
603 JobBufferLevel conf_prio);
604
605 void synchronize_threads_for_blocks(
606 Signal*,
607 const Uint32 blocks[],
608 const Callback&,
609 JobBufferLevel req_prio = JBB,
610 JobBufferLevel conf_prio = ILLEGAL_JB_LEVEL);
611
612 /**
613 * This method will make sure that all external signals from nodes handled by
614 * transporters in current thread are processed.
615 * Should be called from a TRPMAN-worker.
616 */
617 void synchronize_external_signals(Signal* signal, const Callback& cb);
618
619 /**
620 * This method make sure that the path specified in blocks[]
621 * will be traversed before returning
622 */
623 void synchronize_path(Signal*, const Uint32 blocks[],
624 const Callback&, JobBufferLevel = JBB);
625
626 /**
627 * These methods are used to assist blocks to use the TIME_SIGNAL to
628 * generate drum beats with a regular delay. elapsed_time will report
629 * back the elapsed time since last call but will never report more
630 * than max delay. max_delay = 2 * delay here.
631 */
632 void init_elapsed_time(Signal *signal,
633 NDB_TICKS &latestTIME_SIGNAL);
634 void sendTIME_SIGNAL(Signal *signal,
635 const NDB_TICKS currentTime,
636 Uint32 delay);
637 Uint64 elapsed_time(Signal *signal,
638 const NDB_TICKS currentTime,
639 NDB_TICKS &latestTIME_SIGNAL,
640 Uint32 max_delay);
641
642 private:
643 struct SyncThreadRecord
644 {
645 BlockThreadBitmask m_threads;
646 Callback m_callback;
647 Uint32 m_cnt;
648 Uint32 m_next;
649 Uint32 nextPool;
650 };
651 typedef ArrayPool<SyncThreadRecord> SyncThreadRecord_pool;
652
653 SyncThreadRecord_pool c_syncThreadPool;
654 void execSYNC_THREAD_REQ(Signal*);
655 void execSYNC_THREAD_CONF(Signal*);
656 void sendSYNC_THREAD_REQ(Signal*, Ptr<SimulatedBlock::SyncThreadRecord>);
657
658 void execSYNC_REQ(Signal*);
659
660 void execSYNC_PATH_REQ(Signal*);
661 void execSYNC_PATH_CONF(Signal*);
662 public:
get_filename(Uint32 fd) const663 virtual const char* get_filename(Uint32 fd) const { return "";}
664
665 void EXECUTE_DIRECT_FN(ExecFunction f,
666 Signal *signal);
667
668 protected:
669 static Callback TheEmptyCallback;
670 void TheNULLCallbackFunction(class Signal*, Uint32, Uint32);
671 static Callback TheNULLCallback;
672 void execute(Signal* signal, Callback & c, Uint32 returnCode);
673
674
675 /**
676 * Various methods to get data from ndbd/ndbmtd such as time
677 * spent in sleep, sending and executing, number of signals
678 * in queue, and send buffer level.
679 *
680 * Also retrieving a thread name (this name must be pointing to a
681 * static pointer since it will be stored and kept for a long
682 * time. So the pointer cannot be changed.
683 *
684 * Finally also the ability to query for send thread information.
685 */
686 void getSendBufferLevel(NodeId node, SB_LevelType &level);
687 Uint32 getSignalsInJBB();
688 void setOverloadStatus(OverloadStatus new_status);
689 void setWakeupThread(Uint32 wakeup_instance);
690 void setNodeOverloadStatus(OverloadStatus new_status);
691 void setSendNodeOverloadStatus(OverloadStatus new_status);
692 void startChangeNeighbourNode();
693 void setNeighbourNode(NodeId node);
694 void setNoSend();
695 void endChangeNeighbourNode();
696 void getPerformanceTimers(Uint64 µs_sleep,
697 Uint64 &spin_time,
698 Uint64 &buffer_full_micros_sleep,
699 Uint64 µs_send);
700 void getSendPerformanceTimers(Uint32 send_instance,
701 Uint64 & exec_time,
702 Uint64 & sleep_time,
703 Uint64 & spin_time,
704 Uint64 & user_time_os,
705 Uint64 & kernel_time_os,
706 Uint64 & elapsed_time_os);
707 Uint32 getConfiguredSpintime();
708 void setSpintime(Uint32 new_spintime);
709 Uint32 getWakeupLatency();
710 void setWakeupLatency(Uint32);
711 Uint32 getNumSendThreads();
712 Uint32 getNumThreads();
713 const char * getThreadName();
714 const char * getThreadDescription();
715 void flush_send_buffers();
716 void set_watchdog_counter();
717 void assign_recv_thread_new_trp(Uint32 trp_id);
718 void assign_multi_trps_to_send_threads();
719 bool epoll_add_trp(NodeId node_id, TrpId trp_id);
720 bool is_recv_thread_for_new_trp(NodeId node_id, TrpId trp_id);
721
getHighResTimer() const722 NDB_TICKS getHighResTimer() const
723 {
724 return *m_pHighResTimer;
725 }
726
727 /**********************************************************
728 * Send signal - dialects
729 */
730
731 void sendSignal(BlockReference ref,
732 GlobalSignalNumber gsn,
733 Signal* signal,
734 Uint32 length,
735 JobBufferLevel jbuf ) const ;
736
737 void sendSignal(NodeReceiverGroup rg,
738 GlobalSignalNumber gsn,
739 Signal* signal,
740 Uint32 length,
741 JobBufferLevel jbuf ) const ;
742
743 void sendSignal(BlockReference ref,
744 GlobalSignalNumber gsn,
745 Signal* signal,
746 Uint32 length,
747 JobBufferLevel jbuf,
748 SectionHandle* sections) const;
749
750 void sendSignal(NodeReceiverGroup rg,
751 GlobalSignalNumber gsn,
752 Signal* signal,
753 Uint32 length,
754 JobBufferLevel jbuf,
755 SectionHandle* sections) const;
756
757 void sendSignal(BlockReference ref,
758 GlobalSignalNumber gsn,
759 Signal* signal,
760 Uint32 length,
761 JobBufferLevel jbuf,
762 LinearSectionPtr ptr[3],
763 Uint32 noOfSections) const ;
764
765 void sendSignal(NodeReceiverGroup rg,
766 GlobalSignalNumber gsn,
767 Signal* signal,
768 Uint32 length,
769 JobBufferLevel jbuf,
770 LinearSectionPtr ptr[3],
771 Uint32 noOfSections) const ;
772
773 /* NoRelease sendSignal variants do not release sections as
774 * a side-effect of sending. This requires extra
775 * copying for local sends
776 */
777 void sendSignalNoRelease(BlockReference ref,
778 GlobalSignalNumber gsn,
779 Signal* signal,
780 Uint32 length,
781 JobBufferLevel jbuf,
782 SectionHandle* sections) const;
783
784 void sendSignalNoRelease(NodeReceiverGroup rg,
785 GlobalSignalNumber gsn,
786 Signal* signal,
787 Uint32 length,
788 JobBufferLevel jbuf,
789 SectionHandle* sections) const;
790
791 // Send multiple signal with delay. In this VM the jobbufffer level has
792 // no effect on on delayed signals
793 //
794
795 void sendSignalWithDelay(BlockReference ref,
796 GlobalSignalNumber gsn,
797 Signal* signal,
798 Uint32 delayInMilliSeconds,
799 Uint32 length) const ;
800
801 void sendSignalWithDelay(BlockReference ref,
802 GlobalSignalNumber gsn,
803 Signal* signal,
804 Uint32 delayInMilliSeconds,
805 Uint32 length,
806 SectionHandle* sections) const;
807
808 /**
809 * EXECUTE_DIRECT comes in five variants.
810 *
811 * EXECUTE_DIRECT_FN/2 with explicit function, not signal number, see above.
812 *
813 * EXECUTE_DIRECT/4 calls another block within same thread.
814 *
815 * EXECUTE_DIRECT_MT/5 used when other block may be in another thread.
816 *
817 * EXECUTE_DIRECT_WITH_RETURN/4 calls another block within same thread and
818 * expects that result is passed in signal using prepareRETURN_DIRECT.
819 *
820 * EXECUTE_DIRECT_WITH_SECTIONS/5 with sections to block in same thread.
821 */
822 void EXECUTE_DIRECT(Uint32 block,
823 Uint32 gsn,
824 Signal* signal,
825 Uint32 len);
826 /*
827 * Instance defaults to instance of sender. Using explicit
828 * instance argument asserts that the call is thread-safe.
829 */
830 void EXECUTE_DIRECT_MT(Uint32 block,
831 Uint32 gsn,
832 Signal* signal,
833 Uint32 len,
834 Uint32 givenInstanceNo);
835 void EXECUTE_DIRECT_WITH_RETURN(Uint32 block,
836 Uint32 gsn,
837 Signal* signal,
838 Uint32 len);
839 void EXECUTE_DIRECT_WITH_SECTIONS(Uint32 block,
840 Uint32 gsn,
841 Signal* signal,
842 Uint32 len,
843 SectionHandle* sections);
844 /**
845 * prepareRETURN_DIRECT is used to pass a return signal
846 * direct back to caller of EXECUTE_DIRECT_WITH_RETURN.
847 *
848 * The call to prepareRETURN_DIRECT should be immediately followed by
849 * return and bring back control to caller of EXECUTE_DIRECT_WITH_RETURN.
850 */
851 void prepareRETURN_DIRECT(Uint32 gsn,
852 Signal* signal,
853 Uint32 len);
854
855 class SectionSegmentPool& getSectionSegmentPool();
856 void release(SegmentedSectionPtr & ptr);
release(SegmentedSectionPtrPOD & ptr)857 void release(SegmentedSectionPtrPOD & ptr) {
858 SegmentedSectionPtr tmp(ptr);
859 release(tmp);
860 ptr.setNull();
861 }
862 void releaseSection(Uint32 firstSegmentIVal);
863 void releaseSections(struct SectionHandle&);
864
865 bool import(Ptr<SectionSegment> & first, const Uint32 * src, Uint32 len);
866 bool import(SegmentedSectionPtr& ptr, const Uint32* src, Uint32 len) const;
867 bool import(SectionHandle * dst, LinearSectionPtr src[3],Uint32 cnt);
868
869 bool appendToSection(Uint32& firstSegmentIVal, const Uint32* src, Uint32 len);
870 bool dupSection(Uint32& copyFirstIVal, Uint32 srcFirstIVal);
871 bool writeToSection(Uint32 firstSegmentIVal, Uint32 offset, const Uint32* src, Uint32 len);
872
873 void handle_invalid_sections_in_send_signal(const Signal*) const;
874 void handle_lingering_sections_after_execute(const Signal*) const;
875 void handle_invalid_fragmentInfo(Signal*) const;
876 template<typename SecPtr>
877 void handle_send_failed(SendStatus, Signal*, Uint32, SecPtr[]) const;
878 void handle_out_of_longsignal_memory(Signal*) const;
879
880 /**
881 * Send routed signals (ONLY LOCALLY)
882 *
883 * NOTE: Only localhost is allowed!
884 */
885 struct RoutePath
886 {
887 Uint32 ref;
888 JobBufferLevel prio;
889 };
890 void sendRoutedSignal(RoutePath path[],
891 Uint32 pathcnt, // #hops
892 Uint32 dst[], // Final destination(s)
893 Uint32 dstcnt, // #final destination(s)
894 Uint32 gsn, // Final GSN
895 Signal*,
896 Uint32 len,
897 JobBufferLevel prio, // Final prio
898 SectionHandle * handle = 0);
899
900
901 /**
902 * Check that signal sent from remote node
903 * is guaranteed to be correctly serialized wrt to NODE_FAILREP
904 */
905 bool checkNodeFailSequence(Signal*);
906
907 #ifdef ERROR_INSERT
908 void setDelayedPrepare();
909 #endif
910
911 /**********************************************************
912 * Fragmented signals
913 */
914
915 /**
916 * Assemble fragments
917 *
918 * @return true if all fragments has arrived
919 * false otherwise
920 */
921 bool assembleFragments(Signal * signal);
922
923 /**
924 * Assemble dropped fragments
925 *
926 * Should be called at the start of a Dropped Signal Report
927 * (GSN_DROPPED_SIGNAL_REP) handler when it is expected that
928 * the block could receive fragmented signals.
929 * No dropped signal handling should be done until this method
930 * returns true.
931 *
932 * @return true if all fragments has arrived and dropped signal
933 * handling can proceed.
934 * false otherwise
935 */
936 bool assembleDroppedFragments(Signal * signal);
937
938 /* If send size is > FRAGMENT_WORD_SIZE, fragments of this size
939 * will be sent by the sendFragmentedSignal variants
940 */
941 static constexpr Uint32 FRAGMENT_WORD_SIZE = 240;
942 static constexpr Uint32 BATCH_FRAGMENT_WORD_SIZE = 240 * 8;
943
944 void sendFragmentedSignal(BlockReference ref,
945 GlobalSignalNumber gsn,
946 Signal* signal,
947 Uint32 length,
948 JobBufferLevel jbuf,
949 SectionHandle * sections,
950 Callback & = TheEmptyCallback,
951 Uint32 messageSize = FRAGMENT_WORD_SIZE);
952
953 void sendFragmentedSignal(NodeReceiverGroup rg,
954 GlobalSignalNumber gsn,
955 Signal* signal,
956 Uint32 length,
957 JobBufferLevel jbuf,
958 SectionHandle * sections,
959 Callback & = TheEmptyCallback,
960 Uint32 messageSize = FRAGMENT_WORD_SIZE);
961
962 void sendFragmentedSignal(BlockReference ref,
963 GlobalSignalNumber gsn,
964 Signal* signal,
965 Uint32 length,
966 JobBufferLevel jbuf,
967 LinearSectionPtr ptr[3],
968 Uint32 noOfSections,
969 Callback & = TheEmptyCallback,
970 Uint32 messageSize = FRAGMENT_WORD_SIZE);
971
972 void sendFragmentedSignal(NodeReceiverGroup rg,
973 GlobalSignalNumber gsn,
974 Signal* signal,
975 Uint32 length,
976 JobBufferLevel jbuf,
977 LinearSectionPtr ptr[3],
978 Uint32 noOfSections,
979 Callback & = TheEmptyCallback,
980 Uint32 messageSize = FRAGMENT_WORD_SIZE);
981
982 void sendBatchedFragmentedSignal(BlockReference ref,
983 GlobalSignalNumber gsn,
984 Signal* signal,
985 Uint32 length,
986 JobBufferLevel jbuf,
987 SectionHandle * sections,
988 bool noRelease,
989 Callback & = TheEmptyCallback,
990 Uint32 messageSize = BATCH_FRAGMENT_WORD_SIZE);
991
992 void sendBatchedFragmentedSignal(NodeReceiverGroup rg,
993 GlobalSignalNumber gsn,
994 Signal* signal,
995 Uint32 length,
996 JobBufferLevel jbuf,
997 SectionHandle * sections,
998 bool noRelease,
999 Callback & = TheEmptyCallback,
1000 Uint32 messageSize = BATCH_FRAGMENT_WORD_SIZE);
1001
1002 void sendBatchedFragmentedSignal(BlockReference ref,
1003 GlobalSignalNumber gsn,
1004 Signal* signal,
1005 Uint32 length,
1006 JobBufferLevel jbuf,
1007 LinearSectionPtr ptr[3],
1008 Uint32 noOfSections,
1009 Callback & = TheEmptyCallback,
1010 Uint32 messageSize = BATCH_FRAGMENT_WORD_SIZE);
1011
1012 void sendBatchedFragmentedSignal(NodeReceiverGroup rg,
1013 GlobalSignalNumber gsn,
1014 Signal* signal,
1015 Uint32 length,
1016 JobBufferLevel jbuf,
1017 LinearSectionPtr ptr[3],
1018 Uint32 noOfSections,
1019 Callback & = TheEmptyCallback,
1020 Uint32 messageSize = BATCH_FRAGMENT_WORD_SIZE);
1021
1022 /**
1023 * simBlockNodeFailure
1024 *
1025 * Method must be called by blocks that send or receive
1026 * remote Fragmented Signals when they detect a node
1027 * (NDBD or API) failure.
1028 * If the block needs to acknowledge or perform further
1029 * processing after completing block-level node failure
1030 * handling, it can supply a Callback which will be invoked
1031 * when block-level node failure handling has completed.
1032 * Otherwise TheEmptyCallback is used.
1033 * If TheEmptyCallback is used, all failure handling is
1034 * performed in the current timeslice, to avoid any
1035 * races.
1036 *
1037 * Parameters
1038 * signal : Current signal*
1039 * failedNodeId : Node id of failed node
1040 * cb : Callback to be executed when block-level
1041 * node failure handling completed.
1042 * TheEmptyCallback is passed if no further
1043 * processing is required.
1044 * Returns
1045 * Number of 'resources' cleaned up in call.
1046 * Callback return code is total resources cleaned up.
1047 *
1048 */
1049 Uint32 simBlockNodeFailure(Signal* signal,
1050 Uint32 failedNodeId,
1051 Callback& cb = TheEmptyCallback);
1052
1053 /**********************************************************
1054 * Fragmented signals structures
1055 */
1056
1057 /**
1058 * Struct used when assembling fragmented long signals at receiver side
1059 */
1060 struct FragmentInfo {
1061 FragmentInfo(Uint32 fragId, Uint32 sender);
1062
1063 Uint32 m_senderRef;
1064 Uint32 m_fragmentId;
1065 Uint32 m_sectionPtrI[3];
1066 union {
1067 Uint32 nextPool;
1068 Uint32 nextHash;
1069 };
1070 Uint32 prevHash;
1071
equalSimulatedBlock::FragmentInfo1072 inline bool equal(FragmentInfo const & p) const {
1073 return m_senderRef == p.m_senderRef && m_fragmentId == p.m_fragmentId;
1074 }
1075
hashValueSimulatedBlock::FragmentInfo1076 inline Uint32 hashValue() const {
1077 return m_senderRef + m_fragmentId ;
1078 }
1079
isDroppedSimulatedBlock::FragmentInfo1080 inline bool isDropped() const {
1081 /* IsDropped when entry in hash, but no segments stored */
1082 return (( m_sectionPtrI[0] == RNIL ) &&
1083 ( m_sectionPtrI[1] == RNIL ) &&
1084 ( m_sectionPtrI[2] == RNIL ) );
1085 }
1086 }; // sizeof() = 32 bytes
1087 typedef ArrayPool<FragmentInfo> FragmentInfo_pool;
1088 typedef DLHashTable<FragmentInfo_pool, FragmentInfo> FragmentInfo_hash;
1089
1090 /**
1091 * Struct used when sending fragmented signals
1092 */
1093 struct FragmentSendInfo {
1094 FragmentSendInfo();
1095
1096 enum Status {
1097 SendNotComplete = 0,
1098 SendComplete = 1,
1099 SendCancelled = 2
1100 };
1101 Uint8 m_status;
1102 Uint8 m_prio;
1103 Uint8 m_fragInfo;
1104 enum Flags {
1105 SendNoReleaseSeg = 0x1
1106 };
1107 Uint8 m_flags;
1108 Uint16 m_gsn;
1109 Uint16 m_messageSize; // Size of each fragment
1110 Uint32 m_fragmentId;
1111 union {
1112 // Similar to Ptr<SectionSegment> but a POD, as needed in a union.
1113 struct {
1114 SectionSegment* p;
1115 Uint32 i;
1116 } m_segmented;
1117 LinearSectionPtr m_linear;
1118 } m_sectionPtr[3];
1119 LinearSectionPtr m_theDataSection;
1120 NodeReceiverGroup m_nodeReceiverGroup; // 3
1121 Callback m_callback;
1122 union {
1123 Uint32 nextPool;
1124 Uint32 nextList;
1125 };
1126 Uint32 prevList;
1127 };
1128 typedef ArrayPool<FragmentSendInfo> FragmentSendInfo_pool;
1129 typedef DLList<FragmentSendInfo_pool> FragmentSendInfo_list;
1130
1131 /**
1132 * sendFirstFragment
1133 * Used by sendFragmentedSignal
1134 * noRelease can only be used if the caller can guarantee
1135 * not to free the supplied sections until all fragments
1136 * have been sent.
1137 */
1138 bool sendFirstFragment(FragmentSendInfo & info,
1139 NodeReceiverGroup rg,
1140 GlobalSignalNumber gsn,
1141 Signal* signal,
1142 Uint32 length,
1143 JobBufferLevel jbuf,
1144 SectionHandle * sections,
1145 bool noRelease,
1146 Uint32 messageSize = FRAGMENT_WORD_SIZE);
1147
1148 bool sendFirstFragment(FragmentSendInfo & info,
1149 NodeReceiverGroup rg,
1150 GlobalSignalNumber gsn,
1151 Signal* signal,
1152 Uint32 length,
1153 JobBufferLevel jbuf,
1154 LinearSectionPtr ptr[3],
1155 Uint32 noOfSections,
1156 Uint32 messageSize = FRAGMENT_WORD_SIZE);
1157
1158 /**
1159 * Send signal fragment
1160 *
1161 * @see sendFragmentedSignal
1162 */
1163 void sendNextSegmentedFragment(Signal* signal, FragmentSendInfo & info);
1164
1165 /**
1166 * Send signal fragment
1167 *
1168 * @see sendFragmentedSignal
1169 */
1170 void sendNextLinearFragment(Signal* signal, FragmentSendInfo & info);
1171
1172 BlockNumber number() const;
1173 public:
1174 /* Must be public so that we can jam() outside of block scope. */
1175 EmulatedJamBuffer *jamBuffer() const;
1176 protected:
1177 BlockReference reference() const;
1178 NodeId getOwnNodeId() const;
1179
1180 /**
1181 * Refresh Watch Dog in initialising code
1182 *
1183 */
1184 void refresh_watch_dog(Uint32 place = 1);
1185 volatile Uint32* get_watch_dog();
1186 void update_watch_dog_timer(Uint32 interval);
1187
1188 /**
1189 * Prog error
1190 * This function should be called when this node should be shutdown
1191 * If the cause of the shutdown is known use extradata to add an
1192 * errormessage describing the problem
1193 */
1194 [[noreturn]] void progError(int line,
1195 int err_code,
1196 const char* extradata=NULL,
1197 const char* check="") const;
1198 private:
1199 [[noreturn]] void signal_error(Uint32,
1200 Uint32,
1201 Uint32,
1202 const char*,
1203 int) const;
1204 const NodeId theNodeId;
1205 const BlockNumber theNumber;
1206 const Uint32 theInstance;
1207 const BlockReference theReference;
1208 /*
1209 * Instance 0 is the main instance. It creates/owns other instances.
1210 * In MT LQH main instance is the LQH proxy and the others ("workers")
1211 * are real LQHs run by multiple threads.
1212 */
1213 protected:
1214 enum { MaxInstances = NDBMT_MAX_BLOCK_INSTANCES };
1215 private:
1216 SimulatedBlock** theInstanceList; // set in main, indexed by instance
1217 SimulatedBlock* theMainInstance; // set in all
1218 /*
1219 Thread id currently executing this block.
1220 Not used in singlethreaded ndbd.
1221 */
1222 Uint32 m_threadId;
1223 /*
1224 Jam buffer reference.
1225 In multithreaded ndbd, this is different in each thread, and must be
1226 updated if migrating the block to another thread.
1227 */
1228 EmulatedJamBuffer *m_jamBuffer;
1229 /* For multithreaded ndb, the thread-specific watchdog counter. */
1230 Uint32 *m_watchDogCounter;
1231
1232 /* Read-only high res timer pointer */
1233 const NDB_TICKS* m_pHighResTimer;
1234
1235 SectionSegmentPool::Cache * m_sectionPoolCache;
1236
1237
1238 Uint32 doNodeFailureCleanup(Signal* signal,
1239 Uint32 failedNodeId,
1240 Uint32 resource,
1241 Uint32 cursor,
1242 Uint32 elementsCleaned,
1243 Callback& cb);
1244
1245 bool doCleanupFragInfo(Uint32 failedNodeId,
1246 Uint32& cursor,
1247 Uint32& rtUnitsUsed,
1248 Uint32& elementsCleaned);
1249
1250 bool doCleanupFragSend(Uint32 failedNodeId,
1251 Uint32& cursor,
1252 Uint32& rtUnitsUsed,
1253 Uint32& elementsCleaned);
1254
1255 protected:
1256 Block_context m_ctx;
1257 NewVARIABLE* allocateBat(int batSize);
1258 void freeBat();
1259 static const NewVARIABLE* getBat (BlockNumber blockNo,
1260 Uint32 instanceNo);
1261 static Uint16 getBatSize(BlockNumber blockNo,
1262 Uint32 instanceNo);
1263
1264 static BlockReference calcTcBlockRef (NodeId aNode);
1265 static BlockReference calcLqhBlockRef (NodeId aNode);
1266 static BlockReference calcAccBlockRef (NodeId aNode);
1267 static BlockReference calcTupBlockRef (NodeId aNode);
1268 static BlockReference calcTuxBlockRef (NodeId aNode);
1269 static BlockReference calcDihBlockRef (NodeId aNode);
1270 static BlockReference calcQmgrBlockRef (NodeId aNode);
1271 static BlockReference calcDictBlockRef (NodeId aNode);
1272 static BlockReference calcNdbCntrBlockRef (NodeId aNode);
1273 static BlockReference calcTrixBlockRef (NodeId aNode);
1274 static BlockReference calcBackupBlockRef (NodeId aNode);
1275 static BlockReference calcSumaBlockRef (NodeId aNode);
1276
1277 static BlockReference calcApiClusterMgrBlockRef (NodeId aNode);
1278
1279 // matching instance on same node e.g. LQH-ACC-TUP
1280 BlockReference calcInstanceBlockRef(BlockNumber aBlock);
1281
1282 // matching instance on another node e.g. LQH-LQH
1283 // valid only if receiver has same number of workers
1284 BlockReference calcInstanceBlockRef(BlockNumber aBlock, NodeId aNode);
1285
1286 /**
1287 * allocRecord
1288 * Allocates memory for the datastructures where ndb keeps the data
1289 *
1290 */
1291 void* allocRecord(const char * type, size_t s, size_t n, bool clear = true, Uint32 paramId = 0);
1292 void* allocRecordAligned(const char * type, size_t s, size_t n, void **unaligned_buffer, Uint32 align = NDB_O_DIRECT_WRITE_ALIGNMENT, bool clear = true, Uint32 paramId = 0);
1293
1294 /**
1295 * Deallocate record
1296 *
1297 * NOTE: Also resets pointer
1298 */
1299 void deallocRecord(void **, const char * type, size_t s, size_t n);
1300
1301 /**
1302 * Allocate memory from global pool,
1303 * returns #chunks used
1304 *
1305 * Typically used by part of code, not converted to use global pool
1306 * directly, but allocates everything during startup
1307 */
1308 struct AllocChunk
1309 {
1310 Uint32 ptrI;
1311 Uint32 cnt;
1312 };
1313 Uint32 allocChunks(AllocChunk dst[], Uint32 /* size of dst */ arraysize,
1314 Uint32 /* resource group */ rg,
1315 Uint32 /* no of pages to allocate */ pages,
1316 Uint32 paramId /* for error message if failing */);
1317
1318 static int sortchunks(const void*, const void*);
1319
1320 /**
1321 * General info event (sent to cluster log)
1322 */
1323 void infoEvent(const char * msg, ...) const
1324 ATTRIBUTE_FORMAT(printf, 2, 3);
1325 void warningEvent(const char * msg, ...)
1326 ATTRIBUTE_FORMAT(printf, 2, 3);
1327
1328 /**
1329 * Get node state
1330 */
1331 const NodeState & getNodeState() const;
1332
1333 /**
1334 * Get node info
1335 */
1336 const NodeInfo & getNodeInfo(NodeId nodeId) const;
1337 NodeInfo & setNodeInfo(NodeId);
1338
1339 const NodeVersionInfo& getNodeVersionInfo() const;
1340 NodeVersionInfo& setNodeVersionInfo();
1341
1342 Uint32 change_and_get_io_laggers(int change);
1343 /**********************
1344 * Xfrm stuff
1345 *
1346 * xfrm the attr / key for **hash** generation.
1347 * - Keys being equal should generate identical xfrm'ed strings.
1348 * - Uniquenes of two non equal keys are preferred, but not required.
1349 */
1350
1351 /**
1352 * @return length
1353 */
1354 Uint32 xfrm_key_hash(Uint32 tab, const Uint32* src,
1355 Uint32 *dst, Uint32 dstSize,
1356 Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX]) const;
1357
1358 Uint32 xfrm_attr_hash(Uint32 attrDesc, const CHARSET_INFO* cs,
1359 const Uint32* src, Uint32 & srcPos,
1360 Uint32* dst, Uint32 & dstPos, Uint32 dstSize) const;
1361
1362
1363 /*******************
1364 * Compare either a full (non-NULL) key, or a single attr.
1365 *
1366 * Character strings are compared taking their normalized
1367 * 'weight' into considderation, as defined by their collation.
1368 *
1369 * No intermediate xfrm'ed string are produced during the compare.
1370 *
1371 * return '<0', '==0' or '>0' for 's1<s2', s1==s2, 's2>s2' resp.
1372 */
1373 int cmp_key(Uint32 tab, const Uint32* s1, const Uint32 *s2) const;
1374
1375 int cmp_attr(Uint32 attrDesc, const CHARSET_INFO* cs,
1376 const Uint32 *s1, Uint32 s1Len,
1377 const Uint32 *s2, Uint32 s2Len) const;
1378
1379 /**
1380 *
1381 */
1382 Uint32 create_distr_key(Uint32 tableId,
1383 const Uint32* src,
1384 Uint32 *dst,
1385 const Uint32 keyPaLen[MAX_ATTRIBUTES_IN_INDEX])const;
1386
1387 /**
1388 * if ndbd,
1389 * wakeup main-loop if sleeping on IO
1390 * if ndbmtd
1391 * wakeup thread running block-instance
1392 */
1393 void wakeup();
1394
1395 /**
1396 * setup struct for wakeup
1397 */
1398 void setup_wakeup();
1399
1400 /**
1401 * Get receiver thread index for node
1402 * MAX_NODES == no receiver thread
1403 */
1404 Uint32 get_recv_thread_idx(TrpId trp_id);
1405
1406 private:
1407 NewVARIABLE* NewVarRef; /* New Base Address Table for block */
1408 Uint16 theBATSize; /* # entries in BAT */
1409
1410 protected:
1411 GlobalPage_safepool& m_global_page_pool;
1412 GlobalPage_pool& m_shared_page_pool;
1413
1414 void execNDB_TAMPER(Signal * signal);
1415 void execNODE_STATE_REP(Signal* signal);
1416 void execCHANGE_NODE_STATE_REQ(Signal* signal);
1417
1418 void execSIGNAL_DROPPED_REP(Signal* signal);
1419 void execCONTINUE_FRAGMENTED(Signal* signal);
1420 void execSTOP_FOR_CRASH(Signal* signal);
1421 void execAPI_START_REP(Signal* signal);
1422 void execNODE_START_REP(Signal* signal);
1423 void execLOCAL_ROUTE_ORD(Signal*);
1424 public:
1425 void execSEND_PACKED(Signal* signal);
1426 private:
1427 /**
1428 * Node state
1429 */
1430 NodeState theNodeState;
1431
1432 Uint32 c_fragmentIdCounter;
1433 FragmentInfo_pool c_fragmentInfoPool;
1434 FragmentInfo_hash c_fragmentInfoHash;
1435
1436 bool c_fragSenderRunning;
1437 FragmentSendInfo_pool c_fragmentSendPool;
1438 FragmentSendInfo_list c_linearFragmentSendList;
1439 FragmentSendInfo_list c_segmentedFragmentSendList;
1440
1441 protected:
1442 Uint32 debugPrintFragmentCounts();
1443
1444 public:
1445 class MutexManager {
1446 friend class Mutex;
1447 friend class SimulatedBlock;
1448 friend class DbUtil;
1449 public:
1450 MutexManager(class SimulatedBlock &);
1451
1452 bool setSize(Uint32 maxNoOfActiveMutexes);
1453 Uint32 getSize() const ; // Get maxNoOfActiveMutexes
1454
1455 private:
1456 /**
1457 * core interface
1458 */
1459 struct ActiveMutex {
ActiveMutexSimulatedBlock::MutexManager::ActiveMutex1460 ActiveMutex() {}
1461 Uint32 m_gsn; // state
1462 Uint32 m_mutexId;
1463 Callback m_callback;
1464 union {
1465 Uint32 nextPool;
1466 Uint32 nextList;
1467 };
1468 Uint32 prevList;
1469 };
1470 typedef Ptr<ActiveMutex> ActiveMutexPtr;
1471 typedef ArrayPool<ActiveMutex> ActiveMutex_pool;
1472 typedef DLList<ActiveMutex_pool> ActiveMutex_list;
1473
1474 bool seize(ActiveMutexPtr& ptr);
1475 void release(Uint32 activeMutexPtrI);
1476
1477 void getPtr(ActiveMutexPtr& ptr) const;
1478
1479 void create(Signal*, ActiveMutexPtr&);
1480 void destroy(Signal*, ActiveMutexPtr&);
1481 void lock(Signal*, ActiveMutexPtr&, Uint32 flags);
1482 void unlock(Signal*, ActiveMutexPtr&);
1483
1484 private:
1485 void execUTIL_CREATE_LOCK_REF(Signal* signal);
1486 void execUTIL_CREATE_LOCK_CONF(Signal* signal);
1487 void execUTIL_DESTORY_LOCK_REF(Signal* signal);
1488 void execUTIL_DESTORY_LOCK_CONF(Signal* signal);
1489 void execUTIL_LOCK_REF(Signal* signal);
1490 void execUTIL_LOCK_CONF(Signal* signal);
1491 void execUTIL_UNLOCK_REF(Signal* signal);
1492 void execUTIL_UNLOCK_CONF(Signal* signal);
1493
1494 SimulatedBlock & m_block;
1495 ActiveMutex_pool m_mutexPool;
1496 ActiveMutex_list m_activeMutexes;
1497
1498 BlockReference reference() const;
1499 [[noreturn]] void progError(int line,
1500 int err_code,
1501 const char* extra = 0,
1502 const char* check = "");
1503 };
1504
1505 friend class MutexManager;
1506 MutexManager c_mutexMgr;
1507
1508 void ignoreMutexUnlockCallback(Signal* signal, Uint32 ptrI, Uint32 retVal);
getParam(const char * param,Uint32 * retVal)1509 virtual bool getParam(const char * param, Uint32 * retVal) { return false;}
1510
1511 SafeCounterManager c_counterMgr;
1512 private:
1513 void execUTIL_CREATE_LOCK_REF(Signal* signal);
1514 void execUTIL_CREATE_LOCK_CONF(Signal* signal);
1515 void execUTIL_DESTORY_LOCK_REF(Signal* signal);
1516 void execUTIL_DESTORY_LOCK_CONF(Signal* signal);
1517 void execUTIL_LOCK_REF(Signal* signal);
1518 void execUTIL_LOCK_CONF(Signal* signal);
1519 void execUTIL_UNLOCK_REF(Signal* signal);
1520 void execUTIL_UNLOCK_CONF(Signal* signal);
1521
1522 void check_sections(Signal* signal,
1523 Uint32 oldSecCount,
1524 Uint32 newSecCount) const;
1525 protected:
1526
1527 void fsRefError(Signal* signal, Uint32 line, const char *msg);
1528 void execFSWRITEREF(Signal* signal);
1529 void execFSREADREF(Signal* signal);
1530 void execFSOPENREF(Signal* signal);
1531 void execFSCLOSEREF(Signal* signal);
1532 void execFSREMOVEREF(Signal* signal);
1533 void execFSSYNCREF(Signal* signal);
1534 void execFSAPPENDREF(Signal* signal);
1535
1536 // MT LQH callback CONF via signal
1537 public:
1538 struct CallbackPtr {
1539 Uint32 m_callbackIndex;
1540 Uint32 m_callbackData;
1541 };
1542 protected:
1543 enum CallbackFlags {
1544 CALLBACK_DIRECT = 0x0001, // use EXECUTE_DIRECT (assumed thread safe)
1545 CALLBACK_ACK = 0x0002 // send ack at the end of callback timeslice
1546 };
1547
1548 struct CallbackEntry {
1549 CallbackFunction m_function;
1550 Uint32 m_flags;
1551 };
1552
1553 struct CallbackTable {
1554 Uint32 m_count;
1555 CallbackEntry* m_entry; // array
1556 };
1557
1558 CallbackTable* m_callbackTableAddr; // set by block if used
1559
1560 enum {
1561 THE_NULL_CALLBACK = 0 // must assign TheNULLCallbackFunction
1562 };
1563
1564 void block_require(void);
1565 void execute(Signal* signal, CallbackPtr & cptr, Uint32 returnCode);
1566 const CallbackEntry& getCallbackEntry(Uint32 ci);
1567 void sendCallbackConf(Signal* signal, Uint32 fullBlockNo,
1568 CallbackPtr& cptr,
1569 Uint32 senderData, Uint32 callbackInfo,
1570 Uint32 returnCode);
1571 void execCALLBACK_CONF(Signal* signal);
1572
1573 // Variable for storing inserted errors, see pc.H
1574 ERROR_INSERT_VARIABLE;
1575
1576 #ifdef VM_TRACE_TIME
1577 public:
1578 void clearTimes();
1579 void printTimes(FILE * output);
1580 void addTime(Uint32 gsn, Uint64 time);
1581 void subTime(Uint32 gsn, Uint64 time);
1582 struct TimeTrace {
1583 Uint32 cnt;
1584 Uint64 sum, sub;
1585 } m_timeTrace[MAX_GSN+1];
1586 Uint32 m_currentGsn;
1587 #endif
1588
1589 #if defined (USE_INIT_GLOBAL_VARIABLES)
1590 void init_global_ptrs(void ** tmp, size_t cnt);
1591 void init_global_uint32_ptrs(void ** tmp, size_t cnt);
1592 void init_global_uint32(void ** tmp, size_t cnt);
1593 void disable_global_variables();
1594 void enable_global_variables();
1595 #endif
1596
1597 #ifdef VM_TRACE
1598 public:
1599 FileOutputStream debugOutFile;
1600 NdbOut debugOut;
debugOutStream()1601 NdbOut& debugOutStream() { return debugOut; }
1602 bool debugOutOn();
debugOutLock()1603 void debugOutLock() { globalSignalLoggers.lock(); }
debugOutUnlock()1604 void debugOutUnlock() { globalSignalLoggers.unlock(); }
1605 const char* debugOutTag(char* buf, int line);
1606 #endif
1607
getPartitionBalanceString(Uint32 fct)1608 const char* getPartitionBalanceString(Uint32 fct)
1609 {
1610 switch (fct)
1611 {
1612 case NDB_PARTITION_BALANCE_SPECIFIC:
1613 return "NDB_PARTITION_BALANCE_SPECIFIC";
1614 case NDB_PARTITION_BALANCE_FOR_RA_BY_NODE:
1615 return "NDB_PARTITION_BALANCE_FOR_RA_BY_NODE";
1616 case NDB_PARTITION_BALANCE_FOR_RP_BY_NODE:
1617 return "NDB_PARTITION_BALANCE_FOR_RP_BY_NODE";
1618 case NDB_PARTITION_BALANCE_FOR_RP_BY_LDM:
1619 return "NDB_PARTITION_BALANCE_FOR_RP_BY_LDM";
1620 case NDB_PARTITION_BALANCE_FOR_RA_BY_LDM:
1621 return "NDB_PARTITION_BALANCE_FOR_RA_BY_LDM";
1622 case NDB_PARTITION_BALANCE_FOR_RA_BY_LDM_X_2:
1623 return "NDB_PARTITION_BALANCE_FOR_RA_BY_LDM_X_2";
1624 case NDB_PARTITION_BALANCE_FOR_RA_BY_LDM_X_3:
1625 return "NDB_PARTITION_BALANCE_FOR_RA_BY_LDM_X_3";
1626 case NDB_PARTITION_BALANCE_FOR_RA_BY_LDM_X_4:
1627 return "NDB_PARTITION_BALANCE_FOR_RA_BY_LDM_X_4";
1628 default:
1629 ndbabort();
1630 }
1631 return NULL;
1632 }
1633
1634 void ndbinfo_send_row(Signal* signal,
1635 const DbinfoScanReq& req,
1636 const Ndbinfo::Row& row,
1637 Ndbinfo::Ratelimit& rl) const;
1638
1639 void ndbinfo_send_scan_break(Signal* signal,
1640 DbinfoScanReq& req,
1641 const Ndbinfo::Ratelimit& rl,
1642 Uint32 data1, Uint32 data2 = 0,
1643 Uint32 data3 = 0, Uint32 data4 = 0) const;
1644
1645 void ndbinfo_send_scan_conf(Signal* signal,
1646 DbinfoScanReq& req,
1647 const Ndbinfo::Ratelimit& rl) const;
1648
1649 #ifdef NDB_DEBUG_RES_OWNERSHIP
1650 /* Utils to lock and unlock the global section segment pool */
1651 void lock_global_ssp();
1652 void unlock_global_ssp();
1653 #endif
1654
1655
1656 protected:
1657 /**
1658 * SegmentUtils methods
1659 */
1660 virtual SectionSegment* getSegmentPtr(Uint32 iVal);
1661 virtual bool seizeSegment(Ptr<SectionSegment>& p);
1662 virtual void releaseSegment(Uint32 iVal);
1663
1664 virtual void releaseSegmentList(Uint32 firstSegmentIVal);
1665
1666 /** End of SegmentUtils methods */
1667 };
1668
1669 // outside blocks e.g. within a struct
1670 #ifdef VM_TRACE
1671 #define DEBUG_OUT_DEFINES(blockNo) \
1672 static SimulatedBlock* debugOutBlock() \
1673 { return globalData.getBlock(blockNo); } \
1674 static NdbOut& debugOutStream() \
1675 { return debugOutBlock()->debugOutStream(); } \
1676 static bool debugOutOn() \
1677 { return debugOutBlock()->debugOutOn(); } \
1678 static void debugOutLock() \
1679 { debugOutBlock()->debugOutLock(); } \
1680 static void debugOutUnlock() \
1681 { debugOutBlock()->debugOutUnlock(); } \
1682 static const char* debugOutTag(char* buf, int line) \
1683 { return debugOutBlock()->debugOutTag(buf, line); } \
1684 static void debugOutDefines()
1685 #else
1686 #define DEBUG_OUT_DEFINES(blockNo) \
1687 static void debugOutDefines()
1688 #endif
1689
1690 inline
1691 void
executeFunction(GlobalSignalNumber gsn,Signal * signal)1692 SimulatedBlock::executeFunction(GlobalSignalNumber gsn,
1693 Signal *signal)
1694 {
1695 ExecFunction f = theExecArray[gsn];
1696 if (unlikely(gsn > MAX_GSN))
1697 {
1698 handle_execute_error(gsn);
1699 return;
1700 }
1701 executeFunction(gsn, signal, f);
1702 }
1703
1704 inline
1705 void
executeFunction_async(GlobalSignalNumber gsn,Signal * signal)1706 SimulatedBlock::executeFunction_async(GlobalSignalNumber gsn,
1707 Signal *signal)
1708 {
1709 ExecFunction f = theExecArray[gsn];
1710 if (unlikely(gsn > MAX_GSN))
1711 {
1712 handle_execute_error(gsn);
1713 return;
1714 }
1715 executeFunction(gsn, signal, f);
1716 }
1717
1718 inline
1719 void
executeFunction(GlobalSignalNumber gsn,Signal * signal,ExecFunction f,BlockReference ref,Uint32 len)1720 SimulatedBlock::executeFunction(GlobalSignalNumber gsn,
1721 Signal* signal,
1722 ExecFunction f,
1723 BlockReference ref,
1724 Uint32 len)
1725 {
1726 if (unlikely(gsn > MAX_GSN))
1727 {
1728 handle_execute_error(gsn);
1729 return;
1730 }
1731 signal->setLength(len);
1732 signal->header.theSendersBlockRef = ref;
1733 executeFunction(gsn, signal, f);
1734 }
1735
1736 inline
1737 void
executeFunction(GlobalSignalNumber gsn,Signal * signal,ExecFunction f)1738 SimulatedBlock::executeFunction(GlobalSignalNumber gsn,
1739 Signal* signal,
1740 ExecFunction f)
1741 {
1742 #ifdef NDB_DEBUG_RES_OWNERSHIP
1743 /* Use block num + gsn composite as owner id by default */
1744 setResOwner((Uint32(refToBlock(reference())) << 16) | gsn);
1745 #endif
1746 if (likely(f != 0))
1747 {
1748 (this->*f)(signal);
1749
1750 if (unlikely(signal->header.m_noOfSections))
1751 {
1752 handle_lingering_sections_after_execute(signal);
1753 }
1754 return;
1755 }
1756 /**
1757 * This point only passed if an error has occurred
1758 */
1759 handle_execute_error(gsn);
1760 }
1761
1762 inline
block_require(void)1763 void SimulatedBlock::block_require(void)
1764 {
1765 ndbabort();
1766 }
1767
1768 inline
1769 void
execute(Signal * signal,Callback & c,Uint32 returnCode)1770 SimulatedBlock::execute(Signal* signal, Callback & c, Uint32 returnCode){
1771 CallbackFunction fun = c.m_callbackFunction;
1772 if (fun == TheNULLCallback.m_callbackFunction)
1773 return;
1774 ndbrequire(fun != 0);
1775 c.m_callbackFunction = NULL;
1776 (this->*fun)(signal, c.m_callbackData, returnCode);
1777 }
1778
1779 inline
1780 void
execute(Signal * signal,CallbackPtr & cptr,Uint32 returnCode)1781 SimulatedBlock::execute(Signal* signal, CallbackPtr & cptr, Uint32 returnCode){
1782 const CallbackEntry& ce = getCallbackEntry(cptr.m_callbackIndex);
1783 cptr.m_callbackIndex = ZNIL;
1784 Callback c;
1785 c.m_callbackFunction = ce.m_function;
1786 c.m_callbackData = cptr.m_callbackData;
1787 execute(signal, c, returnCode);
1788 }
1789
1790 inline
1791 BlockNumber
number() const1792 SimulatedBlock::number() const {
1793 return theNumber;
1794 }
1795
1796 inline
1797 EmulatedJamBuffer *
jamBuffer() const1798 SimulatedBlock::jamBuffer() const {
1799 return m_jamBuffer;
1800 }
1801
1802 inline
1803 BlockReference
reference() const1804 SimulatedBlock::reference() const {
1805 return theReference;
1806 }
1807
1808 inline
1809 NodeId
getOwnNodeId() const1810 SimulatedBlock::getOwnNodeId() const {
1811 return theNodeId;
1812 }
1813
1814 inline
1815 BlockReference
calcTcBlockRef(NodeId aNodeId)1816 SimulatedBlock::calcTcBlockRef (NodeId aNodeId){
1817 return numberToRef(DBTC, aNodeId);
1818 }
1819
1820 inline
1821 BlockReference
calcLqhBlockRef(NodeId aNodeId)1822 SimulatedBlock::calcLqhBlockRef (NodeId aNodeId){
1823 return numberToRef(DBLQH, aNodeId);
1824 }
1825
1826 inline
1827 BlockReference
calcAccBlockRef(NodeId aNodeId)1828 SimulatedBlock::calcAccBlockRef (NodeId aNodeId){
1829 return numberToRef(DBACC, aNodeId);
1830 }
1831
1832 inline
1833 BlockReference
calcTupBlockRef(NodeId aNodeId)1834 SimulatedBlock::calcTupBlockRef (NodeId aNodeId){
1835 return numberToRef(DBTUP, aNodeId);
1836 }
1837
1838 inline
1839 BlockReference
calcTuxBlockRef(NodeId aNodeId)1840 SimulatedBlock::calcTuxBlockRef (NodeId aNodeId){
1841 return numberToRef(DBTUX, aNodeId);
1842 }
1843
1844 inline
1845 BlockReference
calcDihBlockRef(NodeId aNodeId)1846 SimulatedBlock::calcDihBlockRef (NodeId aNodeId){
1847 return numberToRef(DBDIH, aNodeId);
1848 }
1849
1850 inline
1851 BlockReference
calcDictBlockRef(NodeId aNodeId)1852 SimulatedBlock::calcDictBlockRef (NodeId aNodeId){
1853 return numberToRef(DBDICT, aNodeId);
1854 }
1855
1856 inline
1857 BlockReference
calcQmgrBlockRef(NodeId aNodeId)1858 SimulatedBlock::calcQmgrBlockRef (NodeId aNodeId){
1859 return numberToRef(QMGR, aNodeId);
1860 }
1861
1862 inline
1863 BlockReference
calcNdbCntrBlockRef(NodeId aNodeId)1864 SimulatedBlock::calcNdbCntrBlockRef (NodeId aNodeId){
1865 return numberToRef(NDBCNTR, aNodeId);
1866 }
1867
1868 inline
1869 BlockReference
calcTrixBlockRef(NodeId aNodeId)1870 SimulatedBlock::calcTrixBlockRef (NodeId aNodeId){
1871 return numberToRef(TRIX, aNodeId);
1872 }
1873
1874 inline
1875 BlockReference
calcBackupBlockRef(NodeId aNodeId)1876 SimulatedBlock::calcBackupBlockRef (NodeId aNodeId){
1877 return numberToRef(BACKUP, aNodeId);
1878 }
1879
1880 inline
1881 BlockReference
calcSumaBlockRef(NodeId aNodeId)1882 SimulatedBlock::calcSumaBlockRef (NodeId aNodeId){
1883 return numberToRef(SUMA, aNodeId);
1884 }
1885
1886 inline
1887 BlockReference
calcApiClusterMgrBlockRef(NodeId aNodeId)1888 SimulatedBlock::calcApiClusterMgrBlockRef (NodeId aNodeId){
1889 return numberToRef(API_CLUSTERMGR, aNodeId);
1890 }
1891
1892 inline
1893 BlockReference
calcInstanceBlockRef(BlockNumber aBlock)1894 SimulatedBlock::calcInstanceBlockRef(BlockNumber aBlock){
1895 return numberToRef(aBlock, instance(), getOwnNodeId());
1896 }
1897
1898 inline
1899 BlockReference
calcInstanceBlockRef(BlockNumber aBlock,NodeId aNodeId)1900 SimulatedBlock::calcInstanceBlockRef(BlockNumber aBlock, NodeId aNodeId){
1901 return numberToRef(aBlock, instance(), aNodeId);
1902 }
1903
1904 inline
1905 const NodeState &
getNodeState() const1906 SimulatedBlock::getNodeState() const {
1907 return theNodeState;
1908 }
1909
1910 inline
1911 const NodeInfo &
getNodeInfo(NodeId nodeId) const1912 SimulatedBlock::getNodeInfo(NodeId nodeId) const {
1913 ndbrequire(nodeId > 0 && nodeId < MAX_NODES);
1914 return globalData.m_nodeInfo[nodeId];
1915 }
1916
1917 inline
1918 const NodeVersionInfo &
getNodeVersionInfo() const1919 SimulatedBlock::getNodeVersionInfo() const {
1920 return globalData.m_versionInfo;
1921 }
1922
1923 inline
change_and_get_io_laggers(Int32 change)1924 Uint32 SimulatedBlock::change_and_get_io_laggers(Int32 change)
1925 {
1926 globalData.lock_IO_lag();
1927 Int32 io_laggers = Int32(globalData.get_io_laggers());
1928 require((io_laggers + change) >= 0);
1929 Uint32 new_io_laggers = Uint32(io_laggers + change);
1930 globalData.set_io_laggers(new_io_laggers);
1931 globalData.unlock_IO_lag();
1932 return new_io_laggers;
1933 }
1934
1935 inline
1936 NodeVersionInfo &
setNodeVersionInfo()1937 SimulatedBlock::setNodeVersionInfo() {
1938 return globalData.m_versionInfo;
1939 }
1940
1941 #ifdef VM_TRACE_TIME
1942 inline
1943 void
addTime(Uint32 gsn,Uint64 time)1944 SimulatedBlock::addTime(Uint32 gsn, Uint64 time){
1945 m_timeTrace[gsn].cnt ++;
1946 m_timeTrace[gsn].sum += time;
1947 }
1948
1949 inline
1950 void
subTime(Uint32 gsn,Uint64 time)1951 SimulatedBlock::subTime(Uint32 gsn, Uint64 time){
1952 m_timeTrace[gsn].sub += time;
1953 }
1954 #endif
1955
1956 inline
1957 void
EXECUTE_DIRECT_FN(ExecFunction f,Signal * signal)1958 SimulatedBlock::EXECUTE_DIRECT_FN(ExecFunction f,
1959 Signal *signal)
1960 {
1961 (this->*f)(signal);
1962 }
1963
1964 inline
1965 void
EXECUTE_DIRECT_MT(Uint32 block,Uint32 gsn,Signal * signal,Uint32 len,Uint32 instanceNo)1966 SimulatedBlock::EXECUTE_DIRECT_MT(Uint32 block,
1967 Uint32 gsn,
1968 Signal* signal,
1969 Uint32 len,
1970 Uint32 instanceNo)
1971 {
1972 SimulatedBlock* rec_block;
1973 SimulatedBlock* main_block = globalData.getBlock(block);
1974 ndbassert(main_block != 0);
1975 /**
1976 * In multithreaded NDB, blocks run in different threads, and EXECUTE_DIRECT
1977 * (unlike sendSignal) is generally not thread-safe.
1978 * So only allow EXECUTE_DIRECT between blocks that run in the same thread,
1979 * unless caller explicitly marks it as being thread safe (eg NDBFS),
1980 * by using an explicit instance argument.
1981 * By default instance of sender is used. This is automatically thread-safe
1982 * for worker instances (instance != 0).
1983 *
1984 * We also need to use this function when calling blocks that don't belong
1985 * to the same module, so e.g. LDM blocks can all call each other without
1986 * using this method. But e.g. no block can call THRMAN using implicit
1987 * instance id since the instance numbers of the LDM blocks and the THRMAN
1988 * blocks are not the same. There is one THRMAN instance for each thread,
1989 * not only for the LDM threads.
1990 */
1991 signal->header.theSendersBlockRef = reference();
1992 signal->setLength(len);
1993 ndbassert(instanceNo < MaxInstances);
1994 rec_block = main_block->getInstance(instanceNo);
1995 ndbassert(rec_block != 0);
1996 #ifdef VM_TRACE
1997 if(globalData.testOn){
1998 signal->header.theVerId_signalNumber = gsn;
1999 signal->header.theReceiversBlockNumber = numberToBlock(block, instanceNo);
2000 globalSignalLoggers.executeDirect(signal->header,
2001 0, // in
2002 &signal->theData[0],
2003 globalData.ownId);
2004 }
2005 #endif
2006 #ifdef VM_TRACE_TIME
2007 const NDB_TICKS t1 = NdbTick_getCurrentTicks();
2008 Uint32 tGsn = m_currentGsn;
2009 rec_block->m_currentGsn = gsn;
2010 #endif
2011 rec_block->executeFunction(gsn, signal);
2012 #ifdef VM_TRACE_TIME
2013 const NDB_TICKS t2 = NdbTick_getCurrentTicks();
2014 const Uint64 diff = NdbTick_Elapsed(t1, t2).microSec();
2015 rec_block->addTime(gsn, diff);
2016 m_currentGsn = tGsn;
2017 subTime(tGsn, diff);
2018 #endif
2019 }
2020
2021 /**
2022 We implement the normal EXECUTE_DIRECT in a special function
2023 since this is performance-critical although it introduces a
2024 little bit of code duplication.
2025 */
2026 inline
2027 void
EXECUTE_DIRECT(Uint32 block,Uint32 gsn,Signal * signal,Uint32 len)2028 SimulatedBlock::EXECUTE_DIRECT(Uint32 block,
2029 Uint32 gsn,
2030 Signal* signal,
2031 Uint32 len)
2032 {
2033 /**
2034 globalData.getBlock(block) gives us the pointer to the block of
2035 the receiving class, it gives the pointer to instance 0. This
2036 instance has all the function pointers that all other instances
2037 also have, so we can reuse this block object to get the execute
2038 function. This means that we will use less cache lines over the
2039 system.
2040 */
2041 SimulatedBlock* main_block = globalData.getBlock(block);
2042 Uint32 instanceNo = instance();
2043 BlockReference ref = reference();
2044 SimulatedBlock* rec_block;
2045 signal->setLength(len);
2046 ndbassert(main_block != 0);
2047 ndbassert(main_block->theInstance == 0);
2048 ndbassert(instanceNo < MaxInstances);
2049 rec_block = main_block->theInstanceList[instanceNo];
2050 if (unlikely(gsn > MAX_GSN))
2051 {
2052 handle_execute_error(gsn);
2053 return;
2054 }
2055 ExecFunction f = rec_block->theExecArray[gsn];
2056 signal->header.theSendersBlockRef = ref;
2057 /**
2058 * In this function we only allow function calls within the same thread.
2059 *
2060 * No InstanceList leads to immediate Segmentation Fault,
2061 * so not necessary to check with ndbrequire for this.
2062 */
2063 ndbassert(rec_block != 0);
2064 ndbassert(rec_block->getThreadId() == getThreadId());
2065 #ifdef VM_TRACE
2066 if(globalData.testOn){
2067 signal->header.theVerId_signalNumber = gsn;
2068 signal->header.theReceiversBlockNumber = numberToBlock(block, instanceNo);
2069 globalSignalLoggers.executeDirect(signal->header,
2070 0, // in
2071 &signal->theData[0],
2072 globalData.ownId);
2073 }
2074 #endif
2075 #ifdef VM_TRACE_TIME
2076 const NDB_TICKS t1 = NdbTick_getCurrentTicks();
2077 Uint32 tGsn = m_currentGsn;
2078 rec_block->m_currentGsn = gsn;
2079 #endif
2080 rec_block->executeFunction(gsn, signal, f);
2081 #ifdef VM_TRACE_TIME
2082 const NDB_TICKS t2 = NdbTick_getCurrentTicks();
2083 const Uint64 diff = NdbTick_Elapsed(t1,t2).microSec();
2084 rec_block->addTime(gsn, diff);
2085 m_currentGsn = tGsn;
2086 subTime(tGsn, diff);
2087 #endif
2088 }
2089
2090 inline
2091 void
EXECUTE_DIRECT_WITH_RETURN(Uint32 block,Uint32 gsn,Signal * signal,Uint32 len)2092 SimulatedBlock::EXECUTE_DIRECT_WITH_RETURN(Uint32 block,
2093 Uint32 gsn,
2094 Signal* signal,
2095 Uint32 len)
2096 {
2097 EXECUTE_DIRECT(block, gsn, signal, len);
2098 // TODO check prepareRETURN_DIRECT have been called
2099 }
2100
2101 inline
2102 void
EXECUTE_DIRECT_WITH_SECTIONS(Uint32 block,Uint32 gsn,Signal * signal,Uint32 len,SectionHandle * sections)2103 SimulatedBlock::EXECUTE_DIRECT_WITH_SECTIONS(Uint32 block,
2104 Uint32 gsn,
2105 Signal* signal,
2106 Uint32 len,
2107 SectionHandle* sections)
2108 {
2109 signal->header.m_noOfSections = sections->m_cnt;
2110 for (Uint32 i = 0; i < sections->m_cnt; i++)
2111 {
2112 signal->m_sectionPtrI[i] = sections->m_ptr[i].i;
2113 }
2114 sections->clear();
2115 EXECUTE_DIRECT(block, gsn, signal, len);
2116 }
2117
2118 inline
2119 void
prepareRETURN_DIRECT(Uint32 gsn,Signal * signal,Uint32 len)2120 SimulatedBlock::prepareRETURN_DIRECT(Uint32 gsn,
2121 Signal* signal,
2122 Uint32 len)
2123 {
2124 signal->setLength(len);
2125 if (unlikely(gsn > MAX_GSN))
2126 {
2127 handle_execute_error(gsn);
2128 return;
2129 }
2130 signal->header.theVerId_signalNumber = gsn;
2131 }
2132
2133 // Do a consictency check before reusing a signal.
2134 inline void
check_sections(Signal * signal,Uint32 oldSecCount,Uint32 newSecCount) const2135 SimulatedBlock::check_sections(Signal* signal,
2136 Uint32 oldSecCount,
2137 Uint32 newSecCount) const
2138 {
2139 // Sections from previous use should have been consumed by now.
2140 if (unlikely(oldSecCount != 0))
2141 {
2142 handle_invalid_sections_in_send_signal(signal);
2143 }
2144 else if (unlikely(newSecCount == 0 &&
2145 signal->header.m_fragmentInfo != 0 &&
2146 signal->header.m_fragmentInfo != 3))
2147 {
2148 handle_invalid_fragmentInfo(signal);
2149 }
2150 }
2151
2152 /**
2153 * Defines for backward compatiblility
2154 */
2155
2156 #define BLOCK_DEFINES(BLOCK) \
2157 typedef void (BLOCK::* ExecSignalLocal) (Signal* signal); \
2158 typedef void (BLOCK::* BlockCallback)(Signal*, Uint32 callb, Uint32 retCode); \
2159 inline CallbackFunction safe_cast(BlockCallback f){ \
2160 return static_cast<CallbackFunction>(f); \
2161 } \
2162 public:\
2163 private: \
2164 void addRecSignal(GlobalSignalNumber gsn, ExecSignalLocal f, bool force = false)
2165
2166 #define BLOCK_CONSTRUCTOR(BLOCK) do { SimulatedBlock::initCommon(); } while(0)
2167
2168 #define BLOCK_FUNCTIONS(BLOCK) \
2169 void \
2170 BLOCK::addRecSignal(GlobalSignalNumber gsn, ExecSignalLocal f, bool force){ \
2171 addRecSignalImpl(gsn, (ExecFunction)f, force);\
2172 }
2173
2174 #ifdef ERROR_INSERT
2175 #define RSS_AP_SNAPSHOT(x) Uint32 rss_##x
2176 #define RSS_AP_SNAPSHOT_SAVE(x) rss_##x = x.getUsed()
2177 #define RSS_AP_SNAPSHOT_CHECK(x) ndbrequire(rss_##x == x.getUsed())
2178 #define RSS_AP_SNAPSHOT_SAVE2(x,y) rss_##x = x.getUsed()-(y)
2179 #define RSS_AP_SNAPSHOT_CHECK2(x,y) ndbrequire(rss_##x == x.getUsed()-(y))
2180
2181 #define RSS_OP_COUNTER(x) Uint32 x
2182 #define RSS_OP_COUNTER_INIT(x) x = 0
2183 #define RSS_OP_ALLOC(x) x ++
2184 #define RSS_OP_FREE(x) x --
2185 #define RSS_OP_ALLOC_X(x,n) x += n
2186 #define RSS_OP_FREE_X(x,n) x -= n
2187
2188 #define RSS_OP_SNAPSHOT(x) Uint32 rss_##x
2189 #define RSS_OP_SNAPSHOT_SAVE(x) rss_##x = x
2190 #define RSS_OP_SNAPSHOT_CHECK(x) ndbrequire(rss_##x == x)
2191
2192 #define RSS_DA256_SNAPSHOT(x) Uint32 rss_##x
2193 #define RSS_DA256_SNAPSHOT_SAVE(x) rss_##x = x.m_high_pos
2194 #define RSS_DA256_SNAPSHOT_CHECK(x) ndbrequire(x.m_high_pos <= rss_##x)
2195 #else
2196 #define RSS_AP_SNAPSHOT(x) struct rss_dummy0_##x { int dummy; }
2197 #define RSS_AP_SNAPSHOT_SAVE(x)
2198 #define RSS_AP_SNAPSHOT_CHECK(x)
2199 #define RSS_AP_SNAPSHOT_SAVE2(x,y)
2200 #define RSS_AP_SNAPSHOT_CHECK2(x,y)
2201
2202 #define RSS_OP_COUNTER(x) struct rss_dummy1_##x { int dummy; }
2203 #define RSS_OP_COUNTER_INIT(x)
2204 #define RSS_OP_ALLOC(x)
2205 #define RSS_OP_FREE(x)
2206 #define RSS_OP_ALLOC_X(x,n)
2207 #define RSS_OP_FREE_X(x,n)
2208
2209 #define RSS_OP_SNAPSHOT(x) struct rss_dummy2_##x { int dummy; }
2210 #define RSS_OP_SNAPSHOT_SAVE(x)
2211 #define RSS_OP_SNAPSHOT_CHECK(x)
2212
2213 #define RSS_DA256_SNAPSHOT(x)
2214 #define RSS_DA256_SNAPSHOT_SAVE(x)
2215 #define RSS_DA256_SNAPSHOT_CHECK(x)
2216 #endif
2217
2218 struct Hash2FragmentMap
2219 {
2220 STATIC_CONST( MAX_MAP = NDB_MAX_HASHMAP_BUCKETS );
2221 Uint32 m_cnt;
2222 Uint32 m_fragments;
2223 Uint16 m_map[MAX_MAP];
2224 Uint32 nextPool;
2225 Uint32 m_object_id;
2226 };
2227 typedef ArrayPool<Hash2FragmentMap> Hash2FragmentMap_pool;
2228
2229 extern Hash2FragmentMap_pool g_hash_map;
2230
2231 /**
2232 * Guard class for auto release of segmentedsectionptr's
2233 */
2234 class SegmentedSectionGuard
2235 {
2236 Uint32 cnt;
2237 Uint32 ptr[3];
2238 SimulatedBlock * block;
2239
2240 public:
SegmentedSectionGuard(SimulatedBlock * b)2241 SegmentedSectionGuard(SimulatedBlock* b) : cnt(0), block(b) { }
SegmentedSectionGuard(SimulatedBlock * b,Uint32 ptrI)2242 SegmentedSectionGuard(SimulatedBlock* b, Uint32 ptrI) : cnt(1), block(b) {
2243 ptr[0] = ptrI;
2244 }
2245
add(Uint32 ptrI)2246 void add(Uint32 ptrI) {
2247 if (ptrI != RNIL)
2248 {
2249 assert(cnt < NDB_ARRAY_SIZE(ptr));
2250 ptr[cnt] = ptrI;
2251 cnt++;
2252 }
2253 }
2254
release()2255 void release() {
2256 for (Uint32 i = 0; i < cnt; i++) {
2257 if (ptr[i] != RNIL)
2258 block->releaseSection(ptr[i]);
2259 }
2260 cnt = 0;
2261 }
2262
clear()2263 void clear() {
2264 cnt = 0;
2265 }
2266
~SegmentedSectionGuard()2267 ~SegmentedSectionGuard() {
2268 release();
2269 }
2270 };
2271
2272 #undef JAM_FILE_ID
2273
2274 #endif
2275
2276