void CHardwareMatrixState::DeallocateAll() { int i; DumpState(); for( i = 0; i < m_NumMatrices; i++ ) { m_matrixState[i].allocated = false; m_matrixState[i].globalMatrixID = INT_MAX; m_matrixState[i].lastUsageID = INT_MAX; } m_AllocatedMatrices = 0; DumpState(); }
int main(int argc, const char **argv) { set_debug_flags(NULL, D_ALWAYS); set_mySubSystem( "TEST_LOG_READER_STATE", SUBSYSTEM_TYPE_TOOL ); // initialize to read from config file myDistro->Init( argc, argv ); config(); // Set up the dprintf stuff... dprintf_config("TEST_LOG_READER_STATE"); Options opts; if ( CheckArgs( argc, argv, opts ) < 0 ) { fprintf( stderr, "CheckArgs() failed\n" ); exit( 1 ); } ReadUserLog::FileState state; if ( opts.needStateFile() && ( ReadState( opts, state ) < 0 ) ) { fprintf( stderr, "ReadState() failed\n" ); exit( 1 ); } ReadUserLog::FileState state2; if ( opts.needStateFile2() && ( ReadState( opts, state2 ) < 0 ) ) { fprintf( stderr, "ReadState() failed\n" ); exit( 1 ); } int status = 0; switch( opts.getCommand() ) { case CMD_NONE: status = -1; break; case CMD_LIST: opts.dumpFieldList( ); break; case CMD_DUMP: status = DumpState( opts, state ); break; case CMD_DIFF: status = DiffState( opts, state, state2 ); break; case CMD_ACCESS: status = CheckStateAccess( opts, state ); break; case CMD_VERIFY: status = VerifyState( opts, state ); break; } if ( status == 0 ) { exit( 0 ); } else { exit( 2 ); } }
void Fsm::DumpTo(yostream& s) const { for (size_t state = 0; state < Size(); ++state) { s << "*** State " << state << "\n"; DumpState(s, state); } }
static void WaitForInput(const struct JoystickData *data) { int i = 0; int chosen = data->chosen_joystick; int num_buttons = data->joysticks[chosen].num_buttons; struct Joystick *joystick = &data->joysticks[chosen]; DIJOYSTATE state; BOOL pressed = FALSE; ZeroMemory(&state, sizeof(state)); printf("Polling input from '%s'\n", joystick->instance.tszInstanceName); printf("Joystick has %d buttons and %d axes\n", joystick->num_buttons, joystick->num_axes); printf("Press any joystick key\n"); while (!Poll(joystick->device, &state) && !pressed) for (i = 0; i < num_buttons && !pressed; i++) pressed = pressed || state.rgbButtons[i]; /* Wait for input and dump */ while (!Poll(joystick->device, &state)) { DumpState(&state, num_buttons); Sleep(data->poll_time); } }
void Fsm::DumpTo(yostream& s, const ystring& name) const { s << "digraph {\n \"initial\"[shape=\"plaintext\",label=\"" << name << "\"]\n\n"; for (size_t state = 0; state < Size(); ++state) { DumpState(s, state); } s << "}\n\n"; }
nsresult Http2Decompressor::DecodeHeaderBlock(const uint8_t *data, uint32_t datalen, nsACString &output) { mAlternateReferenceSet.Clear(); mOffset = 0; mData = data; mDataLen = datalen; mOutput = &output; mOutput->Truncate(); mHeaderStatus.Truncate(); mHeaderHost.Truncate(); mHeaderScheme.Truncate(); mHeaderPath.Truncate(); mHeaderMethod.Truncate(); nsresult rv = NS_OK; while (NS_SUCCEEDED(rv) && (mOffset < datalen)) { if (mData[mOffset] & 0x80) { rv = DoIndexed(); LOG(("Decompressor state after indexed")); } else if (mData[mOffset] & 0x40) { rv = DoLiteralWithIncremental(); LOG(("Decompressor state after literal with incremental")); } else if (mData[mOffset] & 0x20) { rv = DoContextUpdate(); LOG(("Decompressor state after context update")); } else if (mData[mOffset] & 0x10) { rv = DoLiteralNeverIndexed(); LOG(("Decompressor state after literal never index")); } else { rv = DoLiteralWithoutIndex(); LOG(("Decompressor state after literal without index")); } DumpState(); } // after processing the input the decompressor comapres the alternate // set to the inherited reference set and generates headers for // anything implicit in reference - alternate. uint32_t setLen = mReferenceSet.Length(); for (uint32_t index = 0; index < setLen; ++index) { if (!mAlternateReferenceSet.Contains(mReferenceSet[index])) { LOG(("HTTP decompressor carryover in reference set with index %u %s %s\n", mReferenceSet[index], mHeaderTable[mReferenceSet[index]]->mName.get(), mHeaderTable[mReferenceSet[index]]->mValue.get())); OutputHeader(mReferenceSet[index]); } } mAlternateReferenceSet.Clear(); return rv; }
// // add a member to the master list if not already there // int plNetTransport::AddMember(plNetTransportMember* mbr) { if (FindMember(mbr)==-1) { fMembers.push_back(mbr); hsLogEntry( plNetClientMgr::GetInstance()->DebugMsg("Adding member %s", mbr->AsString().c_str()) ); plNetClientMgr::GetInstance()->GetListenList()->AddMember(mbr); plNetClientMgr::GetInstance()->GetTalkList()->AddMember(mbr); DumpState(); return fMembers.size()-1; } return -1; }
bool CHardwareMatrixState::AllocateMatrix( int globalMatrixID ) { int i; if( IsMatrixAllocated( globalMatrixID ) ) { return true; } for( i = 0; i < m_NumMatrices; i++ ) { if( !m_matrixState[i].allocated ) { m_matrixState[i].globalMatrixID = globalMatrixID; m_matrixState[i].allocated = true; m_matrixState[i].lastUsageID = m_LRUCounter++; ++m_AllocatedMatrices; DumpState(); return true; } } DumpState(); return false; }
bool Parser::ParseConfigFile(const std::string& path) { INFO("Parsing file %s...\n", path.c_str()); Timer t; std::string data; if (!read_file(path.c_str(), &data)) { return false; } data.push_back('\n'); // TODO: fix parse_config. ParseData(path, data); for (const auto& sp : section_parsers_) { sp.second->EndFile(path); } // Turning this on and letting the INFO logging be discarded adds 0.2s to // Nexus 9 boot time, so it's disabled by default. if (false) DumpState(); NOTICE("(Parsing %s took %.2fs.)\n", path.c_str(), t.duration()); return true; }
nsresult Http2Decompressor::DecodeHeaderBlock(const uint8_t *data, uint32_t datalen, nsACString &output, bool isPush) { mOffset = 0; mData = data; mDataLen = datalen; mOutput = &output; mOutput->Truncate(); mHeaderStatus.Truncate(); mHeaderHost.Truncate(); mHeaderScheme.Truncate(); mHeaderPath.Truncate(); mHeaderMethod.Truncate(); mSeenNonColonHeader = false; mIsPush = isPush; nsresult rv = NS_OK; while (NS_SUCCEEDED(rv) && (mOffset < datalen)) { if (mData[mOffset] & 0x80) { rv = DoIndexed(); LOG(("Decompressor state after indexed")); } else if (mData[mOffset] & 0x40) { rv = DoLiteralWithIncremental(); LOG(("Decompressor state after literal with incremental")); } else if (mData[mOffset] & 0x20) { rv = DoContextUpdate(); LOG(("Decompressor state after context update")); } else if (mData[mOffset] & 0x10) { rv = DoLiteralNeverIndexed(); LOG(("Decompressor state after literal never index")); } else { rv = DoLiteralWithoutIndex(); LOG(("Decompressor state after literal without index")); } DumpState(); } return rv; }
void plNetTransport::IRemoveMember(plNetTransportMember* mbr) { if (!mbr) return; hsLogEntry( plNetClientMgr::GetInstance()->DebugMsg("Removing member %s", mbr->AsString().c_str()) ); // plNetClientMgr::GetInstance()->GetNetCore()->RemovePeer(mbr->GetPeerID()); plNetClientMgr::GetInstance()->GetTalkList()->RemoveMember(mbr); plNetClientMgr::GetInstance()->GetListenList()->RemoveMember(mbr); // remove member from subscription lists IUnSubscribeToAllChannelGrps(mbr); plMembersList::iterator it=std::find(fMembers.begin(),fMembers.end(),mbr); // remove member from master list fMembers.erase(it); hsLogEntry( plNetClientMgr::GetInstance()->DebugMsg("Done Removing member %s", mbr->AsString().c_str()) ); DumpState(); delete mbr; }
int doit(void) { int i ; cvodeSettings_t *settings ; variableIndex_t *s1, *s2; integratorInstance_t *integratorInstanceA; integratorInstance_t *integratorInstanceB; odeModel_t *model = ODEModel_createFromFile("events-2-events-1-assignment-l2.xml"); RETURN_ON_ERRORS_WITH(1); assert(ODEModel_hasVariable(model, "S1")); assert(ODEModel_hasVariable(model, "S1")); assert(!ODEModel_hasVariable(model, "foobar")); s1 = ODEModel_getVariableIndex(model, "S1"); s2 = ODEModel_getVariableIndex(model, "S2"); /* Creating settings with default values */ settings = CvodeSettings_create(); /* Setting end time to .1, number of time steps to 1 and NULL instead of an optional predefined time series (double *); due to Indefinitely == 1, Printstep 1 will be ignored and Time = 0.1 will be used as timestep for infinite integration */ CvodeSettings_setTime(settings, .01, 1); /* Setting Cvode Parameters: absolute and relative tolerances and maximal internal step */ CvodeSettings_setErrors(settings, 1e-18, 1e-14, 500); /* Setting Integration Switches: see documentation or example simpleIntegratorInstance.c for details on the passed values */ CvodeSettings_setSwitches(settings, 1, 1, 0, 0, 0, 0); integratorInstanceA = IntegratorInstance_create(model, settings); RETURN_ON_ERRORS_WITH(1); integratorInstanceB = IntegratorInstance_create(model, settings); RETURN_ON_ERRORS_WITH(1); DumpState(integratorInstanceA, integratorInstanceB, s1, s2); for (i=0; i != 500; i++) { IntegratorInstance_integrateOneStep(integratorInstanceA); RETURN_ON_ERRORS_WITH(1); IntegratorInstance_integrateOneStep(integratorInstanceB); RETURN_ON_ERRORS_WITH(1); DumpState(integratorInstanceA, integratorInstanceB, s1, s2); } IntegratorInstance_free(integratorInstanceA); IntegratorInstance_free(integratorInstanceB); VariableIndex_free(s1); VariableIndex_free(s2); ODEModel_free(model); CvodeSettings_free(settings); return 0; }
int doit(int argc, char *argv[]) { double i, j ; cvodeSettings_t *settings = CvodeSettings_create(); variableIndex_t *speciesVI, *parameterVI, *parameter2VI; integratorInstance_t *integratorInstance; char *modelStr, *parameterStr, *parameter2Str, *speciesStr; double parameter, parameterEnd, parameterStepSize, parameter2, parameter2End, parameter2StepSize, errorTolerance, relativeErrorTolerance, endtime, initCond, maxDiff, diff; int maximumIntegrationSteps; odeModel_t *model ; if (argc < 11) { fprintf( stderr, "usage %s sbml-model variable parameter1 parameter1-start parameter1-end parameter1-step parameter2 parameter2-start parameter2-end parameter2-step [endtime] [error-tolerance] [relative-error-tolerance] [maximum integration steps]\n", argv[0]); exit(0); } modelStr = argv[1]; speciesStr = argv[2]; parameterStr = argv[3]; parameter = atof(argv[4]); parameterEnd = atof(argv[5]); parameterStepSize = atof(argv[6]); parameter2Str = argv[7]; parameter2 = atof(argv[8]); parameter2End = atof(argv[9]); parameter2StepSize = atof(argv[10]); if (argc > 12) endtime = atof(argv[11]); else endtime = 10000; if (argc > 13) errorTolerance = atof(argv[12]); else errorTolerance = 1e-6; if (argc > 14) relativeErrorTolerance = atof(argv[13]); else relativeErrorTolerance = 1e-4; if (argc > 15) maximumIntegrationSteps = atoi(argv[14]); else maximumIntegrationSteps = 1e9; model = ODEModel_createFromFile(modelStr); RETURN_ON_ERRORS_WITH(1); speciesVI = ODEModel_getVariableIndex(model, speciesStr); parameterVI = ODEModel_getVariableIndex(model, parameterStr); parameter2VI = ODEModel_getVariableIndex(model, parameter2Str); RETURN_ON_ERRORS_WITH(1); /* integrate until steady state */ if ( endtime == 0 ) { /* stop integration upon a steady state */ CvodeSettings_setIndefinitely(settings, 1); CvodeSettings_setSteadyStateThreshold(settings, 1e-9); CvodeSettings_setHaltOnSteadyState(settings, 1); CvodeSettings_setTime(settings, 1, 1); } else { CvodeSettings_setHaltOnSteadyState(settings, 0); CvodeSettings_setIndefinitely(settings, 0); CvodeSettings_setTime(settings, endtime, 1000); } /* absolute tolerance in Cvode integration */ CvodeSettings_setError(settings, errorTolerance); /* relative tolerance in Cvode integration */ CvodeSettings_setRError(settings, relativeErrorTolerance); /* maximum step number for CVode integration */ CvodeSettings_setMxstep(settings, maximumIntegrationSteps); /* doesn't stop integration upon an event */ CvodeSettings_setHaltOnEvent(settings, 0); /* don't Store time course history */ CvodeSettings_setStoreResults(settings, 0); /* compile model */ CvodeSettings_setCompileFunctions(settings, 1); integratorInstance = IntegratorInstance_create(model, settings); printf("set xlabel '%s'\n", ODEModel_getVariableName(model, parameterVI)); printf("set ylabel '%s'\n", ODEModel_getVariableName(model, parameter2VI)); printf("splot '-' using 1:2:3 title '%s' with points pointtype 1 pointsize 1 palette\n", ODEModel_getVariableName(model, speciesVI) ); /* remember initial condition of observed variable */ initCond = IntegratorInstance_getVariableValue(integratorInstance, speciesVI); maxDiff = 0.0; int error = 0 ; int run = 0; for ( run=0; run<2; run++ ) { for (i = parameter; i <= parameterEnd; i += parameterStepSize) { for (j = parameter2; j <= parameter2End; j += parameter2StepSize) { /* add fourth parameter here */ IntegratorInstance_reset( integratorInstance); RETURN_ON_ERRORS_WITH(1); /* for the second run reset the initial condition of the observed variable to a multiple of the maximum observed difference of its value wrt to its initial condition */ if ( run == 1 ) IntegratorInstance_setVariableValue(integratorInstance, speciesVI, fabs(5*(initCond-maxDiff))); IntegratorInstance_setVariableValue(integratorInstance, parameterVI, i); IntegratorInstance_setVariableValue(integratorInstance, parameter2VI, j); /* printf("ic %g\t", IntegratorInstance_getVariableValue(integratorInstance, speciesVI)); */ while(!IntegratorInstance_checkSteadyState(integratorInstance) && !IntegratorInstance_timeCourseCompleted(integratorInstance) ) { IntegratorInstance_integrateOneStep(integratorInstance); if (SolverError_getNum(ERROR_ERROR_TYPE) || SolverError_getNum(FATAL_ERROR_TYPE)) { fprintf(stderr, "ERROR at parameter 1 = %g, parameter 2 = %g\n", i, j); DumpErrors(); error++; } } /* printf("end %g\n", IntegratorInstance_getVariableValue(integratorInstance, speciesVI)); */ /* check whether the final value has largest difference to initial condition */ diff = fabs(initCond - IntegratorInstance_getVariableValue(integratorInstance, speciesVI)); if ( diff > maxDiff ) maxDiff = diff; DumpState(integratorInstance, parameterVI, parameter2VI, speciesVI); } } } printf("end\n"); /* printf("end\n init %g, MAX DIFF %g, abs %g\n", initCond, maxDiff, fabs(initCond-maxDiff)); */ if ( error ) printf("\t%d errors occured\n", error); IntegratorInstance_free(integratorInstance); VariableIndex_free(parameterVI); VariableIndex_free(parameter2VI); VariableIndex_free(speciesVI); ODEModel_free(model); CvodeSettings_free(settings); return 0; }
void CSimulation2Impl::Update(int turnLength, const std::vector<SimulationCommand>& commands) { PROFILE3("sim update"); PROFILE2_ATTR("turn %d", (int)m_TurnNumber); fixed turnLengthFixed = fixed::FromInt(turnLength) / 1000; /* * In serialization test mode, we save the original (primary) simulation state before each turn update. * We run the update, then load the saved state into a secondary context. * We serialize that again and compare to the original serialization (to check that * serialize->deserialize->serialize is equivalent to serialize). * Then we run the update on the secondary context, and check that its new serialized * state matches the primary context after the update (to check that the simulation doesn't depend * on anything that's not serialized). */ const bool serializationTestDebugDump = false; // set true to save human-readable state dumps before an error is detected, for debugging (but slow) const bool serializationTestHash = true; // set true to save and compare hash of state SerializationTestState primaryStateBefore; if (m_EnableSerializationTest) { ENSURE(m_ComponentManager.SerializeState(primaryStateBefore.state)); if (serializationTestDebugDump) ENSURE(m_ComponentManager.DumpDebugState(primaryStateBefore.debug, false)); if (serializationTestHash) ENSURE(m_ComponentManager.ComputeStateHash(primaryStateBefore.hash, false)); } UpdateComponents(m_SimContext, turnLengthFixed, commands); if (m_EnableSerializationTest) { // Initialise the secondary simulation CTerrain secondaryTerrain; CSimContext secondaryContext; secondaryContext.m_Terrain = &secondaryTerrain; CComponentManager secondaryComponentManager(secondaryContext, m_ComponentManager.GetScriptInterface().GetRuntime()); secondaryComponentManager.LoadComponentTypes(); ENSURE(LoadDefaultScripts(secondaryComponentManager, NULL)); ResetComponentState(secondaryComponentManager, false, false); // Load the map into the secondary simulation LDR_BeginRegistering(); CMapReader* mapReader = new CMapReader; // automatically deletes itself // TODO: this duplicates CWorld::RegisterInit and could probably be cleaned up a bit std::string mapType; m_ComponentManager.GetScriptInterface().GetProperty(m_InitAttributes.get(), "mapType", mapType); if (mapType == "random") { // TODO: support random map scripts debug_warn(L"Serialization test mode only supports scenarios"); } else { std::wstring mapFile; m_ComponentManager.GetScriptInterface().GetProperty(m_InitAttributes.get(), "map", mapFile); VfsPath mapfilename = VfsPath(mapFile).ChangeExtension(L".pmp"); mapReader->LoadMap(mapfilename, CScriptValRooted(), &secondaryTerrain, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &secondaryContext, INVALID_PLAYER, true); // throws exception on failure } LDR_EndRegistering(); ENSURE(LDR_NonprogressiveLoad() == INFO::OK); ENSURE(secondaryComponentManager.DeserializeState(primaryStateBefore.state)); SerializationTestState secondaryStateBefore; ENSURE(secondaryComponentManager.SerializeState(secondaryStateBefore.state)); if (serializationTestDebugDump) ENSURE(secondaryComponentManager.DumpDebugState(secondaryStateBefore.debug, false)); if (serializationTestHash) ENSURE(secondaryComponentManager.ComputeStateHash(secondaryStateBefore.hash, false)); if (primaryStateBefore.state.str() != secondaryStateBefore.state.str() || primaryStateBefore.hash != secondaryStateBefore.hash) { ReportSerializationFailure(&primaryStateBefore, NULL, &secondaryStateBefore, NULL); } SerializationTestState primaryStateAfter; ENSURE(m_ComponentManager.SerializeState(primaryStateAfter.state)); if (serializationTestHash) ENSURE(m_ComponentManager.ComputeStateHash(primaryStateAfter.hash, false)); UpdateComponents(secondaryContext, turnLengthFixed, CloneCommandsFromOtherContext(m_ComponentManager.GetScriptInterface(), secondaryComponentManager.GetScriptInterface(), commands)); SerializationTestState secondaryStateAfter; ENSURE(secondaryComponentManager.SerializeState(secondaryStateAfter.state)); if (serializationTestHash) ENSURE(secondaryComponentManager.ComputeStateHash(secondaryStateAfter.hash, false)); if (primaryStateAfter.state.str() != secondaryStateAfter.state.str() || primaryStateAfter.hash != secondaryStateAfter.hash) { // Only do the (slow) dumping now we know we're going to need to report it ENSURE(m_ComponentManager.DumpDebugState(primaryStateAfter.debug, false)); ENSURE(secondaryComponentManager.DumpDebugState(secondaryStateAfter.debug, false)); ReportSerializationFailure(&primaryStateBefore, &primaryStateAfter, &secondaryStateBefore, &secondaryStateAfter); } } // if (m_TurnNumber == 0) // m_ComponentManager.GetScriptInterface().DumpHeap(); // Run the GC occasionally // (TODO: we ought to schedule this for a frame where we're not // running the sim update, to spread the load) if (m_TurnNumber % 1 == 0) m_ComponentManager.GetScriptInterface().MaybeIncrementalRuntimeGC(); if (m_EnableOOSLog) DumpState(); // Start computing AI for the next turn CmpPtr<ICmpAIManager> cmpAIManager(m_SimContext, SYSTEM_ENTITY); if (cmpAIManager) cmpAIManager->StartComputation(); ++m_TurnNumber; }
void loop() { int i, j; // delay(1); GPIO_SET(CLK); delay(1); GPIO_SET(CLK); clkCountHi = 1; clkCount++; T++; tracePauseCount++; ReadControlState(); GetAddressFromAB(); if (Mlast==1 && m1==0) T = 1, m1Count++; Mlast = m1; bool suppressDump = false; if (!traceRefresh & !rfsh) suppressDump = true; // If the number of M1 cycles has been reached, skip the rest since we dont // want to execute this M1 phase if (m1Count==stopAtM1) { sprintf(extraInfo, "Number of M1 cycles reached"), running = false; printf("-----------------------------------------------------------+\r\n"); goto control; } // If the address is tri-stated, skip checking various combinations of // control signals since they may also be floating and we can't detect that if (!abTristated) { // Simulate read from RAM if (!mreq && !rd) { SetDataToDB(ram[ab & 0xFFFF]); if (!m1) sprintf(extraInfo, "Opcode read from %03X -> %02X", ab, ram[ab & 0xFF]); else sprintf(extraInfo, "Memory read from %03X -> %02X", ab, ram[ab & 0xFF]); if (++ab % 0x1000 == 0) printf("%04X\n",ab); } else // Simulate interrupt requesting a vector if (!m1 && !iorq) { SetDataToDB(iorqVector); sprintf(extraInfo, "Pushing vector %02X", iorqVector); } else GetDataFromDB(); // Simulate write to RAM if (!mreq && !wr) { ram[ab & 0xFFFF] = db; sprintf(extraInfo, "Memory write to %03X <- %02X", ab, db); } // Detect I/O read: We don't place anything on the bus if (!iorq && !rd) { sprintf(extraInfo, "I/O read from %03X", ab); } // Detect I/O write if (!iorq && !wr) { sprintf(extraInfo, "I/O write to %03X <- %02X", ab, db); } // Capture memory refresh cycle if (!mreq && !rfsh) { sprintf(extraInfo, "Refresh address %03X", ab); } } else GetDataFromDB(); DumpState(suppressDump); // If the user wanted to pause simulation after a certain number of // clocks, handle it here. If the key pressed to continue was not Enter, // stop the simulation to issue that command if (tracePause==tracePauseCount) { tracePauseCount = 0; } //-------------------------------------------------------- // Clock goes low //-------------------------------------------------------- //delay(1); digitalWrite(CLK, LOW); delay(1); digitalWrite(CLK, LOW); clkCountHi = 0; if (traceShowBothPhases) { ReadControlState(); GetAddressFromAB(); DumpState(suppressDump); } // Perform various actions at the requested clock number // if the count is positive (we start it at -2 to skip initial 2T) if (clkCount>=0) { if (clkCount==intAtClk) zint = 0; if (clkCount==nmiAtClk) nmi = 0; if (clkCount==busrqAtClk) busrq = 0; if (clkCount==resetAtClk) reset = 0; if (clkCount==waitAtClk) wait = 0; // De-assert all control pins at this clock number if (clkCount==clearAtClk) zint = nmi = busrq = reset = wait = 1; WriteControlPins(); // Stop the simulation under some conditions if (clkCount==stopAtClk) sprintf(extraInfo, "Number of clocks reached"), running = false; if (stopAtHalt&!halt) sprintf(extraInfo, "HALT instruction"), running = false; } //-------------------------------------------------------- // Trace/simulation control handler //-------------------------------------------------------- control: if (!running) { printf(":Simulation stopped: %s\r\n", extraInfo); extraInfo[0] = 0; digitalWrite(CLK, HIGH); zint = nmi = busrq = wait = 1; WriteControlPins(); while(!running) { // Expect a command from the serial port // if (Serial.available()>0) { memset((void *)temp, 0, TEMP_SIZE); gets(temp); //Serial.readBytesUntil('\r', temp, TEMP_SIZE-1); // Option ":" : this is not really a user option. This is used to // Intel HEX format values into the RAM buffer // Multiple lines may be pasted. They are separated by a space character. char *pTemp = temp; while (*pTemp==':') { byte bytes = hexFromTemprintf(pTemp, 0); if (bytes>0) { int address = (hexFromTemprintf(pTemp, 1)<<8) + hexFromTemprintf(pTemp, 2); byte recordType = hexFromTemprintf(pTemp, 3); printf("%04X:", address); for (i=0; i<bytes; i++) { ram[(address + i) & 0xFF] = hexFromTemprintf(pTemp, 4+i); printf(" %02X", hexFromTemprintf(pTemp, 4+i)); } printf("\r\n"); } pTemp += bytes*2 + 12; // Skip to the next possible line of hex entry } // Option "r" : reset and run the simulation if (temp[0]=='r') { // If the variable 9 (Issue RESET) is not set, perform a RESET and run the simulation. // If the variable was set, skip reset sequence since we might be testing it. if (resetAtClk<0) DoReset(); running = true; } // Option "sc" : clear simulation variables to their default values if (temp[0]=='s' && temp[1]=='c') { ResetSimulationVars(); temp[1] = 0; // Proceed to dump all variables... } // Option "s" : show and set internal control variables if (temp[0]=='s' && temp[1]!='c') { // Show or set the simulation parameters int var = 0, value; int args = sscanf(&temp[1], "%d %d\r\n", &var, &value); // Parameter for the option #12 is read in as a hex; others are decimal by default if (var==12) args = sscanf(&temp[1], "%d %x\r\n", &var, &value); if (args==2) { if (var==0) traceShowBothPhases = value; if (var==1) traceRefresh = value; if (var==2) tracePause = value; if (var==3) stopAtClk = value; if (var==4) stopAtM1 = value; if (var==5) stopAtHalt = value; if (var==6) intAtClk = value; if (var==7) nmiAtClk = value; if (var==8) busrqAtClk = value; if (var==9) resetAtClk = value; if (var==10) waitAtClk = value; if (var==11) clearAtClk = value; if (var==12) iorqVector = value & 0xFF; } printf("------ Simulation variables ------\r\n"); printf("#0 Trace both clock phases = %d\r\n", traceShowBothPhases); printf("#1 Trace refresh cycles = %d\r\n", traceRefresh); printf("#2 Pause for keypress every = %d\r\n", tracePause); printf("#3 Stop after clock # = %d\r\n", stopAtClk); printf("#4 Stop after # M1 cycles = %d\r\n", stopAtM1); printf("#5 Stop at HALT = %d\r\n", stopAtHalt); printf("#6 Issue INT at clock # = %d\r\n", intAtClk); printf("#7 Issue NMI at clock # = %d\r\n", nmiAtClk); printf("#8 Issue BUSRQ at clock # = %d\r\n", busrqAtClk); printf("#9 Issue RESET at clock # = %d\r\n", resetAtClk); printf("#10 Issue WAIT at clock # = %d\r\n", waitAtClk); printf("#11 Clear all at clock # = %d\r\n", clearAtClk); printf("#12 Push IORQ vector #(hex) = %2X\r\n", iorqVector); } // Option "m" : dump RAM memory if (temp[0]=='m' && temp[1]!='c') { // Dump the content of a RAM buffer printf(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\r\n"); printf(" +-----------------------------------------------\r\n"); for(i=0; i<16; i++) { printf("%02X |", i); for(j=0; j<16; j++) { printf("%02X ", ram[i*16+j]); } printf("\r\n"); } } // Option "mc" : clear RAM memory if (temp[0]=='m' && temp[1]=='c') { memset(ram, 0, sizeof(ram)); printf("RAM cleared\r\n"); } // Option "?" : print help if (temp[0]=='?' || temp[0]=='h') { printf("s - show simulation variables\r\n"); printf("s #var value - set simulation variable number to a value\r\n"); printf("sc - clear simulation variables to their default values\r\n"); printf("r - restart the simulation\r\n"); printf(":INTEL-HEX - reload RAM buffer with a given data stream\r\n"); printf("m - dump the content of the RAM buffer\r\n"); printf("mc - clear the RAM buffer\r\n"); } } } } //return 0; } // main
bool CSimulation2Impl::Update(int turnLength, const std::vector<SimulationCommand>& commands) { fixed turnLengthFixed = fixed::FromInt(turnLength) / 1000; // TODO: the update process is pretty ugly, with lots of messages and dependencies // between different components. Ought to work out a nicer way to do this. CMessageTurnStart msgTurnStart; m_ComponentManager.BroadcastMessage(msgTurnStart); CmpPtr<ICmpPathfinder> cmpPathfinder(m_SimContext, SYSTEM_ENTITY); if (!cmpPathfinder.null()) cmpPathfinder->FinishAsyncRequests(); // Push AI commands onto the queue before we use them CmpPtr<ICmpAIManager> cmpAIManager(m_SimContext, SYSTEM_ENTITY); if (!cmpAIManager.null()) cmpAIManager->PushCommands(); CmpPtr<ICmpCommandQueue> cmpCommandQueue(m_SimContext, SYSTEM_ENTITY); if (!cmpCommandQueue.null()) cmpCommandQueue->FlushTurn(commands); // Process newly generated move commands so the UI feels snappy if (!cmpPathfinder.null()) cmpPathfinder->ProcessSameTurnMoves(); // Send all the update phases { CMessageUpdate msgUpdate(turnLengthFixed); m_ComponentManager.BroadcastMessage(msgUpdate); } { CMessageUpdate_MotionFormation msgUpdate(turnLengthFixed); m_ComponentManager.BroadcastMessage(msgUpdate); } // Process move commands for formations (group proxy) if (!cmpPathfinder.null()) cmpPathfinder->ProcessSameTurnMoves(); { CMessageUpdate_MotionUnit msgUpdate(turnLengthFixed); m_ComponentManager.BroadcastMessage(msgUpdate); } { CMessageUpdate_Final msgUpdate(turnLengthFixed); m_ComponentManager.BroadcastMessage(msgUpdate); } // Process moves resulting from group proxy movement (unit needs to catch up or realign) and any others if (!cmpPathfinder.null()) cmpPathfinder->ProcessSameTurnMoves(); // Clean up any entities destroyed during the simulation update m_ComponentManager.FlushDestroyedComponents(); // if (m_TurnNumber == 0) // m_ComponentManager.GetScriptInterface().DumpHeap(); // Run the GC occasionally // (TODO: we ought to schedule this for a frame where we're not // running the sim update, to spread the load) if (m_TurnNumber % 10 == 0) m_ComponentManager.GetScriptInterface().MaybeGC(); if (m_EnableOOSLog) DumpState(); // Start computing AI for the next turn if (!cmpAIManager.null()) cmpAIManager->StartComputation(); ++m_TurnNumber; return true; // TODO: don't bother with bool return }
int DumpState( const Options &opts, const ReadUserLog::FileState &state, const FieldData *wdata ) { ReadUserLogState rstate( state, 60 ); const ReadUserLogState::FileState *istate; ReadUserLogState::convertState( state, istate ); if ( NULL == wdata ) { wdata = opts.getField( ); } switch( wdata->m_field ) { case FIELD_NONE: return -1; break; case FIELD_SIGNATURE: printf( " %s: '%s'\n", wdata->m_name, istate->m_signature ); break; case FIELD_VERSION: printf( " %s: %d\n", wdata->m_name, istate->m_version ); break; case FIELD_UPDATE_TIME: if ( opts.getNumeric() ) { printf( " %s: %lu\n", wdata->m_name, (long unsigned) istate->m_update_time ); } else { printf( " %s: '%s'\n", wdata->m_name, timestr(istate->m_update_time) ); } break; case FIELD_BASE_PATH: printf( " %s: '%s'\n", wdata->m_name, istate->m_base_path ); break; case FIELD_CUR_PATH: printf( " %s: '%s'\n", wdata->m_name, rstate.CurPath(state) ); break; case FIELD_UNIQ_ID: printf( " %s: '%s'\n", wdata->m_name, istate->m_uniq_id ); break; case FIELD_SEQUENCE: printf( " %s: %d\n", wdata->m_name, istate->m_sequence ); break; case FIELD_MAX_ROTATION: printf( " %s: %d\n", wdata->m_name, istate->m_max_rotations ); break; case FIELD_ROTATION: printf( " %s: %d\n", wdata->m_name, istate->m_rotation ); break; case FIELD_OFFSET: printf( " %s: " FILESIZE_T_FORMAT "\n", wdata->m_name, istate->m_offset.asint ); break; case FIELD_EVENT_NUM: printf( " %s: " FILESIZE_T_FORMAT "\n", wdata->m_name, istate->m_event_num.asint ); break; case FIELD_GLOBAL_POSITION: printf( " %s: " FILESIZE_T_FORMAT "\n", wdata->m_name, istate->m_log_position.asint ); break; case FIELD_GLOBAL_RECORD_NUM: printf( " %s: " FILESIZE_T_FORMAT "\n", wdata->m_name, istate->m_log_record.asint ); break; case FIELD_INODE: printf( " %s: %lu\n", wdata->m_name, (long unsigned) istate->m_inode ); break; case FIELD_CTIME: if ( opts.getNumeric() ) { printf( " %s: %lu\n", wdata->m_name, (long unsigned) istate->m_ctime ); } else { printf( " %s: '%s'\n", wdata->m_name, timestr(istate->m_ctime) ); } break; case FIELD_SIZE: printf( " %s: " FILESIZE_T_FORMAT "\n", wdata->m_name, istate->m_size.asint ); break; case FIELD_ALL: DumpState( opts, state, opts.lookupField(FIELD_SIGNATURE) ); DumpState( opts, state, opts.lookupField(FIELD_VERSION) ); DumpState( opts, state, opts.lookupField(FIELD_UPDATE_TIME) ); DumpState( opts, state, opts.lookupField(FIELD_BASE_PATH) ); DumpState( opts, state, opts.lookupField(FIELD_CUR_PATH) ); DumpState( opts, state, opts.lookupField(FIELD_UNIQ_ID) ); DumpState( opts, state, opts.lookupField(FIELD_SEQUENCE) ); DumpState( opts, state, opts.lookupField(FIELD_MAX_ROTATION) ); DumpState( opts, state, opts.lookupField(FIELD_ROTATION) ); DumpState( opts, state, opts.lookupField(FIELD_OFFSET) ); DumpState( opts, state, opts.lookupField(FIELD_EVENT_NUM) ); DumpState( opts, state, opts.lookupField(FIELD_GLOBAL_POSITION) ); DumpState( opts, state, opts.lookupField(FIELD_GLOBAL_RECORD_NUM) ); DumpState( opts, state, opts.lookupField(FIELD_INODE) ); DumpState( opts, state, opts.lookupField(FIELD_CTIME) ); DumpState( opts, state, opts.lookupField(FIELD_SIZE) ); break; default: return -1; } return 0; }
int doit(void) { int i ; double value; cvodeSettings_t *settings ; variableIndex_t *s1, *s2; integratorInstance_t *integratorInstanceA; integratorInstance_t *integratorInstanceB; odeModel_t *model = ODEModel_createFromFile("basic-model1-forward-l2.xml"); RETURN_ON_ERRORS_WITH(1); s1 = ODEModel_getVariableIndex(model, "S1"); s2 = ODEModel_getVariableIndex(model, "S2"); RETURN_ON_ERRORS_WITH(1); /* Creating settings with default values */ settings = CvodeSettings_create(); /* Setting end time to .1, number of time steps to 1 and NULL instead of an optional predefined time series (double *); due to Indefinitely == 1, Printstep 1 will be ignored and Time = 0.1 will be used as timestep for infinite integration */ CvodeSettings_setTime(settings, .1, 1); /* Setting Cvode Parameters: absolute and relative tolerances and maximal internal step */ CvodeSettings_setErrors(settings, 1e-18, 1e-14, 500); /* Setting Integration Switches: see documentation or example simpleIntegratorInstance.c for details on the passed values */ CvodeSettings_setSwitches(settings, 1, 1, 0, 0, 0, 0, 0); /* use compiled model */ CvodeSettings_setCompileFunctions(settings, 0); /* Generate two independent integrator instances from the same odeModel and cvodeSettings */ integratorInstanceA = IntegratorInstance_create(model, settings); RETURN_ON_ERRORS_WITH(1); integratorInstanceB = IntegratorInstance_create(model, settings); RETURN_ON_ERRORS_WITH(1); DumpState(integratorInstanceA, integratorInstanceB, s1, s2); for (i=0; i != 30; i++) { /* run integrations A and B */ IntegratorInstance_integrateOneStep(integratorInstanceA); RETURN_ON_ERRORS_WITH(1); IntegratorInstance_integrateOneStep(integratorInstanceB); RETURN_ON_ERRORS_WITH(1); /* While variable s1 from integration A is between 1e-15 and 1e-16, set variables s1 and s2 in integration B to some value. This function also takes care of creating and freeing CVODE solver structures when ODE variables are changed! */ value = IntegratorInstance_getVariableValue(integratorInstanceA, s1); if ( value < 1.e-15 && value > 1.e-16 ) { IntegratorInstance_setVariableValue(integratorInstanceB, s1,1.5e-15); IntegratorInstance_setVariableValue(integratorInstanceB, s2,1.5e-15); } DumpState(integratorInstanceA, integratorInstanceB, s1, s2); } IntegratorInstance_free(integratorInstanceA); IntegratorInstance_free(integratorInstanceB); VariableIndex_free(s1); VariableIndex_free(s2); ODEModel_free(model); CvodeSettings_free(settings); return 0; }
int main(void) { #if defined(KrnStatMemory) #if defined(__AROSPLATFORM_SMP__) void *ExecLockBase = OpenResource("execlock.resource"); #endif APTR KernelBase; struct Task *me; ULONG page; struct MemHeader *TestArea; ULONG TestLength; struct MemChunk *mc; APTR region1, region2, region3, region4; KernelBase = OpenResource("kernel.resource"); if (!KernelBase) { printf("Failed to open kernel.resource!\n"); return 1; } if (!KrnStatMemory(0, KMS_PageSize, &page, TAG_DONE)) { printf("MMU support is not implemented for this system!\n" "kernel.resource memory allocator will not work!\n"); return 1; } printf("System page size: %u (0x%08X)\n", (unsigned)page, (unsigned)page); TestLength = PAGES_NUM * page; TestArea = AllocMem(TestLength, MEMF_ANY); printf("Allocated test region (%u bytes) at 0x%p\n", (unsigned)TestLength, TestArea); if (!TestArea) { printf("Failed to allocate test region!\n"); return 1; } /* Install trap handler */ me = FindTask(NULL); me->tc_TrapCode = TrapHandler; /* Compose a MemHeader */ TestArea->mh_Node.ln_Succ = NULL; TestArea->mh_Node.ln_Type = NT_MEMORY; TestArea->mh_Node.ln_Name = "Kernel allocator test area"; TestArea->mh_Node.ln_Pri = 127; /* This MemHeader must be the first in the list, otherwise KrnFreePages() will find a wrong one */ TestArea->mh_Attributes = MEMF_FAST; TestArea->mh_Lower = TestArea; TestArea->mh_Upper = TestArea->mh_Lower + TestLength - 1; TestArea->mh_First = TestArea->mh_Lower + MEMHEADER_TOTAL; TestArea->mh_Free = TestLength - MEMHEADER_TOTAL; mc = TestArea->mh_First; mc->mc_Next = NULL; mc->mc_Bytes = TestArea->mh_Free; /* Give up the area to kernel allocator */ KrnInitMemory(TestArea); if (mc->mc_Next || mc->mc_Bytes) { printf("KrnInitMemory() failed:\n" " mc_Next is 0x%p\n" " mc_Bytes is %lu\n", mc->mc_Next, mc->mc_Bytes); goto exit; } printf("Testing initial no-access protection...\n"); TestRead((UBYTE *)TestArea + page); /* * Insert the area into system list. * We do it manually because in future AddMemList() will call KrnInitMemory() itself. */ #if defined(__AROSPLATFORM_SMP__) if (ExecLockBase) ObtainSystemLock(&SysBase->MemList, SPINLOCK_MODE_WRITE, LOCKF_FORBID); else Forbid(); #else Forbid(); #endif Enqueue(&SysBase->MemList, &TestArea->mh_Node); #if defined(__AROSPLATFORM_SMP__) if (ExecLockBase) ReleaseSystemLock(&SysBase->MemList, LOCKF_FORBID); else Permit(); #else Permit(); #endif printf("Allocating region1 (two read-write pages)...\n"); region1 = KrnAllocPages(NULL, 2 * page, MEMF_FAST); printf("region1 at 0x%p\n", region1); DumpState(TestArea); printf("Freeing region1...\n"); KrnFreePages(region1, 2 * page); printf("Done!\n"); DumpState(TestArea); printf("Allocating region1 (3 read-only pages)...\n"); region1 = KrnAllocPages(NULL, 3 * page, MEMF_FAST); printf("region1 at 0x%p\n", region1); DumpState(TestArea); printf("Allocating region2 (4 write-only ;-) pages)...\n"); region2 = KrnAllocPages(NULL, 4 * page, MEMF_FAST); printf("region2 at 0x%p\n", region2); DumpState(TestArea); printf("Attempting to allocate page with wrong flags...\n"); region3 = KrnAllocPages(NULL, page, MEMF_CHIP|MEMF_FAST); printf("Region at 0x%p\n", region3); if (region3) { printf("WARNING!!! This should have been NULL!\n"); KrnFreePages(region3, page); } printf("Freeing region1...\n"); KrnFreePages(region1, 3 * page); printf("Done!\n"); DumpState(TestArea); printf("Freeing region2...\n"); KrnFreePages(region2, 4 * page); printf("Done!\n"); DumpState(TestArea); printf("Allocating region1 (one read-write page)...\n"); region1 = KrnAllocPages(NULL, page, MEMF_FAST); printf("region1 at 0x%p\n", region1); DumpState(TestArea); printf("Freeing region1...\n"); KrnFreePages(region1, page); printf("Done!\n"); DumpState(TestArea); printf("Now we'll try to fragment the memory\n"); printf("Allocating region1 (2 pages)...\n"); region1 = KrnAllocPages(NULL, 2 * page, MEMF_FAST); printf("region1 at 0x%p\n", region1); DumpState(TestArea); printf("Allocating region2 (3 pages)...\n"); region2 = KrnAllocPages(NULL, 3 * page, MEMF_FAST); printf("region2 at 0x%p\n", region2); DumpState(TestArea); printf("Allocating region 3 (1 page)...\n"); region3 = KrnAllocPages(NULL, page, MEMF_FAST); printf("Region at 0x%p\n", region3); DumpState(TestArea); printf("Allocating region 4 (2 pages)...\n"); region4 = KrnAllocPages(NULL, 2 * page, MEMF_FAST); printf("region4 at 0x%p\n", region1); DumpState(TestArea); printf("Freeing region1...\n"); KrnFreePages(region1, 2 * page); printf("Done!\n"); DumpState(TestArea); printf("Freeing region3...\n"); KrnFreePages(region3, page); printf("Done!\n"); DumpState(TestArea); printf("Allocating region 3 (1 page) again...\n"); region3 = KrnAllocPages(NULL, page, MEMF_FAST); printf("Region at 0x%p\n", region3); DumpState(TestArea); printf("Freeing region2...\n"); KrnFreePages(region2, 3 * page); printf("Done!\n"); DumpState(TestArea); printf("Freeing region3...\n"); KrnFreePages(region3, page); printf("Done!\n"); DumpState(TestArea); printf("Freeing region4...\n"); KrnFreePages(region4, 2 * page); printf("Done!\n"); DumpState(TestArea); exit: if (TestArea->mh_Node.ln_Succ) { Forbid(); Remove(&TestArea->mh_Node); Permit(); } FreeMem(TestArea, TestLength); #else printf("The test can't be built for this kernel.resource implementation\n"); #endif return 0; }
void CSimulation2Impl::Update(int turnLength, const std::vector<SimulationCommand>& commands) { PROFILE3("sim update"); PROFILE2_ATTR("turn %d", (int)m_TurnNumber); fixed turnLengthFixed = fixed::FromInt(turnLength) / 1000; /* * In serialization test mode, we save the original (primary) simulation state before each turn update. * We run the update, then load the saved state into a secondary context. * We serialize that again and compare to the original serialization (to check that * serialize->deserialize->serialize is equivalent to serialize). * Then we run the update on the secondary context, and check that its new serialized * state matches the primary context after the update (to check that the simulation doesn't depend * on anything that's not serialized). */ const bool serializationTestDebugDump = false; // set true to save human-readable state dumps before an error is detected, for debugging (but slow) const bool serializationTestHash = true; // set true to save and compare hash of state SerializationTestState primaryStateBefore; ScriptInterface& scriptInterface = m_ComponentManager.GetScriptInterface(); if (m_EnableSerializationTest) { ENSURE(m_ComponentManager.SerializeState(primaryStateBefore.state)); if (serializationTestDebugDump) ENSURE(m_ComponentManager.DumpDebugState(primaryStateBefore.debug, false)); if (serializationTestHash) ENSURE(m_ComponentManager.ComputeStateHash(primaryStateBefore.hash, false)); } UpdateComponents(m_SimContext, turnLengthFixed, commands); if (m_EnableSerializationTest) { // Initialise the secondary simulation CTerrain secondaryTerrain; CSimContext secondaryContext; secondaryContext.m_Terrain = &secondaryTerrain; CComponentManager secondaryComponentManager(secondaryContext, scriptInterface.GetRuntime()); secondaryComponentManager.LoadComponentTypes(); std::set<VfsPath> secondaryLoadedScripts; ENSURE(LoadDefaultScripts(secondaryComponentManager, &secondaryLoadedScripts)); ResetComponentState(secondaryComponentManager, false, false); // Load the trigger scripts after we have loaded the simulation. { JSContext* cx2 = secondaryComponentManager.GetScriptInterface().GetContext(); JSAutoRequest rq2(cx2); JS::RootedValue mapSettingsCloned(cx2, secondaryComponentManager.GetScriptInterface().CloneValueFromOtherContext( scriptInterface, m_MapSettings)); ENSURE(LoadTriggerScripts(secondaryComponentManager, mapSettingsCloned, &secondaryLoadedScripts)); } // Load the map into the secondary simulation LDR_BeginRegistering(); CMapReader* mapReader = new CMapReader; // automatically deletes itself std::string mapType; scriptInterface.GetProperty(m_InitAttributes, "mapType", mapType); if (mapType == "random") { // TODO: support random map scripts debug_warn(L"Serialization test mode does not support random maps"); } else { std::wstring mapFile; scriptInterface.GetProperty(m_InitAttributes, "map", mapFile); VfsPath mapfilename = VfsPath(mapFile).ChangeExtension(L".pmp"); mapReader->LoadMap(mapfilename, scriptInterface.GetJSRuntime(), JS::UndefinedHandleValue, &secondaryTerrain, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &secondaryContext, INVALID_PLAYER, true); // throws exception on failure } LDR_EndRegistering(); ENSURE(LDR_NonprogressiveLoad() == INFO::OK); ENSURE(secondaryComponentManager.DeserializeState(primaryStateBefore.state)); SerializationTestState secondaryStateBefore; ENSURE(secondaryComponentManager.SerializeState(secondaryStateBefore.state)); if (serializationTestDebugDump) ENSURE(secondaryComponentManager.DumpDebugState(secondaryStateBefore.debug, false)); if (serializationTestHash) ENSURE(secondaryComponentManager.ComputeStateHash(secondaryStateBefore.hash, false)); if (primaryStateBefore.state.str() != secondaryStateBefore.state.str() || primaryStateBefore.hash != secondaryStateBefore.hash) { ReportSerializationFailure(&primaryStateBefore, NULL, &secondaryStateBefore, NULL); } SerializationTestState primaryStateAfter; ENSURE(m_ComponentManager.SerializeState(primaryStateAfter.state)); if (serializationTestHash) ENSURE(m_ComponentManager.ComputeStateHash(primaryStateAfter.hash, false)); UpdateComponents(secondaryContext, turnLengthFixed, CloneCommandsFromOtherContext(scriptInterface, secondaryComponentManager.GetScriptInterface(), commands)); SerializationTestState secondaryStateAfter; ENSURE(secondaryComponentManager.SerializeState(secondaryStateAfter.state)); if (serializationTestHash) ENSURE(secondaryComponentManager.ComputeStateHash(secondaryStateAfter.hash, false)); if (primaryStateAfter.state.str() != secondaryStateAfter.state.str() || primaryStateAfter.hash != secondaryStateAfter.hash) { // Only do the (slow) dumping now we know we're going to need to report it ENSURE(m_ComponentManager.DumpDebugState(primaryStateAfter.debug, false)); ENSURE(secondaryComponentManager.DumpDebugState(secondaryStateAfter.debug, false)); ReportSerializationFailure(&primaryStateBefore, &primaryStateAfter, &secondaryStateBefore, &secondaryStateAfter); } } // if (m_TurnNumber == 0) // m_ComponentManager.GetScriptInterface().DumpHeap(); // Run the GC occasionally // No delay because a lot of garbage accumulates in one turn and in non-visual replays there are // much more turns in the same time than in normal games. // Every 500 turns we run a shrinking GC, which decommits unused memory and frees all JIT code. // Based on testing, this seems to be a good compromise between memory usage and performance. // Also check the comment about gcPreserveCode in the ScriptInterface code and this forum topic: // http://www.wildfiregames.com/forum/index.php?showtopic=18466&p=300323 // // (TODO: we ought to schedule this for a frame where we're not // running the sim update, to spread the load) if (m_TurnNumber % 500 == 0) scriptInterface.GetRuntime()->ShrinkingGC(); else scriptInterface.GetRuntime()->MaybeIncrementalGC(0.0f); if (m_EnableOOSLog) DumpState(); // Start computing AI for the next turn CmpPtr<ICmpAIManager> cmpAIManager(m_SimContext, SYSTEM_ENTITY); if (cmpAIManager) cmpAIManager->StartComputation(); ++m_TurnNumber; }