TimeQueue.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 "TimeQueue.hpp"
  14. #include <ErrorHandlingMacros.hpp>
  15. #include <GlobalData.hpp>
  16. #include <FastScheduler.hpp>
  17. #include <VMSignal.hpp>
  18. #include <Error.hpp>
  19. static const int MAX_TIME_QUEUE_VALUE = 32000;
  20. TimeQueue::TimeQueue()
  21. {
  22.   clear();
  23. }
  24. TimeQueue::~TimeQueue()
  25. {
  26. }
  27. void 
  28. TimeQueue::clear()
  29. {
  30.   globalData.theNextTimerJob = 65535;
  31.   globalData.theCurrentTimer = 0;
  32.   globalData.theShortTQIndex = 0;
  33.   globalData.theLongTQIndex = 0;
  34.   for (int i = 0; i < MAX_NO_OF_TQ; i++)
  35.     theFreeIndex[i] = i+1;
  36.   theFreeIndex[MAX_NO_OF_TQ - 1] = NULL_TQ_ENTRY;
  37.   globalData.theFirstFreeTQIndex = 0;
  38. }
  39. void 
  40. TimeQueue::insert(Signal* signal, BlockNumber bnr, 
  41.   GlobalSignalNumber gsn, Uint32 delayTime)
  42. {
  43.   if (delayTime == 0)
  44.     delayTime = 1;
  45.   register Uint32 regCurrentTime = globalData.theCurrentTimer;
  46.   register Uint32 i;
  47.   register Uint32 regSave;
  48.   register TimerEntry newEntry;
  49.   
  50.   newEntry.time_struct.delay_time = regCurrentTime + delayTime;
  51.   newEntry.time_struct.job_index = getIndex();
  52.   regSave = newEntry.copy_struct;
  53.   
  54.   globalScheduler.insertTimeQueue(signal, bnr, gsn, 
  55.   newEntry.time_struct.job_index);
  56.   
  57.   if (newEntry.time_struct.delay_time < globalData.theNextTimerJob)
  58.     globalData.theNextTimerJob = newEntry.time_struct.delay_time;
  59.   if (delayTime < 100){
  60.     register Uint32 regShortIndex = globalData.theShortTQIndex;
  61.     if (regShortIndex == 0){
  62.       theShortQueue[0].copy_struct = newEntry.copy_struct;
  63.     } else if (regShortIndex >= MAX_NO_OF_SHORT_TQ - 1) {
  64.       ERROR_SET(ecError, ERROR_TIME_QUEUE_SHORT, 
  65. "Too many in Short Time Queue", "TimeQueue.C" );
  66.     } else {
  67.       for (i = 0; i < regShortIndex; i++) {
  68.         if (theShortQueue[i].time_struct.delay_time > 
  69.     newEntry.time_struct.delay_time)  {
  70.   
  71.           regSave = theShortQueue[i].copy_struct;
  72.           theShortQueue[i].copy_struct = newEntry.copy_struct;
  73.           break;
  74. }
  75.       }
  76.       if (i == regShortIndex) {
  77.         theShortQueue[regShortIndex].copy_struct = regSave;
  78.       } else {
  79.         for (i++; i < regShortIndex; i++) {
  80.   register Uint32 regTmp = theShortQueue[i].copy_struct;
  81.   theShortQueue[i].copy_struct = regSave;
  82.   regSave = regTmp;
  83.         }
  84.         theShortQueue[regShortIndex].copy_struct = regSave;
  85.       }
  86.     }
  87.     globalData.theShortTQIndex = regShortIndex + 1;
  88.   } else if (delayTime <= (unsigned)MAX_TIME_QUEUE_VALUE) {
  89.     register Uint32 regLongIndex = globalData.theLongTQIndex;
  90.     if (regLongIndex == 0) {
  91.       theLongQueue[0].copy_struct = newEntry.copy_struct;
  92.     } else if (regLongIndex >= MAX_NO_OF_LONG_TQ - 1) {
  93.       ERROR_SET(ecError, ERROR_TIME_QUEUE_LONG, 
  94. "Too many in Long Time Queue", "TimeQueue.C" );
  95.     } else {
  96.       for (i = 0; i < regLongIndex; i++) {
  97.         if (theLongQueue[i].time_struct.delay_time > 
  98.     newEntry.time_struct.delay_time) {
  99.   
  100.           regSave = theLongQueue[i].copy_struct;
  101.           theLongQueue[i].copy_struct = newEntry.copy_struct;
  102.           break;
  103.         }
  104.       }
  105.       if (i == regLongIndex) {
  106.         theLongQueue[regLongIndex].copy_struct = regSave;
  107.       } else {
  108.         for (i++; i < regLongIndex; i++) {
  109.           register Uint32 regTmp = theLongQueue[i].copy_struct;
  110.           theLongQueue[i].copy_struct = regSave;
  111.           regSave = regTmp;
  112.         }
  113.         theLongQueue[regLongIndex].copy_struct = regSave;
  114.       }
  115.     }
  116.     globalData.theLongTQIndex = regLongIndex + 1;
  117.   } else {
  118.     ERROR_SET(ecError, ERROR_TIME_QUEUE_DELAY, 
  119.       "Too long delay for Time Queue", "TimeQueue.C" );
  120.   }
  121. }
  122. // executes the expired signals;
  123. void
  124. TimeQueue::scanTable()
  125. {
  126.   register Uint32 i, j;
  127.   
  128.   globalData.theCurrentTimer++;
  129.   if (globalData.theCurrentTimer == 32000)
  130.     recount_timers();
  131.   if (globalData.theNextTimerJob > globalData.theCurrentTimer)
  132.     return;
  133.   globalData.theNextTimerJob = 65535; // If no more timer jobs
  134.   for (i = 0; i < globalData.theShortTQIndex; i++) {
  135.     if (theShortQueue[i].time_struct.delay_time > globalData.theCurrentTimer){
  136.       break;
  137.     } else {
  138.       releaseIndex((Uint32)theShortQueue[i].time_struct.job_index);
  139.       globalScheduler.scheduleTimeQueue(theShortQueue[i].time_struct.job_index);
  140.     }
  141.   }
  142.   if (i > 0) {
  143.     for (j = i; j < globalData.theShortTQIndex; j++)
  144.       theShortQueue[j - i].copy_struct = theShortQueue[j].copy_struct;
  145.     globalData.theShortTQIndex -= i;
  146.   }
  147.   if (globalData.theShortTQIndex != 0) // If not empty
  148.     globalData.theNextTimerJob = theShortQueue[0].time_struct.delay_time;
  149.   for (i = 0; i < globalData.theLongTQIndex; i++) {
  150.     if (theLongQueue[i].time_struct.delay_time > globalData.theCurrentTimer) {
  151.       break;
  152.     } else {
  153.       releaseIndex((Uint32)theLongQueue[i].time_struct.job_index);
  154.       globalScheduler.scheduleTimeQueue(theLongQueue[i].time_struct.job_index);
  155.     }
  156.   }
  157.   if (i > 0) {
  158.     for (j = i; j < globalData.theLongTQIndex; j++)
  159.       theLongQueue[j - i].copy_struct = theLongQueue[j].copy_struct;
  160.     globalData.theLongTQIndex -= i;
  161.   }  
  162.   if (globalData.theLongTQIndex != 0) // If not empty
  163.     if (globalData.theNextTimerJob > theLongQueue[0].time_struct.delay_time)
  164.       globalData.theNextTimerJob = theLongQueue[0].time_struct.delay_time;
  165. }
  166. void
  167. TimeQueue::recount_timers()
  168. {
  169.   Uint32 i;
  170.   globalData.theCurrentTimer = 0;
  171.   globalData.theNextTimerJob -= 32000;
  172.   for (i = 0; i < globalData.theShortTQIndex; i++)
  173.     theShortQueue[i].time_struct.delay_time -= 32000;
  174.   for (i = 0; i < globalData.theLongTQIndex; i++)
  175.     theLongQueue[i].time_struct.delay_time -= 32000;
  176. }
  177. Uint32
  178. TimeQueue::getIndex()
  179. {
  180.   Uint32 retValue = globalData.theFirstFreeTQIndex;
  181.   globalData.theFirstFreeTQIndex = (Uint32)theFreeIndex[retValue];
  182.   if (retValue >= MAX_NO_OF_TQ)
  183.     ERROR_SET(fatal, ERROR_TIME_QUEUE_INDEX, 
  184.       "Index out of range", "TimeQueue.C" );
  185.   return retValue;
  186. }
  187. void
  188. TimeQueue::releaseIndex(Uint32 aIndex)
  189. {
  190.   theFreeIndex[aIndex] = globalData.theFirstFreeTQIndex;
  191.   globalData.theFirstFreeTQIndex = aIndex;
  192. }