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

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. #ifndef FastScheduler_H
  14. #define FastScheduler_H
  15. #include <VMSignal.hpp>
  16. #include <kernel_types.h>
  17. #include <Prio.hpp>
  18. #include <SignalLoggerManager.hpp>
  19. #include <SimulatedBlock.hpp>
  20. #include <ErrorHandlingMacros.hpp>
  21. #include <GlobalData.hpp>
  22. #include <TransporterDefinitions.hpp>
  23. #include <prefetch.h>
  24. #define MAX_OCCUPANCY 1024
  25. #define JBASIZE   1280 // Jobs which have dead lines to meet use this level
  26. #define JBBSIZE   4096 // Most jobs use this level
  27. #define JBCSIZE   64   // Only used by STTOR and STTORRY currently
  28. #define JBDSIZE   4096 // Time Queue uses this level for storage, not supported
  29.                        // as priority level
  30. void bnr_error();
  31. void jbuf_error();
  32. class Signal;
  33. class Block;
  34. class BufferEntry
  35. {
  36. public:
  37.   SignalHeader header;
  38.   Uint32 theDataRegister[25];
  39. };
  40. class APZJobBuffer
  41. {
  42. public:
  43.   APZJobBuffer();
  44.   ~APZJobBuffer();
  45.   void newBuffer(int size);
  46.   
  47.   void insert(Signal* signal, BlockNumber bnr, GlobalSignalNumber gsn);   
  48.   void insert(const SignalHeader * const sh, const Uint32 * const theData, const Uint32 secPtrI[3]);
  49.   void insert(Signal* signal, BlockNumber bnr, GlobalSignalNumber gsn, 
  50.       Uint32 myWPtr);   
  51.   
  52.   Uint32 retrieve(Signal *signal);
  53.   void retrieve(Signal *signal, Uint32 myRptr);
  54.   
  55.   /**
  56.    * Used when dumping to trace file
  57.    */
  58.   void retrieveDump(Signal *signal, Uint32 myRptr);
  59.   
  60.   void clear();
  61.   Uint32 getOccupancy() const;
  62.   
  63.   Uint32 getReadPtr() const;
  64.   Uint32 getWritePtr() const;
  65.   Uint32 getBufSize() const;
  66.   
  67. private:
  68.   void signal2buffer(Signal* signal, BlockNumber bnr,
  69.      GlobalSignalNumber gsn, BufferEntry& buf);
  70.   Uint32 rPtr;
  71.   Uint32 wPtr;
  72.   Uint32 theOccupancy;
  73.   Uint32 bufSize;
  74.   BufferEntry* buffer;
  75.   BufferEntry* memRef;
  76. };
  77. class FastScheduler
  78. {
  79. public:
  80.    FastScheduler();
  81.    ~FastScheduler();
  82.   void doJob();
  83.   int checkDoJob();
  84.   void activateSendPacked();
  85.   
  86.   void execute(Signal* signal, 
  87.        Priority prio,
  88.        BlockNumber bnr, 
  89.        GlobalSignalNumber gsn);
  90.   
  91.   void execute(const SignalHeader * const sh, 
  92.        Uint8 prio, const Uint32 * const theData, const Uint32 secPtr[3]);
  93.   
  94.   void clear();
  95.   Signal* getVMSignals();
  96.   
  97.   void dumpSignalMemory(FILE * output);
  98.   Priority highestAvailablePrio() const;
  99.   Uint32 getBOccupancy() const;
  100.   void sendPacked();
  101.   
  102.   void insertTimeQueue(Signal* aSignal, BlockNumber bnr,
  103.        GlobalSignalNumber gsn, Uint32 aIndex);
  104.   void scheduleTimeQueue(Uint32 aIndex);
  105.   
  106. private:
  107.   void highestAvailablePrio(Priority prio);
  108.   void reportJob(Priority aPriority);
  109.   void prio_level_error();
  110.   Uint32 theDoJobTotalCounter;
  111.   Uint32 theDoJobCallCounter;
  112.   Uint8 theJobPriority[4096];
  113.   APZJobBuffer theJobBuffers[JB_LEVELS];
  114.   void reportDoJobStatistics(Uint32 meanLoopCount);
  115. };
  116. inline 
  117. Uint32 
  118. FastScheduler::getBOccupancy() const {
  119.   return theJobBuffers[JBB].getOccupancy();
  120. }//FastScheduler::getBOccupancy()
  121. inline 
  122. int 
  123. FastScheduler::checkDoJob()
  124. {
  125.   /* 
  126.    * Job buffer overload protetction 
  127.    * If the job buffer B is filled over a certain limit start
  128.    * to execute the signals in the job buffer's
  129.    */
  130.   if (getBOccupancy() < MAX_OCCUPANCY) {
  131.     return 0;
  132.   } else {
  133.     doJob();
  134.     return 1;
  135.   }//if
  136. }//FastScheduler::checkDoJob()
  137. inline 
  138. void 
  139. FastScheduler::reportJob(Priority aPriority)
  140. {
  141.   Uint32 tJobCounter = globalData.JobCounter;
  142.   Uint32 tJobLap = globalData.JobLap;
  143.   theJobPriority[tJobCounter] = (Uint8)aPriority;
  144.   globalData.JobCounter = (tJobCounter + 1) & 4095;
  145.   globalData.JobLap = tJobLap + 1;
  146. }
  147. inline 
  148. Priority 
  149. FastScheduler::highestAvailablePrio() const
  150. {
  151.    return (Priority)globalData.highestAvailablePrio;
  152. }
  153. inline 
  154. void 
  155. FastScheduler::highestAvailablePrio(Priority prio)
  156. {
  157.    globalData.highestAvailablePrio = (Uint32)prio;
  158. }
  159. inline 
  160. Signal* 
  161. FastScheduler::getVMSignals()
  162. {
  163.   return &globalData.VMSignals[0];
  164. }
  165. // Inserts of a protocol object into the Job Buffer.
  166. inline
  167. void
  168. FastScheduler::execute(const SignalHeader * const sh, Uint8 prio, 
  169.        const Uint32 * const theData, const Uint32 secPtrI[3]){
  170. #ifdef VM_TRACE
  171.   if (prio >= LEVEL_IDLE)
  172.     prio_level_error();
  173. #endif
  174.   
  175.   theJobBuffers[prio].insert(sh, theData, secPtrI);
  176.   if (prio < (Uint8)highestAvailablePrio())
  177.     highestAvailablePrio((Priority)prio);
  178. }
  179. inline 
  180. void 
  181. FastScheduler::execute(Signal* signal, Priority prio,
  182.        BlockNumber bnr, GlobalSignalNumber gsn)
  183. {
  184. #ifdef VM_TRACE
  185.   if (prio >= LEVEL_IDLE)
  186.     prio_level_error();
  187. #endif
  188.   theJobBuffers[prio].insert(signal, bnr, gsn);
  189.   if (prio < highestAvailablePrio())
  190.     highestAvailablePrio(prio);
  191. }
  192. inline 
  193. void 
  194. FastScheduler::insertTimeQueue(Signal* signal, BlockNumber bnr,
  195.        GlobalSignalNumber gsn, Uint32 aIndex)
  196. {
  197.   theJobBuffers[3].insert(signal, bnr, gsn, aIndex);
  198. }
  199. inline 
  200. void 
  201. FastScheduler::scheduleTimeQueue(Uint32 aIndex)
  202. {
  203.   Signal* signal = getVMSignals();
  204.   theJobBuffers[3].retrieve(signal, aIndex);
  205.   theJobBuffers[0].insert
  206.     (signal,
  207.      (BlockNumber)signal->header.theReceiversBlockNumber,
  208.      (GlobalSignalNumber)signal->header.theVerId_signalNumber);
  209.   if (highestAvailablePrio() > JBA)
  210.     highestAvailablePrio(JBA);
  211. }
  212. inline
  213. Uint32
  214. APZJobBuffer::getWritePtr() const
  215. {
  216.   return wPtr;
  217. }
  218. inline 
  219. Uint32 
  220. APZJobBuffer::getReadPtr() const
  221. {
  222.   return rPtr;
  223. }
  224. inline 
  225. Uint32 
  226. APZJobBuffer::getOccupancy() const 
  227. {
  228.   return theOccupancy;
  229. }
  230. inline 
  231. Uint32 
  232. APZJobBuffer::getBufSize() const
  233. {
  234.   return bufSize;
  235. }
  236. inline
  237. void
  238. APZJobBuffer::retrieve(Signal* signal, Uint32 myRptr)
  239. {              
  240.   register BufferEntry& buf = buffer[myRptr];
  241.   
  242.   buf.header.theSignalId = globalData.theSignalId++;
  243.   signal->header = buf.header;
  244.   
  245.   Uint32 *from = (Uint32*) &buf.theDataRegister[0];
  246.   Uint32 *to   = (Uint32*) &signal->theData[0];
  247.   Uint32 noOfWords = buf.header.theLength;
  248.   for(; noOfWords; noOfWords--)
  249.     *to++ = *from++;
  250.   // Copy sections references (copy all without if-statements)
  251.   SegmentedSectionPtr * tSecPtr = &signal->m_sectionPtr[0];
  252.   tSecPtr[0].i = from[0];
  253.   tSecPtr[1].i = from[1];
  254.   tSecPtr[2].i = from[2];
  255.   return;
  256. }
  257. inline
  258. void
  259. APZJobBuffer::retrieveDump(Signal* signal, Uint32 myRptr)
  260. {              
  261.   /**
  262.    * Note that signal id is not taken from global data
  263.    */
  264.   
  265.   register BufferEntry& buf = buffer[myRptr];
  266.   signal->header = buf.header;
  267.   
  268.   Uint32 *from = (Uint32*) &buf.theDataRegister[0];
  269.   Uint32 *to   = (Uint32*) &signal->theData[0];
  270.   Uint32 noOfWords = buf.header.theLength;
  271.   for(; noOfWords; noOfWords--)
  272.     *to++ = *from++;
  273.   return;
  274. }
  275. inline
  276. void 
  277. APZJobBuffer::insert(Signal* signal,
  278.      BlockNumber bnr, GlobalSignalNumber gsn)
  279. {
  280.   Uint32 tOccupancy = theOccupancy + 1;
  281.   Uint32 myWPtr = wPtr;
  282.   if (tOccupancy < bufSize) {
  283.     register BufferEntry& buf = buffer[myWPtr];
  284.     Uint32 cond =  (++myWPtr == bufSize) - 1;
  285.     wPtr = myWPtr & cond;
  286.     theOccupancy = tOccupancy;
  287.     signal2buffer(signal, bnr, gsn, buf);
  288.     //---------------------------------------------------------
  289.     // Prefetch of buffer[wPtr] is done here. We prefetch for
  290.     // write both the first cache line and the next 64 byte
  291.     // entry
  292.     //---------------------------------------------------------
  293.     WRITEHINT((void*)&buffer[wPtr]);
  294.     WRITEHINT((void*)(((char*)&buffer[wPtr]) + 64));
  295.   } else {
  296.     jbuf_error();
  297.   }//if
  298. }
  299. inline
  300. void
  301. APZJobBuffer::insert(Signal* signal, BlockNumber bnr,
  302.      GlobalSignalNumber gsn, Uint32 myWPtr)
  303. {
  304.   register BufferEntry& buf = buffer[myWPtr];
  305.   signal2buffer(signal, bnr, gsn, buf);
  306. }
  307. #endif