1 /* Copyright (c) 2003-2005 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 #ifndef FastScheduler_H
17 #define FastScheduler_H
19 #include <VMSignal.hpp>
20 #include <kernel_types.h>
22 #include <SignalLoggerManager.hpp>
23 #include <SimulatedBlock.hpp>
24 #include <ErrorHandlingMacros.hpp>
25 #include <GlobalData.hpp>
26 #include <TransporterDefinitions.hpp>
29 #define MAX_OCCUPANCY 1024
31 #define JBASIZE 1280 // Jobs which have dead lines to meet use this level
32 #define JBBSIZE 4096 // Most jobs use this level
33 #define JBCSIZE 64 // Only used by STTOR and STTORRY currently
34 #define JBDSIZE 4096 // Time Queue uses this level for storage, not supported
45 Uint32 theDataRegister
[25];
54 void newBuffer(int size
);
56 void insert(Signal
* signal
, BlockNumber bnr
, GlobalSignalNumber gsn
);
57 void insert(const SignalHeader
* const sh
, const Uint32
* const theData
, const Uint32 secPtrI
[3]);
58 void insert(Signal
* signal
, BlockNumber bnr
, GlobalSignalNumber gsn
,
61 Uint32
retrieve(Signal
*signal
);
62 void retrieve(Signal
*signal
, Uint32 myRptr
);
65 * Used when dumping to trace file
67 void retrieveDump(Signal
*signal
, Uint32 myRptr
);
70 Uint32
getOccupancy() const;
72 Uint32
getReadPtr() const;
73 Uint32
getWritePtr() const;
74 Uint32
getBufSize() const;
77 void signal2buffer(Signal
* signal
, BlockNumber bnr
,
78 GlobalSignalNumber gsn
, BufferEntry
& buf
);
97 void activateSendPacked();
99 void execute(Signal
* signal
,
102 GlobalSignalNumber gsn
);
104 void execute(const SignalHeader
* const sh
,
105 Uint8 prio
, const Uint32
* const theData
, const Uint32 secPtr
[3]);
108 Signal
* getVMSignals();
110 void dumpSignalMemory(FILE * output
);
111 Priority
highestAvailablePrio() const;
112 Uint32
getBOccupancy() const;
115 void insertTimeQueue(Signal
* aSignal
, BlockNumber bnr
,
116 GlobalSignalNumber gsn
, Uint32 aIndex
);
117 void scheduleTimeQueue(Uint32 aIndex
);
120 void highestAvailablePrio(Priority prio
);
121 void reportJob(Priority aPriority
);
122 void prio_level_error();
124 Uint32 theDoJobTotalCounter
;
125 Uint32 theDoJobCallCounter
;
126 Uint8 theJobPriority
[4096];
127 APZJobBuffer theJobBuffers
[JB_LEVELS
];
129 void reportDoJobStatistics(Uint32 meanLoopCount
);
134 FastScheduler::getBOccupancy() const {
135 return theJobBuffers
[JBB
].getOccupancy();
136 }//FastScheduler::getBOccupancy()
140 FastScheduler::checkDoJob()
143 * Job buffer overload protetction
144 * If the job buffer B is filled over a certain limit start
145 * to execute the signals in the job buffer's
147 if (getBOccupancy() < MAX_OCCUPANCY
) {
153 }//FastScheduler::checkDoJob()
157 FastScheduler::reportJob(Priority aPriority
)
159 Uint32 tJobCounter
= globalData
.JobCounter
;
160 Uint32 tJobLap
= globalData
.JobLap
;
161 theJobPriority
[tJobCounter
] = (Uint8
)aPriority
;
162 globalData
.JobCounter
= (tJobCounter
+ 1) & 4095;
163 globalData
.JobLap
= tJobLap
+ 1;
168 FastScheduler::highestAvailablePrio() const
170 return (Priority
)globalData
.highestAvailablePrio
;
175 FastScheduler::highestAvailablePrio(Priority prio
)
177 globalData
.highestAvailablePrio
= (Uint32
)prio
;
182 FastScheduler::getVMSignals()
184 return &globalData
.VMSignals
[0];
188 // Inserts of a protocol object into the Job Buffer.
191 FastScheduler::execute(const SignalHeader
* const sh
, Uint8 prio
,
192 const Uint32
* const theData
, const Uint32 secPtrI
[3]){
194 if (prio
>= LEVEL_IDLE
)
198 theJobBuffers
[prio
].insert(sh
, theData
, secPtrI
);
199 if (prio
< (Uint8
)highestAvailablePrio())
200 highestAvailablePrio((Priority
)prio
);
205 FastScheduler::execute(Signal
* signal
, Priority prio
,
206 BlockNumber bnr
, GlobalSignalNumber gsn
)
209 if (prio
>= LEVEL_IDLE
)
212 theJobBuffers
[prio
].insert(signal
, bnr
, gsn
);
213 if (prio
< highestAvailablePrio())
214 highestAvailablePrio(prio
);
219 FastScheduler::insertTimeQueue(Signal
* signal
, BlockNumber bnr
,
220 GlobalSignalNumber gsn
, Uint32 aIndex
)
222 theJobBuffers
[3].insert(signal
, bnr
, gsn
, aIndex
);
227 FastScheduler::scheduleTimeQueue(Uint32 aIndex
)
229 Signal
* signal
= getVMSignals();
230 theJobBuffers
[3].retrieve(signal
, aIndex
);
231 theJobBuffers
[0].insert
233 (BlockNumber
)signal
->header
.theReceiversBlockNumber
,
234 (GlobalSignalNumber
)signal
->header
.theVerId_signalNumber
);
235 if (highestAvailablePrio() > JBA
)
236 highestAvailablePrio(JBA
);
241 APZJobBuffer::getWritePtr() const
248 APZJobBuffer::getReadPtr() const
255 APZJobBuffer::getOccupancy() const
262 APZJobBuffer::getBufSize() const
269 APZJobBuffer::retrieve(Signal
* signal
, Uint32 myRptr
)
271 register BufferEntry
& buf
= buffer
[myRptr
];
273 buf
.header
.theSignalId
= globalData
.theSignalId
++;
275 signal
->header
= buf
.header
;
277 Uint32
*from
= (Uint32
*) &buf
.theDataRegister
[0];
278 Uint32
*to
= (Uint32
*) &signal
->theData
[0];
279 Uint32 noOfWords
= buf
.header
.theLength
;
280 for(; noOfWords
; noOfWords
--)
282 // Copy sections references (copy all without if-statements)
283 SegmentedSectionPtr
* tSecPtr
= &signal
->m_sectionPtr
[0];
284 tSecPtr
[0].i
= from
[0];
285 tSecPtr
[1].i
= from
[1];
286 tSecPtr
[2].i
= from
[2];
292 APZJobBuffer::retrieveDump(Signal
* signal
, Uint32 myRptr
)
295 * Note that signal id is not taken from global data
298 register BufferEntry
& buf
= buffer
[myRptr
];
299 signal
->header
= buf
.header
;
301 Uint32
*from
= (Uint32
*) &buf
.theDataRegister
[0];
302 Uint32
*to
= (Uint32
*) &signal
->theData
[0];
303 Uint32 noOfWords
= buf
.header
.theLength
;
304 for(; noOfWords
; noOfWords
--)
311 APZJobBuffer::insert(Signal
* signal
,
312 BlockNumber bnr
, GlobalSignalNumber gsn
)
314 Uint32 tOccupancy
= theOccupancy
+ 1;
315 Uint32 myWPtr
= wPtr
;
316 if (tOccupancy
< bufSize
) {
317 register BufferEntry
& buf
= buffer
[myWPtr
];
318 Uint32 cond
= (++myWPtr
== bufSize
) - 1;
319 wPtr
= myWPtr
& cond
;
320 theOccupancy
= tOccupancy
;
321 signal2buffer(signal
, bnr
, gsn
, buf
);
322 //---------------------------------------------------------
323 // Prefetch of buffer[wPtr] is done here. We prefetch for
324 // write both the first cache line and the next 64 byte
326 //---------------------------------------------------------
327 WRITEHINT((void*)&buffer
[wPtr
]);
328 WRITEHINT((void*)(((char*)&buffer
[wPtr
]) + 64));
337 APZJobBuffer::insert(Signal
* signal
, BlockNumber bnr
,
338 GlobalSignalNumber gsn
, Uint32 myWPtr
)
340 register BufferEntry
& buf
= buffer
[myWPtr
];
341 signal2buffer(signal
, bnr
, gsn
, buf
);