~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/ndb/src/kernel/vm/TimeQueue.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

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