00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "copyright.h"
00010 #include "autoconf.h"
00011 #include "config.h"
00012 #include "externs.h"
00013
00014 #include <signal.h>
00015
00016 #include "command.h"
00017 #include "mguests.h"
00018
00019 CScheduler scheduler;
00020
00021
00022
00023 void dispatch_FreeListReconstruction(void *pUnused, int iUnused)
00024 {
00025 UNUSED_PARAMETER(pUnused);
00026 UNUSED_PARAMETER(iUnused);
00027
00028 if (mudconf.control_flags & CF_DBCHECK)
00029 {
00030 char *cmdsave = mudstate.debug_cmd;
00031 mudstate.debug_cmd = (char *)"< dbck >";
00032 do_dbck(NOTHING, NOTHING, NOTHING, 0);
00033 Guest.CleanUp();
00034 pcache_trim();
00035 pool_reset();
00036 mudstate.debug_cmd = cmdsave;
00037 }
00038
00039
00040
00041 CLinearTimeAbsolute ltaNow;
00042 ltaNow.GetUTC();
00043 CLinearTimeDelta ltd;
00044 ltd.SetSeconds(mudconf.check_interval);
00045 mudstate.check_counter = ltaNow + ltd;
00046 scheduler.DeferTask(mudstate.check_counter, PRIORITY_SYSTEM,
00047 dispatch_FreeListReconstruction, 0, 0);
00048 }
00049
00050
00051
00052 void dispatch_DatabaseDump(void *pUnused, int iUnused)
00053 {
00054 UNUSED_PARAMETER(pUnused);
00055 UNUSED_PARAMETER(iUnused);
00056
00057 int nNextTimeInSeconds = mudconf.dump_interval;
00058
00059 if (mudconf.control_flags & CF_CHECKPOINT)
00060 {
00061 char *cmdsave = mudstate.debug_cmd;
00062 mudstate.debug_cmd = (char *)"< dump >";
00063 #ifndef WIN32
00064 if (mudstate.dumping)
00065 {
00066
00067
00068
00069
00070
00071 nNextTimeInSeconds = 20;
00072 }
00073 else
00074 #endif // !WIN32
00075 {
00076 fork_and_dump(0);
00077 }
00078 mudstate.debug_cmd = cmdsave;
00079 }
00080
00081
00082
00083 CLinearTimeAbsolute ltaNow;
00084 ltaNow.GetUTC();
00085 CLinearTimeDelta ltd;
00086 ltd.SetSeconds(nNextTimeInSeconds);
00087 mudstate.dump_counter = ltaNow + ltd;
00088 scheduler.DeferTask(mudstate.dump_counter, PRIORITY_SYSTEM, dispatch_DatabaseDump, 0, 0);
00089 }
00090
00091
00092
00093 void dispatch_IdleCheck(void *pUnused, int iUnused)
00094 {
00095 UNUSED_PARAMETER(pUnused);
00096 UNUSED_PARAMETER(iUnused);
00097
00098 if (mudconf.control_flags & CF_IDLECHECK)
00099 {
00100 char *cmdsave = mudstate.debug_cmd;
00101 mudstate.debug_cmd = (char *)"< idlecheck >";
00102 check_idle();
00103 mudstate.debug_cmd = cmdsave;
00104 }
00105
00106
00107
00108 CLinearTimeAbsolute ltaNow;
00109 ltaNow.GetUTC();
00110 CLinearTimeDelta ltd;
00111 ltd.SetSeconds(mudconf.idle_interval);
00112 mudstate.idle_counter = ltaNow + ltd;
00113 scheduler.DeferTask(mudstate.idle_counter, PRIORITY_SYSTEM, dispatch_IdleCheck, 0, 0);
00114 }
00115
00116
00117
00118 void dispatch_CheckEvents(void *pUnused, int iUnused)
00119 {
00120 UNUSED_PARAMETER(pUnused);
00121 UNUSED_PARAMETER(iUnused);
00122
00123 if (mudconf.control_flags & CF_EVENTCHECK)
00124 {
00125 char *cmdsave = mudstate.debug_cmd;
00126 mudstate.debug_cmd = (char *)"< eventcheck >";
00127 check_events();
00128 mudstate.debug_cmd = cmdsave;
00129 }
00130
00131
00132
00133 CLinearTimeAbsolute ltaNow;
00134 ltaNow.GetUTC();
00135 CLinearTimeDelta ltd = time_15m;
00136 mudstate.events_counter = ltaNow + ltd;
00137 scheduler.DeferTask(mudstate.events_counter, PRIORITY_SYSTEM, dispatch_CheckEvents, 0, 0);
00138 }
00139
00140 #ifndef MEMORY_BASED
00141 void dispatch_CacheTick(void *pUnused, int iUnused)
00142 {
00143 UNUSED_PARAMETER(pUnused);
00144 UNUSED_PARAMETER(iUnused);
00145
00146 char *cmdsave = mudstate.debug_cmd;
00147 mudstate.debug_cmd = (char *)"< cachetick >";
00148
00149 CLinearTimeDelta ltd = 0;
00150 if (mudconf.cache_tick_period <= ltd)
00151 {
00152 mudconf.cache_tick_period.SetSeconds(1);
00153 }
00154
00155 cache_tick();
00156
00157
00158
00159 CLinearTimeAbsolute ltaNextTime;
00160 ltaNextTime.GetUTC();
00161 ltaNextTime += mudconf.cache_tick_period;
00162 scheduler.DeferTask(ltaNextTime, PRIORITY_SYSTEM, dispatch_CacheTick, 0, 0);
00163 mudstate.debug_cmd = cmdsave;
00164 }
00165 #endif // !MEMORY_BASED
00166
00167 #if 0
00168 void dispatch_CleanChannels(void *pUnused, int iUnused)
00169 {
00170 char *cmdsave = mudstate.debug_cmd;
00171 mudstate.debug_cmd = (char *)"< cleanchannels >";
00172 do_cleanupchannels();
00173
00174
00175
00176 CLinearTimeAbsolute ltaNextTime;
00177 ltaNextTime.GetUTC();
00178 CLinearTimeDelta ltd = time_15m;
00179 ltaNextTime += ltd;
00180 scheduler.DeferTask(ltaNextTime, PRIORITY_SYSTEM, dispatch_CleanChannels, 0, 0);
00181 mudstate.debug_cmd = cmdsave;
00182 }
00183 #endif // 0
00184
00185 static void dispatch_CanRestart(void *pUnused, int iUnused)
00186 {
00187 UNUSED_PARAMETER(pUnused);
00188 UNUSED_PARAMETER(iUnused);
00189 mudstate.bCanRestart = true;
00190 }
00191
00192 #ifdef WIN32
00193 static void dispatch_CalibrateQueryPerformance(void *pUnused, int iUnused)
00194 {
00195 UNUSED_PARAMETER(pUnused);
00196 UNUSED_PARAMETER(iUnused);
00197
00198 CLinearTimeAbsolute ltaNextTime;
00199 ltaNextTime.GetUTC();
00200 CLinearTimeDelta ltd = time_30s;
00201 ltaNextTime += ltd;
00202
00203 if (CalibrateQueryPerformance())
00204 {
00205 scheduler.DeferTask(ltaNextTime, PRIORITY_SYSTEM,
00206 dispatch_CalibrateQueryPerformance, 0, 0);
00207 }
00208 }
00209 #endif // WIN32
00210
00211 void init_timer(void)
00212 {
00213 CLinearTimeAbsolute ltaNow;
00214 ltaNow.GetUTC();
00215
00216
00217
00218 CLinearTimeDelta ltd;
00219 ltd.SetSeconds((mudconf.check_offset == 0) ? mudconf.check_interval : mudconf.check_offset);
00220 mudstate.check_counter = ltaNow + ltd;
00221 scheduler.DeferTask(mudstate.check_counter, PRIORITY_SYSTEM,
00222 dispatch_FreeListReconstruction, 0, 0);
00223
00224
00225
00226 ltd.SetSeconds((mudconf.dump_offset == 0) ? mudconf.dump_interval : mudconf.dump_offset);
00227 mudstate.dump_counter = ltaNow + ltd;
00228 scheduler.DeferTask(mudstate.dump_counter, PRIORITY_SYSTEM,
00229 dispatch_DatabaseDump, 0, 0);
00230
00231
00232
00233 ltd.SetSeconds(mudconf.idle_interval);
00234 mudstate.idle_counter = ltaNow + ltd;
00235 scheduler.DeferTask(mudstate.idle_counter, PRIORITY_SYSTEM,
00236 dispatch_IdleCheck, 0, 0);
00237
00238
00239
00240 mudstate.events_counter = ltaNow + time_15s;
00241 scheduler.DeferTask(mudstate.events_counter, PRIORITY_SYSTEM,
00242 dispatch_CheckEvents, 0, 0);
00243
00244 #ifndef MEMORY_BASED
00245
00246
00247 ltd.SetSeconds(0);
00248 if (mudconf.cache_tick_period <= ltd)
00249 {
00250 mudconf.cache_tick_period.SetSeconds(1);
00251 }
00252 scheduler.DeferTask(ltaNow+mudconf.cache_tick_period, PRIORITY_SYSTEM,
00253 dispatch_CacheTick, 0, 0);
00254 #endif // !MEMORY_BASED
00255
00256 #if 0
00257
00258
00259 scheduler.DeferTask(ltaNow+time_45s, PRIORITY_SYSTEM, dispatch_CleanChannels, 0, 0);
00260 #endif // 0
00261
00262
00263
00264 scheduler.DeferTask(ltaNow+time_15s, PRIORITY_OBJECT, dispatch_CanRestart, 0, 0);
00265
00266 #ifdef WIN32
00267
00268
00269 scheduler.DeferTask(ltaNow+time_30s, PRIORITY_SYSTEM,
00270 dispatch_CalibrateQueryPerformance, 0, 0);
00271
00272 #endif // WIN32
00273 }
00274
00275
00276
00277
00278
00279
00280 void do_timewarp(dbref executor, dbref caller, dbref enactor, int key, char *arg)
00281 {
00282 int secs;
00283
00284 secs = mux_atol(arg);
00285
00286
00287
00288 if ((key == 0) || (key & TWARP_QUEUE))
00289 {
00290 do_queue(executor, caller, enactor, QUEUE_WARP, arg);
00291 }
00292
00293
00294
00295 CLinearTimeDelta ltd;
00296 ltd.SetSeconds(secs);
00297 if (key & TWARP_DUMP)
00298 {
00299 mudstate.dump_counter -= ltd;
00300 scheduler.CancelTask(dispatch_DatabaseDump, 0, 0);
00301 scheduler.DeferTask(mudstate.dump_counter, PRIORITY_SYSTEM, dispatch_DatabaseDump, 0, 0);
00302 }
00303 if (key & TWARP_CLEAN)
00304 {
00305 mudstate.check_counter -= ltd;
00306 scheduler.CancelTask(dispatch_FreeListReconstruction, 0, 0);
00307 scheduler.DeferTask(mudstate.check_counter, PRIORITY_SYSTEM, dispatch_FreeListReconstruction, 0, 0);
00308 }
00309 if (key & TWARP_IDLE)
00310 {
00311 mudstate.idle_counter -= ltd;
00312 scheduler.CancelTask(dispatch_IdleCheck, 0, 0);
00313 scheduler.DeferTask(mudstate.idle_counter, PRIORITY_SYSTEM, dispatch_IdleCheck, 0, 0);
00314 }
00315 if (key & TWARP_EVENTS)
00316 {
00317 mudstate.events_counter -= ltd;
00318 scheduler.CancelTask(dispatch_CheckEvents, 0, 0);
00319 scheduler.DeferTask(mudstate.events_counter, PRIORITY_SYSTEM, dispatch_CheckEvents, 0, 0);
00320 }
00321 }
00322
00323 #define INITIAL_TASKS 100
00324 #define EXTRA_TASKS 50
00325
00326 CTaskHeap::CTaskHeap(void)
00327 {
00328 m_nCurrent = 0;
00329 m_iVisitedMark = 0;
00330 m_nAllocated = INITIAL_TASKS;
00331 m_pHeap = new PTASK_RECORD[m_nAllocated];
00332 if (!m_pHeap)
00333 {
00334 m_nAllocated = 0;
00335 }
00336 }
00337
00338 CTaskHeap::~CTaskHeap(void)
00339 {
00340 while (m_nCurrent--)
00341 {
00342 PTASK_RECORD pTask = m_pHeap[m_nCurrent];
00343 if (pTask)
00344 {
00345 delete pTask;
00346 }
00347 m_pHeap[m_nCurrent] = NULL;
00348 }
00349 if (m_pHeap)
00350 {
00351 delete [] m_pHeap;
00352 }
00353 }
00354
00355 bool CTaskHeap::Insert(PTASK_RECORD pTask, SCHCMP *pfCompare)
00356 {
00357 if (m_nCurrent == m_nAllocated)
00358 {
00359 if (!Grow())
00360 {
00361 return false;
00362 }
00363 }
00364 pTask->m_iVisitedMark = m_iVisitedMark-1;
00365
00366 m_pHeap[m_nCurrent] = pTask;
00367 m_nCurrent++;
00368 SiftUp(m_nCurrent-1, pfCompare);
00369 return true;
00370 }
00371
00372 bool CTaskHeap::Grow(void)
00373 {
00374
00375
00376 int n = m_nAllocated + EXTRA_TASKS;
00377 PTASK_RECORD *p = new PTASK_RECORD[n];
00378 if (!p)
00379 {
00380 return false;
00381 }
00382
00383 memcpy(p, m_pHeap, sizeof(PTASK_RECORD)*m_nAllocated);
00384 m_nAllocated = n;
00385 delete [] m_pHeap;
00386 m_pHeap = p;
00387
00388 return true;
00389 }
00390
00391 PTASK_RECORD CTaskHeap::PeekAtTopmost(void)
00392 {
00393 if (m_nCurrent <= 0)
00394 {
00395 return NULL;
00396 }
00397 return m_pHeap[0];
00398 }
00399
00400 PTASK_RECORD CTaskHeap::RemoveTopmost(SCHCMP *pfCompare)
00401 {
00402 return Remove(0, pfCompare);
00403 }
00404
00405 void CTaskHeap::CancelTask(FTASK *fpTask, void *arg_voidptr, int arg_Integer)
00406 {
00407 for (int i = 0; i < m_nCurrent; i++)
00408 {
00409 PTASK_RECORD p = m_pHeap[i];
00410 if ( p->fpTask == fpTask
00411 && p->arg_voidptr == arg_voidptr
00412 && p->arg_Integer == arg_Integer)
00413 {
00414 p->fpTask = NULL;
00415 }
00416 }
00417 }
00418
00419 static int ComparePriority(PTASK_RECORD pTaskA, PTASK_RECORD pTaskB)
00420 {
00421 int i = (pTaskA->iPriority) - (pTaskB->iPriority);
00422 if (i == 0)
00423 {
00424
00425
00426 return (pTaskA->m_Ticket) - (pTaskB->m_Ticket);
00427 }
00428 return i;
00429 }
00430
00431 static int CompareWhen(PTASK_RECORD pTaskA, PTASK_RECORD pTaskB)
00432 {
00433
00434
00435 if (pTaskA->ltaWhen < pTaskB->ltaWhen)
00436 {
00437 return -1;
00438 }
00439 else if (pTaskA->ltaWhen > pTaskB->ltaWhen)
00440 {
00441 return 1;
00442 }
00443 return 0;
00444 }
00445
00446 void CScheduler::DeferTask(const CLinearTimeAbsolute& ltaWhen, int iPriority,
00447 FTASK *fpTask, void *arg_voidptr, int arg_Integer)
00448 {
00449 PTASK_RECORD pTask = new TASK_RECORD;
00450 if (!pTask) return;
00451
00452 pTask->ltaWhen = ltaWhen;
00453 pTask->iPriority = iPriority;
00454 pTask->fpTask = fpTask;
00455 pTask->arg_voidptr = arg_voidptr;
00456 pTask->arg_Integer = arg_Integer;
00457 pTask->m_Ticket = m_Ticket++;
00458
00459
00460
00461 if (!m_WhenHeap.Insert(pTask, CompareWhen))
00462 {
00463 delete pTask;
00464 }
00465 }
00466
00467 void CScheduler::DeferImmediateTask(int iPriority, FTASK *fpTask, void *arg_voidptr, int arg_Integer)
00468 {
00469 PTASK_RECORD pTask = new TASK_RECORD;
00470 if (!pTask) return;
00471
00472
00473 pTask->iPriority = iPriority;
00474 pTask->fpTask = fpTask;
00475 pTask->arg_voidptr = arg_voidptr;
00476 pTask->arg_Integer = arg_Integer;
00477 pTask->m_Ticket = m_Ticket++;
00478
00479
00480
00481 if (!m_WhenHeap.Insert(pTask, CompareWhen))
00482 {
00483 delete pTask;
00484 }
00485 }
00486
00487 void CScheduler::CancelTask(FTASK *fpTask, void *arg_voidptr, int arg_Integer)
00488 {
00489 m_WhenHeap.CancelTask(fpTask, arg_voidptr, arg_Integer);
00490 m_PriorityHeap.CancelTask(fpTask, arg_voidptr, arg_Integer);
00491 }
00492
00493 void CScheduler::ReadyTasks(const CLinearTimeAbsolute& ltaNow)
00494 {
00495
00496
00497 PTASK_RECORD pTask = m_WhenHeap.PeekAtTopmost();
00498 while ( pTask
00499 && pTask->ltaWhen < ltaNow)
00500 {
00501 pTask = m_WhenHeap.RemoveTopmost(CompareWhen);
00502 if (pTask)
00503 {
00504 if ( NULL == pTask->fpTask
00505 || !m_PriorityHeap.Insert(pTask, ComparePriority))
00506 {
00507 delete pTask;
00508 }
00509 }
00510 pTask = m_WhenHeap.PeekAtTopmost();
00511 }
00512 }
00513
00514 int CScheduler::RunTasks(const CLinearTimeAbsolute& ltaNow)
00515 {
00516 ReadyTasks(ltaNow);
00517 if (mudconf.active_q_chunk)
00518 {
00519 return RunTasks(mudconf.active_q_chunk);
00520 }
00521 else
00522 {
00523 return RunAllTasks();
00524 }
00525 }
00526
00527 int CScheduler::RunTasks(int iCount)
00528 {
00529 int nTasks = 0;
00530 while (iCount--)
00531 {
00532 PTASK_RECORD pTask = m_PriorityHeap.PeekAtTopmost();
00533 if (!pTask) break;
00534
00535 if (pTask->iPriority > m_minPriority)
00536 {
00537
00538
00539
00540
00541 break;
00542 }
00543 pTask = m_PriorityHeap.RemoveTopmost(ComparePriority);
00544 if (pTask)
00545 {
00546 if (pTask->fpTask)
00547 {
00548 pTask->fpTask(pTask->arg_voidptr, pTask->arg_Integer);
00549 nTasks++;
00550 }
00551 delete pTask;
00552 }
00553 }
00554 return nTasks;
00555 }
00556
00557 int CScheduler::RunAllTasks(void)
00558 {
00559 int nTotalTasks = 0;
00560
00561 int nTasks;
00562 do
00563 {
00564 nTasks = RunTasks(100);
00565 nTotalTasks += nTasks;
00566 } while (nTasks);
00567
00568 return nTotalTasks;
00569 }
00570
00571 bool CScheduler::WhenNext(CLinearTimeAbsolute *ltaWhen)
00572 {
00573
00574
00575 PTASK_RECORD pTask = m_PriorityHeap.PeekAtTopmost();
00576 if (pTask)
00577 {
00578 if (pTask->iPriority <= m_minPriority)
00579 {
00580 ltaWhen->SetSeconds(0);
00581 return true;
00582 }
00583 }
00584
00585
00586
00587 pTask = m_WhenHeap.PeekAtTopmost();
00588 if (pTask)
00589 {
00590 *ltaWhen = pTask->ltaWhen;
00591 return true;
00592 }
00593 return false;
00594 }
00595
00596 #define HEAP_LEFT_CHILD(x) (2*(x)+1)
00597 #define HEAP_RIGHT_CHILD(x) (2*(x)+2)
00598 #define HEAP_PARENT(x) (((x)-1)/2)
00599
00600 void CTaskHeap::SiftDown(int iSubRoot, SCHCMP *pfCompare)
00601 {
00602 int parent = iSubRoot;
00603 int child = HEAP_LEFT_CHILD(parent);
00604
00605 PTASK_RECORD Ref = m_pHeap[parent];
00606
00607 while (child < m_nCurrent)
00608 {
00609 int rightchild = HEAP_RIGHT_CHILD(parent);
00610 if (rightchild < m_nCurrent)
00611 {
00612 if (pfCompare(m_pHeap[rightchild], m_pHeap[child]) < 0)
00613 {
00614 child = rightchild;
00615 }
00616 }
00617 if (pfCompare(Ref, m_pHeap[child]) <= 0)
00618 break;
00619
00620 m_pHeap[parent] = m_pHeap[child];
00621 parent = child;
00622 child = HEAP_LEFT_CHILD(parent);
00623 }
00624 m_pHeap[parent] = Ref;
00625 }
00626
00627 void CTaskHeap::SiftUp(int child, SCHCMP *pfCompare)
00628 {
00629 while (child)
00630 {
00631 int parent = HEAP_PARENT(child);
00632 if (pfCompare(m_pHeap[parent], m_pHeap[child]) <= 0)
00633 break;
00634
00635 PTASK_RECORD Tmp;
00636 Tmp = m_pHeap[child];
00637 m_pHeap[child] = m_pHeap[parent];
00638 m_pHeap[parent] = Tmp;
00639
00640 child = parent;
00641 }
00642 }
00643
00644 PTASK_RECORD CTaskHeap::Remove(int iNode, SCHCMP *pfCompare)
00645 {
00646 if (iNode < 0 || m_nCurrent <= iNode) return NULL;
00647
00648 PTASK_RECORD pTask = m_pHeap[iNode];
00649
00650 m_nCurrent--;
00651 m_pHeap[iNode] = m_pHeap[m_nCurrent];
00652 SiftDown(iNode, pfCompare);
00653 SiftUp(iNode, pfCompare);
00654
00655 return pTask;
00656 }
00657
00658 void CTaskHeap::Update(int iNode, SCHCMP *pfCompare)
00659 {
00660 if (iNode < 0 || m_nCurrent <= iNode)
00661 {
00662 return;
00663 }
00664
00665 SiftDown(iNode, pfCompare);
00666 SiftUp(iNode, pfCompare);
00667 }
00668
00669 void CScheduler::TraverseUnordered(SCHLOOK *pfLook)
00670 {
00671 if (m_WhenHeap.TraverseUnordered(pfLook, CompareWhen))
00672 {
00673 m_PriorityHeap.TraverseUnordered(pfLook, ComparePriority);
00674 }
00675 }
00676
00677 void CScheduler::TraverseOrdered(SCHLOOK *pfLook)
00678 {
00679 m_PriorityHeap.TraverseOrdered(pfLook, ComparePriority);
00680 m_WhenHeap.TraverseOrdered(pfLook, CompareWhen);
00681 }
00682
00683
00684
00685
00686
00687 int CTaskHeap::TraverseUnordered(SCHLOOK *pfLook, SCHCMP *pfCompare)
00688 {
00689
00690
00691 m_iVisitedMark++;
00692 if (m_iVisitedMark == 0)
00693 {
00694
00695
00696
00697 for (int i = 0; i < m_nCurrent; i++)
00698 {
00699 PTASK_RECORD p = m_pHeap[i];
00700 p->m_iVisitedMark = m_iVisitedMark;
00701 }
00702 m_iVisitedMark++;
00703 }
00704
00705 int bUnvisitedRecords;
00706 do
00707 {
00708 bUnvisitedRecords = false;
00709 for (int i = 0; i < m_nCurrent; i++)
00710 {
00711 PTASK_RECORD p = m_pHeap[i];
00712
00713 if (p->m_iVisitedMark == m_iVisitedMark)
00714 {
00715
00716
00717 continue;
00718 }
00719 bUnvisitedRecords = true;
00720 p->m_iVisitedMark = m_iVisitedMark;
00721
00722 int cmd = pfLook(p);
00723 switch (cmd)
00724 {
00725 case IU_REMOVE_TASK:
00726 Remove(i, pfCompare);
00727 break;
00728
00729 case IU_DONE:
00730 return false;
00731
00732 case IU_UPDATE_TASK:
00733 Update(i, pfCompare);
00734 break;
00735 }
00736 }
00737 } while (bUnvisitedRecords);
00738 return true;
00739 }
00740
00741
00742
00743
00744
00745 int CTaskHeap::TraverseOrdered(SCHLOOK *pfLook, SCHCMP *pfCompare)
00746 {
00747 Sort(pfCompare);
00748
00749 for (int i = m_nCurrent-1; i >= 0; i--)
00750 {
00751 PTASK_RECORD p = m_pHeap[i];
00752 int cmd = pfLook(p);
00753 if (IU_DONE == cmd)
00754 {
00755 break;
00756 }
00757 }
00758
00759 Remake(pfCompare);
00760 return true;
00761 }
00762
00763 void CTaskHeap::Sort(SCHCMP *pfCompare)
00764 {
00765 int s_nCurrent = m_nCurrent;
00766 while (m_nCurrent--)
00767 {
00768 PTASK_RECORD p = m_pHeap[m_nCurrent];
00769 m_pHeap[m_nCurrent] = m_pHeap[0];
00770 m_pHeap[0] = p;
00771 SiftDown(0, pfCompare);
00772 }
00773 m_nCurrent = s_nCurrent;
00774 }
00775
00776 void CTaskHeap::Remake(SCHCMP *pfCompare)
00777 {
00778 int s_nCurrent = m_nCurrent;
00779 m_nCurrent = 0;
00780 while (s_nCurrent--)
00781 {
00782 m_nCurrent++;
00783 SiftUp(m_nCurrent-1, pfCompare);
00784 }
00785 }
00786
00787 void CScheduler::SetMinPriority(int arg_minPriority)
00788 {
00789 m_minPriority = arg_minPriority;
00790 }