mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / ndb / src / kernel / vm / ThreadConfig.cpp
blob7f7f1bac5836a3b624cca870638d4b93c65b73a9
1 /* Copyright (c) 2003-2006 MySQL AB
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16 #include "ThreadConfig.hpp"
17 #include "Emulator.hpp"
18 #include "GlobalData.hpp"
19 #include "TimeQueue.hpp"
20 #include "TransporterRegistry.hpp"
21 #include "FastScheduler.hpp"
22 #include "pc.hpp"
24 #include <GlobalSignalNumbers.h>
25 #include <BlockNumbers.h>
27 #include <NdbSleep.h>
28 #include <NdbTick.h>
29 #include <NdbOut.hpp>
31 #include <signaldata/StartOrd.hpp>
33 ThreadConfig::ThreadConfig()
37 ThreadConfig::~ThreadConfig()
41 /**
42 * For each millisecond that has passed since this function was last called:
43 * Scan the job buffer and increment the internalMillisecCounter
44 * with 1 to keep track of where we are
46 inline
47 void
48 ThreadConfig::scanTimeQueue()
50 unsigned int maxCounter;
51 Uint64 currMilliSecond;
52 maxCounter = 0;
53 currMilliSecond = NdbTick_CurrentMillisecond();
54 if (currMilliSecond < globalData.internalMillisecCounter) {
55 //--------------------------------------------------------------------
56 // This could occur around 2036 or if the operator decides to change
57 // time backwards. We cannot know how long time has past since last
58 // time and we make a best try with 0 milliseconds.
59 //--------------------------------------------------------------------
60 #ifdef VM_TRACE
61 ndbout << "Time moved backwards with ";
62 ndbout << (globalData.internalMillisecCounter - currMilliSecond);
63 ndbout << " milliseconds" << endl;
64 #endif
65 globalData.internalMillisecCounter = currMilliSecond;
66 }//if
67 if (currMilliSecond > (globalData.internalMillisecCounter + 1500)) {
68 //--------------------------------------------------------------------
69 // Time has moved forward more than a second. Either it could happen
70 // if operator changed the time or if the OS has misbehaved badly.
71 // We set the new time to one second from the past.
72 //--------------------------------------------------------------------
73 #ifdef VM_TRACE
74 ndbout << "Time moved forward with ";
75 ndbout << (currMilliSecond - globalData.internalMillisecCounter);
76 ndbout << " milliseconds" << endl;
77 #endif
78 globalData.internalMillisecCounter = currMilliSecond - 1000;
79 }//if
80 while (((currMilliSecond - globalData.internalMillisecCounter) > 0) &&
81 (maxCounter < 20)){
82 globalData.internalMillisecCounter++;
83 maxCounter++;
84 globalTimeQueue.scanTable();
85 }//while
86 }//ThreadConfig::scanTimeQueue()
89 //--------------------------------------------------------------------
90 // ipControlLoop -- The main loop of ndb.
91 // Handles the scheduling of signal execution and input/output
92 // One lap in the loop should take approximately 10 milli seconds
93 // If the jobbuffer is empty and the laptime is less than 10 milliseconds
94 // at the end of the loop
95 // the TransporterRegistry is called in order to sleep on the IO ports
96 // waiting for another incoming signal to wake us up.
97 // The timeout value in this call is calculated as (10 ms - laptime)
98 // This would make ndb use less cpu while improving response time.
99 //--------------------------------------------------------------------
100 void ThreadConfig::ipControlLoop()
103 //--------------------------------------------------------------------
104 // initialise the counter that keeps track of the current millisecond
105 //--------------------------------------------------------------------
106 globalData.internalMillisecCounter = NdbTick_CurrentMillisecond();
107 Uint32 i = 0;
108 while (globalData.theRestartFlag != perform_stop) {
110 Uint32 timeOutMillis = 0;
111 if (LEVEL_IDLE == globalData.highestAvailablePrio) {
112 //--------------------------------------------------------------------
113 // The buffers are empty, we need to wait for a while until we continue.
114 // We cannot wait forever since we can also have timed events.
115 //--------------------------------------------------------------------
116 //--------------------------------------------------------------------
117 // Set the time we will sleep on the sockets before waking up
118 // unconditionally to 10 ms. Will never sleep more than 10 milliseconds
119 // on a socket.
120 //--------------------------------------------------------------------
121 timeOutMillis = 10;
122 }//if
123 //--------------------------------------------------------------------
124 // Now it is time to check all interfaces. We will send all buffers
125 // plus checking for any received messages.
126 //--------------------------------------------------------------------
127 if (i++ >= 20) {
128 globalTransporterRegistry.update_connections();
129 globalData.incrementWatchDogCounter(5);
130 i = 0;
131 }//if
133 globalData.incrementWatchDogCounter(6);
134 globalTransporterRegistry.performSend();
136 globalData.incrementWatchDogCounter(7);
137 if (globalTransporterRegistry.pollReceive(timeOutMillis)) {
138 globalData.incrementWatchDogCounter(8);
139 globalTransporterRegistry.performReceive();
142 //--------------------------------------------------------------------
143 // We scan the time queue to see if there are any timed signals that
144 // is now ready to be executed.
145 //--------------------------------------------------------------------
146 globalData.incrementWatchDogCounter(2);
147 scanTimeQueue();
149 //--------------------------------------------------------------------
150 // This is where the actual execution of signals occur. We execute
151 // until all buffers are empty or until we have executed 2048 signals.
152 //--------------------------------------------------------------------
153 globalScheduler.doJob();
154 }//while
156 globalData.incrementWatchDogCounter(6);
157 globalTransporterRegistry.performSend();
159 }//ThreadConfig::ipControlLoop()
162 ThreadConfig::doStart(NodeState::StartLevel startLevel){
164 SignalHeader sh;
165 memset(&sh, 0, sizeof(SignalHeader));
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;
174 Uint32 theData[25];
175 StartOrd * const startOrd = (StartOrd *)&theData[0];
176 startOrd->restartInfo = 0;
178 Uint32 secPtrI[3];
179 globalScheduler.execute(&sh, JBA, theData, secPtrI);
180 return 0;