18 #ifndef FastScheduler_H
19 #define FastScheduler_H
21 #include <VMSignal.hpp>
22 #include <kernel_types.h>
24 #include <SignalLoggerManager.hpp>
25 #include <SimulatedBlock.hpp>
26 #include <ErrorHandlingMacros.hpp>
27 #include <GlobalData.hpp>
28 #include <TransporterDefinitions.hpp>
29 #include <portlib/ndb_prefetch.h>
31 #define MAX_OCCUPANCY 1024
33 #define JBASIZE 1280 // Jobs which have dead lines to meet use this level
34 #define JBBSIZE 4096 // Most jobs use this level
35 #define JBCSIZE 64 // Only used by STTOR and STTORRY currently
36 #define JBDSIZE 4096 // Time Queue uses this level for storage, not supported
47 Uint32 theDataRegister[25];
56 void newBuffer(
int size);
58 void insert(
Signal* signal, BlockNumber bnr, GlobalSignalNumber gsn);
59 void insert(
const SignalHeader *
const sh,
const Uint32 *
const theData,
const Uint32 secPtrI[3]);
60 void insert(
Signal* signal, BlockNumber bnr, GlobalSignalNumber gsn,
63 Uint32 retrieve(
Signal *signal);
64 void retrieve(
Signal *signal, Uint32 myRptr);
72 Uint32 getOccupancy()
const;
74 Uint32 getReadPtr()
const;
75 Uint32 getWritePtr()
const;
76 Uint32 getBufSize()
const;
79 void signal2buffer(
Signal* signal, BlockNumber bnr,
100 void activateSendPacked();
102 void execute(
Signal* signal,
105 GlobalSignalNumber gsn);
108 Uint8 prio,
const Uint32 *
const theData,
const Uint32 secPtr[3]);
113 Priority highestAvailablePrio()
const;
114 Uint32 getBOccupancy()
const;
117 void insertTimeQueue(
Signal* aSignal, BlockNumber bnr,
118 GlobalSignalNumber gsn, Uint32 aIndex);
119 void scheduleTimeQueue(Uint32 aIndex);
127 void traceDumpPrepare(NdbShutdownType&);
129 Uint32 traceDumpGetNumThreads();
131 int traceDumpGetCurrentThread();
134 bool traceDumpGetJam(Uint32 thr_no, Uint32 & jamBlockNumber,
135 const Uint32 * & thrdTheEmulatedJam,
136 Uint32 & thrdTheEmulatedJamIndex);
138 void dumpSignalMemory(Uint32 thr_no, FILE * output);
140 void reportThreadConfigLoop(Uint32 expired_time, Uint32 extra_constant,
141 Uint32 *no_exec_loops, Uint32 *tot_exec_time,
142 Uint32 *no_extra_loops, Uint32 *tot_extra_time);
145 void highestAvailablePrio(Priority prio);
146 void reportJob(Priority aPriority);
147 void prio_level_error();
149 Uint32 theDoJobTotalCounter;
150 Uint32 theDoJobCallCounter;
151 Uint8 theJobPriority[4096];
154 void reportDoJobStatistics(Uint32 meanLoopCount);
159 FastScheduler::getBOccupancy()
const {
160 return theJobBuffers[JBB].getOccupancy();
165 FastScheduler::checkDoJob()
172 if (getBOccupancy() < MAX_OCCUPANCY) {
182 FastScheduler::reportJob(Priority aPriority)
184 Uint32 tJobCounter = globalData.JobCounter;
185 Uint64 tJobLap = globalData.JobLap;
186 theJobPriority[tJobCounter] = (Uint8)aPriority;
187 globalData.JobCounter = (tJobCounter + 1) & 4095;
188 globalData.JobLap = tJobLap + 1;
193 FastScheduler::highestAvailablePrio()
const
195 return (Priority)globalData.highestAvailablePrio;
200 FastScheduler::highestAvailablePrio(Priority prio)
202 globalData.highestAvailablePrio = (Uint32)prio;
207 FastScheduler::getVMSignals()
209 return &globalData.VMSignals[0];
216 FastScheduler::execute(
const SignalHeader *
const sh, Uint8 prio,
217 const Uint32 *
const theData,
const Uint32 secPtrI[3]){
219 if (prio >= LEVEL_IDLE)
223 theJobBuffers[prio].insert(sh, theData, secPtrI);
224 if (prio < (Uint8)highestAvailablePrio())
225 highestAvailablePrio((Priority)prio);
230 FastScheduler::execute(
Signal* signal, Priority prio,
231 BlockNumber bnr, GlobalSignalNumber gsn)
234 if (prio >= LEVEL_IDLE)
237 theJobBuffers[prio].insert(signal, bnr, gsn);
238 if (prio < highestAvailablePrio())
239 highestAvailablePrio(prio);
244 FastScheduler::insertTimeQueue(
Signal* signal, BlockNumber bnr,
245 GlobalSignalNumber gsn, Uint32 aIndex)
247 theJobBuffers[3].insert(signal, bnr, gsn, aIndex);
252 FastScheduler::scheduleTimeQueue(Uint32 aIndex)
254 Signal* signal = getVMSignals();
255 theJobBuffers[3].retrieve(signal, aIndex);
256 theJobBuffers[0].insert
258 (BlockNumber)signal->header.theReceiversBlockNumber,
259 (GlobalSignalNumber)signal->header.theVerId_signalNumber);
260 if (highestAvailablePrio() > JBA)
261 highestAvailablePrio(JBA);
263 signal->header.m_noOfSections = 0;
268 APZJobBuffer::getWritePtr()
const
275 APZJobBuffer::getReadPtr()
const
282 APZJobBuffer::getOccupancy()
const
289 APZJobBuffer::getBufSize()
const
296 APZJobBuffer::retrieve(
Signal* signal, Uint32 myRptr)
300 buf.header.theSignalId = globalData.theSignalId++;
302 signal->header = buf.header;
304 Uint32 *from = (Uint32*) &buf.theDataRegister[0];
305 Uint32 *
to = (Uint32*) &signal->theData[0];
306 Uint32 noOfWords = buf.header.theLength + buf.header.m_noOfSections;
307 for(; noOfWords; noOfWords--)
322 signal->header = buf.header;
324 Uint32 *from = (Uint32*) &buf.theDataRegister[0];
325 Uint32 *
to = (Uint32*) &signal->theData[0];
326 Uint32 noOfWords = buf.header.theLength;
327 for(; noOfWords; noOfWords--)
334 APZJobBuffer::insert(
Signal* signal,
335 BlockNumber bnr, GlobalSignalNumber gsn)
337 Uint32 tOccupancy = theOccupancy + 1;
338 Uint32 myWPtr = wPtr;
339 if (tOccupancy < bufSize) {
341 Uint32 cond = (++myWPtr == bufSize) - 1;
342 wPtr = myWPtr & cond;
343 theOccupancy = tOccupancy;
344 signal2buffer(signal, bnr, gsn, buf);
350 NDB_PREFETCH_WRITE((
void*)&buffer[wPtr]);
351 NDB_PREFETCH_WRITE((
void*)(((
char*)&buffer[wPtr]) + 64));
360 APZJobBuffer::insert(
Signal* signal, BlockNumber bnr,
361 GlobalSignalNumber gsn, Uint32 myWPtr)
364 signal2buffer(signal, bnr, gsn, buf);