xgc_void XGameMap::CreateClock( xgc_lpcstr lpName, xgc_lpcstr lpStart, xgc_lpcstr lpParam, xgc_lpcstr lpDuration ) { auto it = mMapClock.find( lpName ); if( it != mMapClock.end() ) { USR_WRN( "场景[%s]创建定时器[%s]时发现定时器已存在。", getString( XGameMap::MapIndex ), lpName ); return; } datetime dt_start, dt_close; datetime now = datetime::now(); if( strncasecmp( "relative", lpStart, 8 ) == 0 ) { dt_start = datetime::relative_time( timespan::convert( lpStart + 8 ) ); } else { dt_start = datetime::convert( lpStart ); } timespan ts_duration = lpDuration ? timespan::convert( lpDuration ) : timespan( 0 ); xgc_char szDateTime[64] = { 0 }; DBG_TIP( "场景%s创建定时器%s 触发时间为%s", getString( XGameMap::MapName ), lpName, dt_start.to_string( szDateTime, sizeof( szDateTime ) ) ); auto evt = MakeEvent< XGameMapEvent >( evt_map_clock ); evt->alias = it->first.c_str(); mMapClock[lpName] = getClock().insert( std::bind( (XEventBind3)&XObject::EmmitEvent, this, &evt->cast, DeleteEvent< XGameMapEvent > ), dt_start, ts_duration, lpParam ); }
inline /* static */ timespan timespan::milliseconds( timespan::span_type seconds ) { return timespan(seconds * 1000); }
inline /* static */ timespan timespan::microseconds( timespan::span_type seconds ) { return timespan(seconds); }
inline timespan operator -( timespan const& lhs , timespan const& rhs ) { return timespan(lhs.Microseconds - rhs.Microseconds); }
void MeldInterpretScheduler::SemWaitOrReadDebugMessage() { if (MeldInterpretVM::isInDebuggingMode()) { while(!sem_schedulerStart->tryWait()) { //waitForOneVMCommand(); //checkForReceivedVMCommands(); std::chrono::milliseconds timespan(10); std::this_thread::sleep_for(timespan); } } else { sem_schedulerStart->wait(); } }
//////////////////////////////////////////////////////////////////////////////////////////////////// // client simulator ask about DNS entry //////////////////////////////////////////////////////////////////////////////////////////////////// void client( int tid, int num_threads) { DNSServer* server = DNSServer::get(); std::string domains[] = { "www.ovgu.de", "www.tu-berlin.de"}; int ndomains = 2; for( int i = 0; i < 10; ++i) { std::chrono::milliseconds timespan( rand() % 1000); std::cout << tid << " sleeping for " << timespan.count() << std::endl; std::this_thread::sleep_for(timespan); DNSServer::DNSEntry entry = server->getDNS( domains[i % ndomains]); std::cout << tid << " got " << entry << std::endl; } }
thread seq_receive(ushort uart, ushort udp) { uint len, seq = 0; ulong ticks, time; struct voipPkt *voip; voip = malloc(sizeof(struct voipPkt)); voip->len = 0; enable(); while (TRUE) { /* Read from the UDP device */ len = read(udp, voip, sizeof(struct voipPkt)); if (len > 0) { if (seq < voip->seq) { kprintf("l%d ", seq); //voip->seq + 1); seq = voip->seq; } else if (voip->seq < seq) { kprintf("dup%d", voip->seq); continue; } seq++; //kprintf("%d ms\r\n", timespan(clktime, clkticks, time, ticks)); ticks = clkticks; time = clktime; /* Write to the serial device */ write(uart, voip->buf, voip->len); } else if (timespan(clktime, clkticks, time, ticks) > (SEQ_BUF_SIZE / 8)) { ticks = clkticks; time = clktime; write(uart, voip->buf, voip->len); kprintf("- "); } resched(); } }
//////////////////////////////////////////////////////////////////////////////////////////////////// // admin simulator adds new entrys //////////////////////////////////////////////////////////////////////////////////////////////////// void admin() { DNSServer* server = DNSServer::get(); // put in some new entries std::vector< std::pair< std::string, int > > new_entries; new_entries.push_back(std::pair<std::string,DNSServer::DNSEntry>("www.hu-berlin.de", 141205188)); new_entries.push_back(std::pair<std::string,DNSServer::DNSEntry>("www.fu-berlin.de", 1604517010)); new_entries.push_back(std::pair<std::string,DNSServer::DNSEntry>("www.ethz", 12913219216)); for( auto& entry : new_entries) { std::chrono::milliseconds timespan( rand() % 1000); std::this_thread::sleep_for(timespan); server->newEntry( entry.first, entry.second); } }
timespan timespan::hours( int64_t c ) { return timespan( c * 60 * 60 * 1000 * 1000 ); }
timespan timespan::operator-( void ) const { return timespan(-_delta); }
timespan timespan::minutes( s64 c ) { return timespan( c * 60 * 1000 * 1000 ); }
timespan timespan::operator*( const int times) const{ return timespan( _delta * times ); }
timespan timespan::operator/( const int times) const{ return timespan( _delta / times ); }
timespan timespan::microseconds( int64_t c ) { return timespan( c ); }
timespan timespan::operator-( const timespan& rhs ) const{ return timespan( _delta - rhs._delta ); }
timespan timespan::hours( s64 c ) { return timespan( c * 60 * 60 * 1000 * 1000 ); }
timespan timespan::milliseconds( int64_t c ) { return timespan( c * 1000 ); }
timespan timespan::seconds( s64 c ) { return timespan( c * 1000 * 1000 ); }
timespan timespan::milliseconds( s64 c ) { return timespan( c * 1000 ); }
timespan timespan::days( int64_t c ) { return timespan( c * 24 * 60 * 60 * 1000 * 1000 ); }
timespan timespan::microseconds( s64 c ) { return timespan( c ); }
timespan timestamp::operator-( const timestamp& rhs ) const { return timespan( _tick - rhs._tick ); }
void *MeldInterpretScheduler::startPaused(/*void *param*/) { int seed = 500; srand (seed); bool hasProcessed = false; // 1) world ready // 2) user start order int nbSemWait = 1; //usleep(1000000); OUTPUT << "\033[1;33mScheduler Mode :" << schedulerMode << "\033[0m" << endl; #ifndef TEST_DETER if (MeldInterpretVM::isInDebuggingMode()) { // 3) Debugger "run" nbSemWait = 3; } for (int i = 0; i < nbSemWait; i++) { SemWaitOrReadDebugMessage(); } #else sem_schedulerStart->wait(); schedulerMode = SCHEDULER_MODE_FASTEST; #endif state = RUNNING; //checkForReceivedVMCommands(); multimap<Time, EventPtr>::iterator first, tmp; EventPtr pev; auto systemStartTime = get_time::now(); auto pausedTime = systemStartTime - systemStartTime; // zero by default cout << "\033[1;33m" << "Scheduler : start order received " << 0 << "\033[0m" << endl; switch (schedulerMode) { case SCHEDULER_MODE_FASTEST: OUTPUT << "fastest mode scheduler\n" << endl; //MeldInterpretDebugger::print("Simulation starts in deterministic mode"); while (state != ENDED) { do { while (!eventsMap.empty() || schedulerLength == SCHEDULER_LENGTH_INFINITE) { hasProcessed = true; // lock(); first = eventsMap.begin(); pev = (*first).second; currentDate = pev->date; pev->consume(); StatsCollector::getInstance().incEventsCount(); eventsMap.erase(first); eventsMapSize--; // unlock(); if (state == PAUSED) { if (MeldInterpretVM::isInDebuggingMode()) { //getDebugger()->handleBreakAtTimeReached(currentDate); } else { sem_schedulerStart->wait(); } setState(RUNNING); } // Check that we have not reached the maximum simulation date, if there is one if (currentDate > maximumDate) { cout << "\033[1;33m" << "Scheduler : maximum simulation date (" << maximumDate << ") has been reached. Terminating..." << "\033[0m" << endl; break; } //checkForReceivedVMCommands(); } OUTPUT << "EventMap is empty" << endl; // PTHY: Equilibrium doesn't seem to be working, use SCHEDULER_LENGTH_INFINITE // to keep looping if (eventsMap.empty() && schedulerLength != SCHEDULER_LENGTH_INFINITE) { state = ENDED; break; } if (terminate.load()) { break; } //checkForReceivedVMCommands(); } while (!MeldInterpretVM::equilibrium() || !eventsMap.empty()); if(hasProcessed) { hasProcessed = false; ostringstream s; s << "Equilibrium reached at "<< now() << "us ..."; //MeldInterpretDebugger::print(s.str(), false); /*if (getSimulator()->testMode) { BlinkyBlocks::getWorld()->dump(); stop(0); return 0; }*/ if (MeldInterpretVM::isInDebuggingMode()) { //getDebugger()->handlePauseRequest(); } } //checkForReceivedVMCommands(); } #ifdef TEST_DETER getWorld()->killAllVMs(); exit(0); #endif break; case SCHEDULER_MODE_REALTIME: OUTPUT << "Realtime mode scheduler\n" << endl; //MeldInterpretDebugger::print("Simulation starts in real time mode"); while((state != ENDED && !eventsMap.empty()) || schedulerLength == SCHEDULER_LENGTH_INFINITE) { auto systemCurrentTime = get_time::now() - pausedTime; auto systemCurrentTimeMax = systemCurrentTime - systemStartTime; // currentDate = systemCurrentTimeMax; //checkForReceivedVMCommands(); // while (true) { // // Lock from here, to be sure that the element // // is not destroyed in another thread // // (previously the graphic interface was doing // // it). // lock(); // if (eventsMap.empty()) { // unlock(); // break; // } // first=eventsMap.begin(); // pev = (*first).second; // if(pev->date > systemCurrentTimeMax) { // unlock(); // break; // } // currentDate = pev->date; // pev->consume(); // eventsMap.erase(first); // eventsMapSize--; // unlock(); // //cout << "check to send" << endl; // //checkForReceivedVMCommands(); // //cout << "ok" << endl; // } if (!eventsMap.empty()) { first=eventsMap.begin(); pev = (*first).second; while (!eventsMap.empty() && pev->date <= chrono::duration_cast<us>(systemCurrentTimeMax).count()) { first=eventsMap.begin(); pev = (*first).second; currentDate = pev->date; //lock(); pev->consume(); StatsCollector::getInstance().incEventsCount(); //unlock(); eventsMap.erase(first); eventsMapSize--; } } if (!eventsMap.empty()) { //ev = *(listeEvenements.begin()); first=eventsMap.begin(); pev = (*first).second; } if (state == PAUSED) { cout << "paused" << endl; auto pauseBeginning = get_time::now(); SemWaitOrReadDebugMessage(); setState(RUNNING); pausedTime = get_time::now() - pauseBeginning; } if (!eventsMap.empty() || schedulerLength == SCHEDULER_LENGTH_INFINITE) { std::chrono::milliseconds timespan(5); std::this_thread::sleep_for(timespan); } if (terminate.load()) { break; } } break; default: OUTPUT << "ERROR : Scheduler mode not recognized !!" << endl; } auto systemStopTime = get_time::now(); auto elapsedTime = systemStopTime - systemStartTime; cout << "\033[1;33m" << "Scheduler end : " << chrono::duration_cast<us>(elapsedTime).count() << "\033[0m" << endl; pev.reset(); StatsCollector::getInstance().updateElapsedTime(currentDate, chrono::duration_cast<us>(elapsedTime).count()); StatsCollector::getInstance().setLivingCounters(Event::getNbLivingEvents(), Message::getNbMessages()); StatsCollector::getInstance().setEndEventsQueueSize(eventsMap.size()); // if simulation is a regression testing run, export configuration before leaving if (Simulator::regrTesting && !terminate.load()) getWorld()->exportConfiguration(); // if autoStop is enabled, terminate simulation if (willAutoStop() && !terminate.load()) glutLeaveMainLoop(); printStats(); terminate.store(true); return(NULL); }
timespan timespan::minutes( int64_t c ) { return timespan( c * 60 * 1000 * 1000 ); }
timespan timespan::seconds( int64_t c ) { return timespan( c * 1000 * 1000 ); }
timespan timespan::days( s64 c ) { return timespan( c * 24 * 60 * 60 * 1000 * 1000 ); }