00001 // File: con.C 00002 // Module for conservative simulation strategy class 00003 // Last Modified: 07.31.01 by Terry L. Wilmarth 00004 00005 #include "pose.h" 00006 00007 void con::Step() 00008 { 00009 Event *ev; 00010 00011 #if !CMK_TRACE_DISABLED 00012 if(pose_config.stats) 00013 localStats->SwitchTimer(CAN_TIMER); 00014 #endif 00015 if (!parent->cancels.IsEmpty()) // Cancel as much as possible 00016 CancelEvents(); 00017 #if !CMK_TRACE_DISABLED 00018 if(pose_config.stats) 00019 localStats->SwitchTimer(SIM_TIMER); 00020 #endif 00021 // Prepare to execute an event 00022 ev = eq->currentPtr; 00023 while ((ev->timestamp <= localPVT->getGVT()) && (ev->timestamp >= 0)) { 00024 // execute all events at GVT 00025 currentEvent = ev; 00026 ev->done = 2; 00027 parent->DOs++; 00028 #if !CMK_TRACE_DISABLED 00029 if(pose_config.stats){ 00030 localStats->Do(); 00031 localStats->SwitchTimer(DO_TIMER); 00032 } 00033 #endif 00034 parent->ResolveFn(ev->fnIdx, ev->msg); // execute it 00035 #if !CMK_TRACE_DISABLED 00036 if(pose_config.stats) 00037 localStats->SwitchTimer(SIM_TIMER); 00038 #endif 00039 ev->done = 1; 00040 eq->ShiftEvent(); // move on to next event 00041 ev = eq->currentPtr; 00042 } 00043 } 00044 00045 // Cancel events in cancellations list 00046 void con::CancelEvents() 00047 { 00048 Event *ev; 00049 int found; 00050 POSE_TimeType eGVT = localPVT->getGVT(); 00051 CancelNode *it, *last; 00052 00053 last = parent->cancels.GetItem(); // make note of last item to be examined 00054 if (!last) // none of the cancellations are early enough to bother with 00055 return; 00056 while (!parent->cancels.IsEmpty()) { // loop through all cancellations 00057 it = parent->cancels.GetItem(); // it is the event to cancel 00058 if (!it) // none of the cancellations are early enough to bother with 00059 return; 00060 found = 0; // init the found flag to not found (0) 00061 00062 // search the cancellations list for a cancellation that has a corresponding 00063 // event in the event queue 00064 while (!found) { // loop until one is found, or exit fn if all examined 00065 ev = eq->currentPtr; // set search start point 00066 00067 // look for "it" above currentPtr 00068 if ((ev->timestamp <= it->timestamp) && (ev != eq->back())) { 00069 while ((ev->timestamp >= 0) && (ev->timestamp <= it->timestamp)) 00070 if (ev->evID == it->evID) { 00071 found = 1; 00072 break; 00073 } 00074 else ev = ev->next; 00075 if (!found) { // not in linked list; check heap 00076 found = eq->eqh->DeleteEvent(it->evID, it->timestamp); 00077 if (found) ev = NULL; // make ev NULL so we know it was deleted 00078 } 00079 } 00080 else if (ev != eq->back()) { // current at back of queue; check the heap 00081 found = eq->eqh->DeleteEvent(it->evID, it->timestamp); 00082 if (found) ev = NULL; // make ev NULL so we know it was deleted 00083 } 00084 else if (ev->timestamp > it->timestamp) { // ERROR: the event is a past event 00085 CkPrintf("ERROR: con::CancelEvents: Trying to cancel past event.\n"); 00086 CkExit(); 00087 } 00088 if (!found) { // "it" event has not arrived yet 00089 if (it == last) { // seen all cancellations during this call 00090 /* 00091 CkPrintf("WARNING: con::CancelEvents: Waiting for [%d.%d] to arrive\n", 00092 it->evID.id, it->evID.pe); 00093 */ 00094 return; 00095 } 00096 it = parent->cancels.GetItem(); 00097 if (!it) // none of the cancellations are early enough to bother with 00098 return; 00099 } 00100 } 00101 00102 if (ev && (ev->done == 0)) { // found it; get rid of it 00103 if (ev == eq->currentPtr) // adjust currentPtr 00104 eq->ShiftEvent(); 00105 eq->DeleteEvent(ev); // delete the event 00106 } 00107 else if (ev) { // ERROR: event was executed 00108 CkPrintf("ERROR: con::CancelEvents: Trying to cancel executed event.\n"); 00109 CkExit(); 00110 } 00111 00112 parent->cancels.RemoveItem(it); // clean up 00113 } 00114 } 00115 00116