📄 threadconfig.cpp
字号:
/* Copyright (C) 2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "ThreadConfig.hpp"#include "Emulator.hpp"#include "GlobalData.hpp"#include "TimeQueue.hpp"#include "TransporterRegistry.hpp"#include "FastScheduler.hpp"#include "pc.hpp"#include <GlobalSignalNumbers.h>#include <BlockNumbers.h>#include <NdbSleep.h>#include <NdbTick.h>#include <NdbOut.hpp>#include <signaldata/StartOrd.hpp>ThreadConfig::ThreadConfig(){}ThreadConfig::~ThreadConfig(){}/** * For each millisecond that has passed since this function was last called: * Scan the job buffer and increment the internalMillisecCounter * with 1 to keep track of where we are */inlinevoid ThreadConfig::scanTimeQueue(){ unsigned int maxCounter; Uint64 currMilliSecond; maxCounter = 0; currMilliSecond = NdbTick_CurrentMillisecond(); if (currMilliSecond < globalData.internalMillisecCounter) {//--------------------------------------------------------------------// This could occur around 2036 or if the operator decides to change// time backwards. We cannot know how long time has past since last// time and we make a best try with 0 milliseconds.//--------------------------------------------------------------------#ifdef VM_TRACE ndbout << "Time moved backwards with "; ndbout << (globalData.internalMillisecCounter - currMilliSecond); ndbout << " milliseconds" << endl;#endif globalData.internalMillisecCounter = currMilliSecond; }//if if (currMilliSecond > (globalData.internalMillisecCounter + 1500)) {//--------------------------------------------------------------------// Time has moved forward more than a second. Either it could happen// if operator changed the time or if the OS has misbehaved badly.// We set the new time to one second from the past.//--------------------------------------------------------------------#ifdef VM_TRACE ndbout << "Time moved forward with "; ndbout << (currMilliSecond - globalData.internalMillisecCounter); ndbout << " milliseconds" << endl;#endif globalData.internalMillisecCounter = currMilliSecond - 1000; }//if while (((currMilliSecond - globalData.internalMillisecCounter) > 0) && (maxCounter < 20)){ globalData.internalMillisecCounter++; maxCounter++; globalTimeQueue.scanTable(); }//while}//ThreadConfig::scanTimeQueue()//--------------------------------------------------------------------// ipControlLoop -- The main loop of ndb.// Handles the scheduling of signal execution and input/output// One lap in the loop should take approximately 10 milli seconds// If the jobbuffer is empty and the laptime is less than 10 milliseconds// at the end of the loop// the TransporterRegistry is called in order to sleep on the IO ports// waiting for another incoming signal to wake us up.// The timeout value in this call is calculated as (10 ms - laptime)// This would make ndb use less cpu while improving response time.//--------------------------------------------------------------------void ThreadConfig::ipControlLoop(){#if defined NDB_OSE || defined NDB_SOFTOSE//--------------------------------------------------------------------// To let the Cello Watchdog do it's work NDB must sleep a short // period every 10 minutes. If this is not done, the watchdog will // reboot the board NDB is running on when the load is high. //-------------------------------------------------------------------- int loopCounter = 0;#endif//--------------------------------------------------------------------// initialise the counter that keeps track of the current millisecond//-------------------------------------------------------------------- globalData.internalMillisecCounter = NdbTick_CurrentMillisecond(); Uint32 i = 0; while (globalData.theRestartFlag != perform_stop) { #if defined NDB_OSE || defined NDB_SOFTOSE loopCounter++; if(loopCounter > 1000){//--------------------------------------------------------------------// This is done to allow OSE do a context switch to let the watchdog // do it's stuff.//-------------------------------------------------------------------- NdbSleep_MilliSleep(1); loopCounter = 0; }#endif Uint32 timeOutMillis = 0; if (LEVEL_IDLE == globalData.highestAvailablePrio) {//--------------------------------------------------------------------// The buffers are empty, we need to wait for a while until we continue.// We cannot wait forever since we can also have timed events.//--------------------------------------------------------------------//--------------------------------------------------------------------// Set the time we will sleep on the sockets before waking up// unconditionally to 10 ms. Will never sleep more than 10 milliseconds// on a socket.//-------------------------------------------------------------------- timeOutMillis = 10; }//if//--------------------------------------------------------------------// Now it is time to check all interfaces. We will send all buffers// plus checking for any received messages.//-------------------------------------------------------------------- if (i++ >= 20) { globalTransporterRegistry.update_connections(); globalData.incrementWatchDogCounter(5); i = 0; }//if globalData.incrementWatchDogCounter(6); globalTransporterRegistry.performSend(); globalData.incrementWatchDogCounter(7); if (globalTransporterRegistry.pollReceive(timeOutMillis)) { globalData.incrementWatchDogCounter(8); globalTransporterRegistry.performReceive(); }//--------------------------------------------------------------------// We scan the time queue to see if there are any timed signals that// is now ready to be executed.//-------------------------------------------------------------------- globalData.incrementWatchDogCounter(2); scanTimeQueue(); //--------------------------------------------------------------------// This is where the actual execution of signals occur. We execute// until all buffers are empty or until we have executed 2048 signals.//-------------------------------------------------------------------- globalScheduler.doJob(); }//while globalData.incrementWatchDogCounter(6); globalTransporterRegistry.performSend();}//ThreadConfig::ipControlLoop()intThreadConfig::doStart(NodeState::StartLevel startLevel){ SignalHeader sh; memset(&sh, 0, sizeof(SignalHeader)); sh.theVerId_signalNumber = GSN_START_ORD; sh.theReceiversBlockNumber = CMVMI; sh.theSendersBlockRef = 0; sh.theTrace = 0; sh.theSignalId = 0; sh.theLength = StartOrd::SignalLength; Uint32 theData[25]; StartOrd * const startOrd = (StartOrd *)&theData[0]; startOrd->restartInfo = 0; Uint32 secPtrI[3]; globalScheduler.execute(&sh, JBA, theData, secPtrI); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -