18 #ifndef SIMULATEDBLOCK_H
19 #define SIMULATEDBLOCK_H
22 #include <kernel_types.h>
23 #include <util/version.h>
24 #include <ndb_limits.h>
26 #include "VMSignal.hpp"
27 #include <RefConvert.hpp>
28 #include <BlockNumbers.h>
29 #include <GlobalSignalNumbers.h>
33 #include <NodeInfo.hpp>
34 #include <NodeState.hpp>
35 #include "GlobalData.hpp"
36 #include "LongSignal.hpp"
37 #include <SignalLoggerManager.hpp>
39 #include <ErrorReporter.hpp>
40 #include <ErrorHandlingMacros.hpp>
43 #include "ArrayPool.hpp"
44 #include "DLHashTable.hpp"
47 #include "Callback.hpp"
48 #include "SafeCounter.hpp"
51 #include <mgmapi_config_parameters.h>
52 #include <mgmapi_config_parameters_debug.h>
53 #include <kernel_config_parameters.h>
54 #include <Configuration.hpp>
56 #include <signaldata/ReadConfig.hpp>
57 #include "ndbd_malloc_impl.hpp"
58 #include <blocks/record_types.hpp>
60 #include "Ndbinfo.hpp"
66 if (!debugOutOn()) break; \
68 debugOutStream() << debugOutTag(buf, __LINE__) << x << dec << "\n"; \
71 #define V(x) " " << #x << ":" << (x)
73 #define D(x) do { } while(0)
87 unsigned int unused : 25 ;
101 : m_config(cfg), m_mm(mm) {}
107 friend class TraceLCP;
124 friend class BlockComponent;
133 Uint32 instanceNumber = 0);
139 void addRecSignalImpl(GlobalSignalNumber g, ExecFunction fun,
bool f =
false);
140 void installSimulatedBlockFunctions();
141 ExecFunction theExecArray[MAX_GSN+1];
149 CallbackFunction m_callbackFunction;
150 Uint32 m_callbackData;
159 Uint32 instance()
const {
163 ndbrequire(theInstance == 0);
164 if (instanceNumber == 0)
166 ndbrequire(instanceNumber < MaxInstances);
167 if (theInstanceList != 0)
168 return theInstanceList[instanceNumber];
172 virtual void loadWorkers() {}
178 Uint32 * watchDogCounter;
179 SectionSegmentPool::Cache * sectionPoolCache;
184 uint32 getThreadId()
const {
return m_threadId; }
185 static bool isMultiThreaded();
188 static bool isNdbMt() {
return globalData.isNdbMt; }
189 static bool isNdbMtLqh() {
return globalData.isNdbMtLqh; }
190 static Uint32 getLqhWorkers() {
return globalData.ndbMtLqhWorkers; }
208 static Uint32 getInstanceKey(Uint32 tabId, Uint32 fragId);
209 static Uint32 getInstanceFromKey(Uint32 instanceKey);
217 const Callback&, JobBufferLevel = JBB);
224 const Callback&, JobBufferLevel = JBB);
227 struct SyncThreadRecord
234 void execSYNC_THREAD_REQ(
Signal*);
235 void execSYNC_THREAD_CONF(
Signal*);
237 void execSYNC_REQ(
Signal*);
239 void execSYNC_PATH_REQ(
Signal*);
240 void execSYNC_PATH_CONF(
Signal*);
242 virtual const char* get_filename(Uint32 fd)
const {
return "";}
244 static Callback TheEmptyCallback;
245 void TheNULLCallbackFunction(
class Signal*, Uint32, Uint32);
246 static Callback TheNULLCallback;
247 void execute(
Signal* signal, Callback & c, Uint32 returnCode);
254 void sendSignal(BlockReference ref,
255 GlobalSignalNumber gsn,
258 JobBufferLevel jbuf )
const ;
261 GlobalSignalNumber gsn,
264 JobBufferLevel jbuf )
const ;
266 void sendSignal(BlockReference ref,
267 GlobalSignalNumber gsn,
274 GlobalSignalNumber gsn,
280 void sendSignal(BlockReference ref,
281 GlobalSignalNumber gsn,
286 Uint32 noOfSections)
const ;
289 GlobalSignalNumber gsn,
294 Uint32 noOfSections)
const ;
301 GlobalSignalNumber gsn,
308 GlobalSignalNumber gsn,
317 void sendSignalWithDelay(BlockReference ref,
318 GlobalSignalNumber gsn,
320 Uint32 delayInMilliSeconds,
321 Uint32 length)
const ;
323 void sendSignalWithDelay(BlockReference ref,
324 GlobalSignalNumber gsn,
326 Uint32 delayInMilliSeconds,
338 Uint32 givenInstanceNo = ZNIL);
347 void releaseSection(Uint32 firstSegmentIVal);
352 bool appendToSection(Uint32& firstSegmentIVal,
const Uint32* src, Uint32 len);
353 bool dupSection(Uint32& copyFirstIVal, Uint32 srcFirstIVal);
354 bool writeToSection(Uint32 firstSegmentIVal, Uint32
offset,
const Uint32* src, Uint32 len);
356 void handle_invalid_sections_in_send_signal(
Signal*)
const;
357 void handle_lingering_sections_after_execute(
Signal*)
const;
358 void handle_lingering_sections_after_execute(
SectionHandle*)
const;
359 void handle_invalid_fragmentInfo(
Signal*)
const;
360 void handle_send_failed(SendStatus,
Signal*)
const;
361 void handle_out_of_longsignal_memory(
Signal*)
const;
420 STATIC_CONST( FRAGMENT_WORD_SIZE = 240 );
422 void sendFragmentedSignal(BlockReference ref,
423 GlobalSignalNumber gsn,
429 Uint32 messageSize = FRAGMENT_WORD_SIZE);
432 GlobalSignalNumber gsn,
438 Uint32 messageSize = FRAGMENT_WORD_SIZE);
440 void sendFragmentedSignal(BlockReference ref,
441 GlobalSignalNumber gsn,
448 Uint32 messageSize = FRAGMENT_WORD_SIZE);
451 GlobalSignalNumber gsn,
458 Uint32 messageSize = FRAGMENT_WORD_SIZE);
503 Uint32 m_sectionPtrI[3];
511 return m_senderRef == p.m_senderRef && m_fragmentId == p.m_fragmentId;
514 inline Uint32 hashValue()
const {
515 return m_senderRef + m_fragmentId ;
518 inline bool isDropped()
const {
520 return (( m_sectionPtrI[0] == RNIL ) &&
521 ( m_sectionPtrI[1] == RNIL ) &&
522 ( m_sectionPtrI[2] == RNIL ) );
541 SendNoReleaseSeg = 0x1
545 Uint16 m_messageSize;
570 GlobalSignalNumber gsn,
576 Uint32 messageSize = FRAGMENT_WORD_SIZE);
580 GlobalSignalNumber gsn,
586 Uint32 messageSize = FRAGMENT_WORD_SIZE);
602 BlockNumber number()
const;
607 BlockReference reference()
const;
608 NodeId getOwnNodeId()
const;
615 void update_watch_dog_timer(Uint32 interval);
623 void progError(
int line,
int err_code,
const char* extradata=NULL) const
626 void signal_error(Uint32, Uint32, Uint32, const
char*,
int) const
628 const NodeId theNodeId;
629 const BlockNumber theNumber;
630 const Uint32 theInstance;
631 const BlockReference theReference;
637 enum { MaxInstances = 1 + MAX_NDBMT_LQH_WORKERS + 1 };
652 Uint32 *m_watchDogCounter;
654 SectionSegmentPool::Cache * m_sectionPoolCache;
657 Uint32 doNodeFailureCleanup(
Signal* signal,
661 Uint32 elementsCleaned,
664 bool doCleanupFragInfo(Uint32 failedNodeId,
667 Uint32& elementsCleaned);
669 bool doCleanupFragSend(Uint32 failedNodeId,
672 Uint32& elementsCleaned);
678 static const NewVARIABLE* getBat (BlockNumber blockNo,
680 static Uint16 getBatSize(BlockNumber blockNo,
683 static BlockReference calcTcBlockRef (NodeId aNode);
684 static BlockReference calcLqhBlockRef (NodeId aNode);
685 static BlockReference calcAccBlockRef (NodeId aNode);
686 static BlockReference calcTupBlockRef (NodeId aNode);
687 static BlockReference calcTuxBlockRef (NodeId aNode);
688 static BlockReference calcDihBlockRef (NodeId aNode);
689 static BlockReference calcQmgrBlockRef (NodeId aNode);
690 static BlockReference calcDictBlockRef (NodeId aNode);
691 static BlockReference calcNdbCntrBlockRef (NodeId aNode);
692 static BlockReference calcTrixBlockRef (NodeId aNode);
693 static BlockReference calcBackupBlockRef (NodeId aNode);
694 static BlockReference calcSumaBlockRef (NodeId aNode);
696 static BlockReference calcApiClusterMgrBlockRef (NodeId aNode);
699 BlockReference calcInstanceBlockRef(BlockNumber aBlock);
703 BlockReference calcInstanceBlockRef(BlockNumber aBlock, NodeId aNode);
710 void*
allocRecord(
const char *
type,
size_t s,
size_t n,
bool clear =
true, Uint32 paramId = 0);
711 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);
732 Uint32 allocChunks(
AllocChunk dst[], Uint32 arraysize,
737 static int sortchunks(
const void*,
const void*);
743 ATTRIBUTE_FORMAT(printf, 2, 3);
745 ATTRIBUTE_FORMAT(printf, 2, 3);
768 Uint32
xfrm_key(Uint32 tab, const Uint32* src,
769 Uint32 *dst, Uint32 dstSize,
770 Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX]) const;
773 const Uint32* src, Uint32 & srcPos,
774 Uint32* dst, Uint32 & dstPos, Uint32 dstSize) const;
779 Uint32 create_distr_key(Uint32 tableId,
782 const Uint32 keyPaLen[MAX_ATTRIBUTES_IN_INDEX])const;
805 void execNDB_TAMPER(
Signal * signal);
806 void execNODE_STATE_REP(
Signal* signal);
809 void execSIGNAL_DROPPED_REP(
Signal* signal);
810 void execCONTINUE_FRAGMENTED(
Signal* signal);
811 void execSTOP_FOR_CRASH(
Signal* signal);
812 void execAPI_START_REP(
Signal* signal);
813 void execNODE_START_REP(
Signal* signal);
814 void execSEND_PACKED(
Signal* signal);
822 Uint32 c_fragmentIdCounter;
826 bool c_fragSenderRunning;
832 Uint32 debugPrintFragmentCounts();
842 bool setSize(Uint32 maxNoOfActiveMutexes);
843 Uint32 getSize()
const ;
862 bool seize(ActiveMutexPtr& ptr);
863 void release(Uint32 activeMutexPtrI);
865 void getPtr(ActiveMutexPtr& ptr);
867 void create(Signal*, ActiveMutexPtr&);
868 void destroy(Signal*, ActiveMutexPtr&);
869 void lock(Signal*, ActiveMutexPtr&, Uint32
flags);
870 void unlock(Signal*, ActiveMutexPtr&);
873 void execUTIL_CREATE_LOCK_REF(Signal* signal);
874 void execUTIL_CREATE_LOCK_CONF(Signal* signal);
875 void execUTIL_DESTORY_LOCK_REF(Signal* signal);
876 void execUTIL_DESTORY_LOCK_CONF(Signal* signal);
877 void execUTIL_LOCK_REF(Signal* signal);
878 void execUTIL_LOCK_CONF(Signal* signal);
879 void execUTIL_UNLOCK_REF(Signal* signal);
880 void execUTIL_UNLOCK_CONF(Signal* signal);
886 BlockReference reference()
const;
893 void ignoreMutexUnlockCallback(
Signal* signal, Uint32 ptrI, Uint32 retVal);
894 virtual bool getParam(
const char * param, Uint32 * retVal) {
return false;}
898 void execUTIL_CREATE_LOCK_REF(
Signal* signal);
899 void execUTIL_CREATE_LOCK_CONF(
Signal* signal);
900 void execUTIL_DESTORY_LOCK_REF(
Signal* signal);
901 void execUTIL_DESTORY_LOCK_CONF(
Signal* signal);
902 void execUTIL_LOCK_REF(
Signal* signal);
903 void execUTIL_LOCK_CONF(
Signal* signal);
904 void execUTIL_UNLOCK_REF(
Signal* signal);
905 void execUTIL_UNLOCK_CONF(
Signal* signal);
909 void fsRefError(
Signal* signal, Uint32 line,
const char *
msg);
910 void execFSWRITEREF(
Signal* signal);
911 void execFSREADREF(
Signal* signal);
912 void execFSOPENREF(
Signal* signal);
913 void execFSCLOSEREF(
Signal* signal);
914 void execFSREMOVEREF(
Signal* signal);
915 void execFSSYNCREF(
Signal* signal);
916 void execFSAPPENDREF(
Signal* signal);
921 Uint32 m_callbackIndex;
922 Uint32 m_callbackData;
926 CALLBACK_DIRECT = 0x0001,
927 CALLBACK_ACK = 0x0002
931 CallbackFunction m_function;
943 THE_NULL_CALLBACK = 0
946 void execute(
Signal* signal, CallbackPtr & cptr, Uint32 returnCode);
947 const CallbackEntry& getCallbackEntry(Uint32 ci);
948 void sendCallbackConf(
Signal* signal, Uint32 fullBlockNo,
949 CallbackPtr& cptr, Uint32 returnCode);
950 void execCALLBACK_CONF(
Signal* signal);
953 ERROR_INSERT_VARIABLE;
958 void printTimes(FILE * output);
959 void addTime(Uint32 gsn, Uint64 time);
960 void subTime(Uint32 gsn, Uint64 time);
964 } m_timeTrace[MAX_GSN+1];
969 Ptr<void> **m_global_variables, **m_global_variables_save;
970 void clear_global_variables();
971 void init_globals_list(
void ** tmp,
size_t cnt);
972 void disable_global_variables();
973 void enable_global_variables();
979 NdbOut& debugOutStream() {
return debugOut; };
981 void debugOutLock() { globalSignalLoggers.lock(); }
982 void debugOutUnlock() { globalSignalLoggers.unlock(); }
983 const char* debugOutTag(
char*
buf,
int line);
986 void ndbinfo_send_row(
Signal* signal,
991 void ndbinfo_send_scan_break(
Signal* signal,
994 Uint32 data1, Uint32 data2 = 0,
995 Uint32 data3 = 0, Uint32 data4 = 0)
const;
997 void ndbinfo_send_scan_conf(
Signal* signal,
1005 #define DEBUG_OUT_DEFINES(blockNo) \
1006 static SimulatedBlock* debugOutBlock() \
1007 { return globalData.getBlock(blockNo); } \
1008 static NdbOut& debugOutStream() \
1009 { return debugOutBlock()->debugOutStream(); } \
1010 static bool debugOutOn() \
1011 { return debugOutBlock()->debugOutOn(); } \
1012 static void debugOutLock() \
1013 { debugOutBlock()->debugOutLock(); } \
1014 static void debugOutUnlock() \
1015 { debugOutBlock()->debugOutUnlock(); } \
1016 static const char* debugOutTag(char* buf, int line) \
1017 { return debugOutBlock()->debugOutTag(buf, line); } \
1018 static void debugOutDefines()
1020 #define DEBUG_OUT_DEFINES(blockNo) \
1021 static void debugOutDefines()
1027 ExecFunction f = theExecArray[gsn];
1028 if(gsn <= MAX_GSN && f != 0){
1030 clear_global_variables();
1034 if (unlikely(signal->header.m_noOfSections))
1036 handle_lingering_sections_after_execute(signal);
1045 if (!(gsn <= MAX_GSN)) {
1047 ERROR_SET(fatal, NDBD_EXIT_PRGERR, errorMsg, errorMsg);
1049 if (!(theExecArray[gsn] != 0)) {
1051 ERROR_SET(fatal, NDBD_EXIT_PRGERR, errorMsg, errorMsg);
1058 SimulatedBlock::execute(
Signal* signal, Callback & c, Uint32 returnCode){
1059 CallbackFunction fun = c.m_callbackFunction;
1060 if (fun == TheNULLCallback.m_callbackFunction)
1062 ndbrequire(fun != 0);
1063 c.m_callbackFunction = NULL;
1064 (this->*fun)(signal, c.m_callbackData, returnCode);
1069 SimulatedBlock::execute(
Signal* signal, CallbackPtr & cptr, Uint32 returnCode){
1070 const CallbackEntry& ce = getCallbackEntry(cptr.m_callbackIndex);
1071 cptr.m_callbackIndex = ZNIL;
1073 c.m_callbackFunction = ce.m_function;
1074 c.m_callbackData = cptr.m_callbackData;
1075 execute(signal, c, returnCode);
1080 SimulatedBlock::number()
const {
1086 SimulatedBlock::jamBuffer()
const {
1092 SimulatedBlock::reference()
const {
1093 return theReference;
1098 SimulatedBlock::getOwnNodeId()
const {
1104 SimulatedBlock::calcTcBlockRef (NodeId aNodeId){
1105 return numberToRef(DBTC, aNodeId);
1110 SimulatedBlock::calcLqhBlockRef (NodeId aNodeId){
1111 return numberToRef(DBLQH, aNodeId);
1116 SimulatedBlock::calcAccBlockRef (NodeId aNodeId){
1117 return numberToRef(DBACC, aNodeId);
1122 SimulatedBlock::calcTupBlockRef (NodeId aNodeId){
1123 return numberToRef(DBTUP, aNodeId);
1128 SimulatedBlock::calcTuxBlockRef (NodeId aNodeId){
1129 return numberToRef(DBTUX, aNodeId);
1134 SimulatedBlock::calcDihBlockRef (NodeId aNodeId){
1135 return numberToRef(DBDIH, aNodeId);
1140 SimulatedBlock::calcDictBlockRef (NodeId aNodeId){
1141 return numberToRef(DBDICT, aNodeId);
1146 SimulatedBlock::calcQmgrBlockRef (NodeId aNodeId){
1147 return numberToRef(QMGR, aNodeId);
1152 SimulatedBlock::calcNdbCntrBlockRef (NodeId aNodeId){
1153 return numberToRef(NDBCNTR, aNodeId);
1158 SimulatedBlock::calcTrixBlockRef (NodeId aNodeId){
1159 return numberToRef(TRIX, aNodeId);
1164 SimulatedBlock::calcBackupBlockRef (NodeId aNodeId){
1165 return numberToRef(BACKUP, aNodeId);
1170 SimulatedBlock::calcSumaBlockRef (NodeId aNodeId){
1171 return numberToRef(SUMA, aNodeId);
1176 SimulatedBlock::calcApiClusterMgrBlockRef (NodeId aNodeId){
1177 return numberToRef(API_CLUSTERMGR, aNodeId);
1182 SimulatedBlock::calcInstanceBlockRef(BlockNumber aBlock){
1183 return numberToRef(aBlock, instance(), getOwnNodeId());
1188 SimulatedBlock::calcInstanceBlockRef(BlockNumber aBlock, NodeId aNodeId){
1189 return numberToRef(aBlock, instance(), aNodeId);
1195 return theNodeState;
1201 ndbrequire(nodeId > 0 && nodeId < MAX_NODES);
1202 return globalData.m_nodeInfo[nodeId];
1207 SimulatedBlock::getNodeVersionInfo()
const {
1208 return globalData.m_versionInfo;
1213 SimulatedBlock::setNodeVersionInfo() {
1214 return globalData.m_versionInfo;
1217 #ifdef VM_TRACE_TIME
1220 SimulatedBlock::addTime(Uint32 gsn, Uint64 time){
1221 m_timeTrace[gsn].cnt ++;
1222 m_timeTrace[gsn].sum += time;
1227 SimulatedBlock::subTime(Uint32 gsn, Uint64 time){
1228 m_timeTrace[gsn].sub += time;
1238 Uint32 givenInstanceNo)
1240 signal->setLength(len);
1252 Uint32 instanceNo = givenInstanceNo;
1253 if (instanceNo == ZNIL)
1254 instanceNo = instance();
1255 if (instanceNo != 0)
1256 b = b->getInstance(instanceNo);
1258 ndbassert(givenInstanceNo != ZNIL || b->getThreadId() == getThreadId());
1259 signal->header.theSendersBlockRef = reference();
1261 if(globalData.testOn){
1262 signal->header.theVerId_signalNumber = gsn;
1263 signal->header.theReceiversBlockNumber = numberToBlock(block, instanceNo);
1264 globalSignalLoggers.executeDirect(signal->header,
1266 &signal->theData[0],
1270 #ifdef VM_TRACE_TIME
1273 NdbTick_CurrentMicrosecond(&ms1, &us1);
1274 Uint32 tGsn = m_currentGsn;
1275 b->m_currentGsn = gsn;
1278 #ifdef VM_TRACE_TIME
1279 NdbTick_CurrentMicrosecond(&ms2, &us2);
1285 b->addTime(gsn, diff);
1286 m_currentGsn = tGsn;
1287 subTime(tGsn, diff);
1295 #define BLOCK_DEFINES(BLOCK) \
1296 typedef void (BLOCK::* ExecSignalLocal) (Signal* signal); \
1297 typedef void (BLOCK::* BlockCallback)(Signal*, Uint32 callb, Uint32 retCode); \
1298 inline CallbackFunction safe_cast(BlockCallback f){ \
1299 return static_cast<CallbackFunction>(f); \
1303 void addRecSignal(GlobalSignalNumber gsn, ExecSignalLocal f, bool force = false)
1305 #define BLOCK_CONSTRUCTOR(BLOCK) do { SimulatedBlock::initCommon(); } while(0)
1307 #define BLOCK_FUNCTIONS(BLOCK) \
1309 BLOCK::addRecSignal(GlobalSignalNumber gsn, ExecSignalLocal f, bool force){ \
1310 addRecSignalImpl(gsn, (ExecFunction)f, force);\
1313 #include "Mutex.hpp"
1316 SectionHandle::~SectionHandle()
1318 if (unlikely(m_cnt))
1320 m_block->handle_lingering_sections_after_execute(
this);
1325 #define RSS_AP_SNAPSHOT(x) Uint32 rss_##x
1326 #define RSS_AP_SNAPSHOT_SAVE(x) rss_##x = x.getNoOfFree()
1327 #define RSS_AP_SNAPSHOT_CHECK(x) ndbrequire(rss_##x == x.getNoOfFree())
1328 #define RSS_AP_SNAPSHOT_SAVE2(x,y) rss_##x = x.getNoOfFree()+(y)
1329 #define RSS_AP_SNAPSHOT_CHECK2(x,y) ndbrequire(rss_##x == x.getNoOfFree()+(y))
1331 #define RSS_OP_COUNTER(x) Uint32 x
1332 #define RSS_OP_COUNTER_INIT(x) x = 0
1333 #define RSS_OP_ALLOC(x) x ++
1334 #define RSS_OP_FREE(x) x --
1335 #define RSS_OP_ALLOC_X(x,n) x += n
1336 #define RSS_OP_FREE_X(x,n) x -= n
1338 #define RSS_OP_SNAPSHOT(x) Uint32 rss_##x
1339 #define RSS_OP_SNAPSHOT_SAVE(x) rss_##x = x
1340 #define RSS_OP_SNAPSHOT_CHECK(x) ndbrequire(rss_##x == x)
1342 #define RSS_AP_SNAPSHOT(x) struct rss_dummy0_##x { int dummy; }
1343 #define RSS_AP_SNAPSHOT_SAVE(x)
1344 #define RSS_AP_SNAPSHOT_CHECK(x)
1345 #define RSS_AP_SNAPSHOT_SAVE2(x,y)
1346 #define RSS_AP_SNAPSHOT_CHECK2(x,y)
1348 #define RSS_OP_COUNTER(x) struct rss_dummy1_##x { int dummy; }
1349 #define RSS_OP_COUNTER_INIT(x)
1350 #define RSS_OP_ALLOC(x)
1351 #define RSS_OP_FREE(x)
1352 #define RSS_OP_ALLOC_X(x,n)
1353 #define RSS_OP_FREE_X(x,n)
1355 #define RSS_OP_SNAPSHOT(x) struct rss_dummy2_##x { int dummy; }
1356 #define RSS_OP_SNAPSHOT_SAVE(x)
1357 #define RSS_OP_SNAPSHOT_CHECK(x)
1363 STATIC_CONST( MAX_MAP = 240 );
1366 Uint8 m_map[MAX_MAP];