ThreadConfig.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:7k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include "ThreadConfig.hpp"
  14. #include "Emulator.hpp"
  15. #include "GlobalData.hpp"
  16. #include "TimeQueue.hpp"
  17. #include "TransporterRegistry.hpp"
  18. #include "FastScheduler.hpp"
  19. #include "pc.hpp"
  20. #include <GlobalSignalNumbers.h>
  21. #include <BlockNumbers.h>
  22. #include <NdbSleep.h>
  23. #include <NdbTick.h>
  24. #include <NdbOut.hpp>
  25. #include <signaldata/StartOrd.hpp>
  26. ThreadConfig::ThreadConfig()
  27. {
  28. }
  29. ThreadConfig::~ThreadConfig()
  30. {
  31. }
  32. /**
  33.  * For each millisecond that has passed since this function was last called:
  34.  *   Scan the job buffer and increment the internalMillisecCounter 
  35.  *      with 1 to keep track of where we are
  36.  */
  37. inline
  38. void 
  39. ThreadConfig::scanTimeQueue()
  40. {
  41.   unsigned int maxCounter;
  42.   Uint64 currMilliSecond;
  43.   maxCounter = 0;
  44.   currMilliSecond = NdbTick_CurrentMillisecond();
  45.   if (currMilliSecond < globalData.internalMillisecCounter) {
  46. //--------------------------------------------------------------------
  47. // This could occur around 2036 or if the operator decides to change
  48. // time backwards. We cannot know how long time has past since last
  49. // time and we make a best try with 0 milliseconds.
  50. //--------------------------------------------------------------------
  51. #ifdef VM_TRACE
  52.     ndbout << "Time moved backwards with ";
  53.     ndbout << (globalData.internalMillisecCounter - currMilliSecond);
  54.     ndbout << " milliseconds" << endl;
  55. #endif
  56.     globalData.internalMillisecCounter = currMilliSecond;
  57.   }//if
  58.   if (currMilliSecond > (globalData.internalMillisecCounter + 1500)) {
  59. //--------------------------------------------------------------------
  60. // Time has moved forward more than a second. Either it could happen
  61. // if operator changed the time or if the OS has misbehaved badly.
  62. // We set the new time to one second from the past.
  63. //--------------------------------------------------------------------
  64. #ifdef VM_TRACE
  65.     ndbout << "Time moved forward with ";
  66.     ndbout << (currMilliSecond - globalData.internalMillisecCounter);
  67.     ndbout << " milliseconds" << endl;
  68. #endif
  69.     globalData.internalMillisecCounter = currMilliSecond - 1000;
  70.   }//if
  71.   while (((currMilliSecond - globalData.internalMillisecCounter) > 0) &&
  72.          (maxCounter < 20)){
  73.     globalData.internalMillisecCounter++;
  74.     maxCounter++;
  75.     globalTimeQueue.scanTable();
  76.   }//while
  77. }//ThreadConfig::scanTimeQueue()
  78. //--------------------------------------------------------------------
  79. // ipControlLoop -- The main loop of ndb.
  80. // Handles the scheduling of signal execution and input/output
  81. // One lap in the loop should take approximately 10 milli seconds
  82. // If the jobbuffer is empty and the laptime is less than 10 milliseconds
  83. // at the end of the loop
  84. // the TransporterRegistry is called in order to sleep on the IO ports
  85. // waiting for another incoming signal to wake us up.
  86. // The timeout value in this call is calculated as (10 ms - laptime)
  87. // This would make ndb use less cpu while improving response time.
  88. //--------------------------------------------------------------------
  89. void ThreadConfig::ipControlLoop()
  90. {
  91. #if defined NDB_OSE || defined NDB_SOFTOSE
  92. //--------------------------------------------------------------------
  93. // To let the Cello Watchdog do it's work NDB must sleep a short 
  94. // period every 10 minutes. If this is not done, the watchdog will 
  95. // reboot the board NDB is running on when the load is high. 
  96. //--------------------------------------------------------------------
  97.   int loopCounter = 0;
  98. #endif
  99. //--------------------------------------------------------------------
  100. // initialise the counter that keeps track of the current millisecond
  101. //--------------------------------------------------------------------
  102.   globalData.internalMillisecCounter = NdbTick_CurrentMillisecond();
  103.   Uint32 i = 0;
  104.   while (globalData.theRestartFlag != perform_stop)  { 
  105. #if defined NDB_OSE || defined NDB_SOFTOSE
  106.     loopCounter++;
  107.     if(loopCounter > 1000){
  108. //--------------------------------------------------------------------
  109. // This is done to allow OSE do a context switch to let the watchdog 
  110. // do it's stuff.
  111. //--------------------------------------------------------------------
  112.       NdbSleep_MilliSleep(1);
  113.       loopCounter = 0;
  114.     }
  115. #endif
  116.     Uint32 timeOutMillis = 0;
  117.     if (LEVEL_IDLE == globalData.highestAvailablePrio) {
  118. //--------------------------------------------------------------------
  119. // The buffers are empty, we need to wait for a while until we continue.
  120. // We cannot wait forever since we can also have timed events.
  121. //--------------------------------------------------------------------
  122. //--------------------------------------------------------------------
  123. // Set the time we will sleep on the sockets before waking up
  124. // unconditionally to 10 ms. Will never sleep more than 10 milliseconds
  125. // on a socket.
  126. //--------------------------------------------------------------------
  127.       timeOutMillis = 10;
  128.     }//if
  129. //--------------------------------------------------------------------
  130. // Now it is time to check all interfaces. We will send all buffers
  131. // plus checking for any received messages.
  132. //--------------------------------------------------------------------
  133.     if (i++ >= 20) {
  134.       globalTransporterRegistry.update_connections();
  135.       globalData.incrementWatchDogCounter(5);
  136.       i = 0;
  137.     }//if
  138.     globalData.incrementWatchDogCounter(6);
  139.     globalTransporterRegistry.performSend();
  140.     
  141.     globalData.incrementWatchDogCounter(7);
  142.     if (globalTransporterRegistry.pollReceive(timeOutMillis)) {
  143.       globalData.incrementWatchDogCounter(8);
  144.       globalTransporterRegistry.performReceive();
  145.     }
  146. //--------------------------------------------------------------------
  147. // We scan the time queue to see if there are any timed signals that
  148. // is now ready to be executed.
  149. //--------------------------------------------------------------------
  150.     globalData.incrementWatchDogCounter(2);
  151.     scanTimeQueue(); 
  152. //--------------------------------------------------------------------
  153. // This is where the actual execution of signals occur. We execute
  154. // until all buffers are empty or until we have executed 2048 signals.
  155. //--------------------------------------------------------------------
  156.     globalScheduler.doJob();
  157.   }//while
  158.   globalData.incrementWatchDogCounter(6);
  159.   globalTransporterRegistry.performSend();
  160. }//ThreadConfig::ipControlLoop()
  161. int
  162. ThreadConfig::doStart(NodeState::StartLevel startLevel){
  163.   
  164.   SignalHeader sh;
  165.   memset(&sh, 0, sizeof(SignalHeader));
  166.   
  167.   sh.theVerId_signalNumber   = GSN_START_ORD;
  168.   sh.theReceiversBlockNumber = CMVMI;
  169.   sh.theSendersBlockRef      = 0;
  170.   sh.theTrace                = 0;
  171.   sh.theSignalId             = 0;
  172.   sh.theLength               = StartOrd::SignalLength;
  173.   
  174.   Uint32 theData[25];
  175.   StartOrd * const  startOrd = (StartOrd *)&theData[0];
  176.   startOrd->restartInfo = 0;
  177.   
  178.   Uint32 secPtrI[3];
  179.   globalScheduler.execute(&sh, JBA, theData, secPtrI);
  180.   return 0;
  181. }