void TimeBasedInput::load(const char * key, const char * value) { int eventId, eventState; float dt; //read a sim start type of switch, type 0 //format //SIMULATION_START eventId eventState if (strcmp(key, "simulation_start") == 0) { if (sscanf(value, " %i %i", &eventId, &eventState)) { dt = 0; inputs.push_back(TimeSpec(0, dt, Event(eventId, eventState))); } } //type 1 //format //REAL_TIME dt eventId eventState if (strcmp(key, "real_time") == 0) { if (sscanf(value, " %f %i %i", &dt, &eventId, &eventState) == 3) { inputs.push_back(TimeSpec(1, dt, Event(eventId, eventState))); } } //type 2 //format //SIM_TIME dt eventId eventState if (strcmp(key, "sim_time") == 0) { if (sscanf(value, " %f %i %i", &dt, &eventId, &eventState) == 3) { inputs.push_back(TimeSpec(2, dt, Event(eventId, eventState))); } } //type 3 //format //SIMULATION_END eventId eventState if (strcmp(key, "simulation_end") == 0) { if (sscanf(value, " %i %i", &eventId, &eventState)) { dt = 0; inputs.push_back(TimeSpec(3, dt, Event(eventId, eventState))); } } }
TimeSpec TimeSpec::operator-(const TimeSpec& other) const { if (ts.tv_nsec < other.ts.tv_nsec) { const timespec ret = {ts.tv_sec - (other.ts.tv_sec + 1), secInNsec + ts.tv_nsec - other.ts.tv_nsec}; assert(ret.tv_sec >= 0); return TimeSpec(ret); } else { const timespec ret = {ts.tv_sec - other.ts.tv_sec, ts.tv_nsec - other.ts.tv_nsec}; assert(ret.tv_sec >= 0); return TimeSpec(ret); } }
int GSemaphoreImpl::Wait(long Timeout) { int status; // Process wait based on desired timeout behavior. switch (Timeout) { // No wait specified, don't block. case 0: status = sem_trywait(&m_Semaphore); break; // Wait forever. case -1: do { status = sem_wait(&m_Semaphore); } while ((status < 0) && ((EAGAIN == errno) || (EINTR == errno))); break; // Wait with timeout. default: struct timespec stTimeout; TimeSpec(Timeout, &stTimeout); do { status = sem_timedwait(&m_Semaphore, &stTimeout); } while ((status < 0) && ((EAGAIN == errno) || (EINTR == errno))); break; } // Return semaphore acquisition status. return (status == 0)? 1 : 0; }
TimeSpec TimeSpec::RealNow() { struct TimeSpec now; if (0 == clock_gettime(CLOCK_REALTIME, &now)) return now; gLog.Optional(Log::Critical, "clock_gettime(CLOCK_REALTIME) failed.%s", ErrnoToString()); LogAssertFalse("clock_gettime(CLOCK_REALTIME) failed"); return TimeSpec(); }
TimeSpec TimeSpec::MonoNow() { struct TimeSpec now; if (0 == clock_gettime(CLOCK_MONOTONIC, &now)) return now; gLog.Optional(Log::Critical, "clock_gettime(CLOCK_MONOTONIC) failed.%s", ErrnoToString()); LogAssertFalse("clock_gettime(CLOCK_MONOTONIC) failed"); return TimeSpec(); }
/** * Helper for Run(). * * Gets the timeout period between now and the next timer. * * @return - The timeout value */ TimeSpec SchedulerBase::getNextTimerTimeout() { // // Calculate next scheduled timer time. // if (m_activeTimers.empty()) { // Just for laughs ... and because we do not run on low power machines, wake up // every few seconds. return TimeSpec(3,0); } TimeSpec now(TimeSpec::MonoNow()); if (now.empty()) return TimeSpec(TimeSpec::Millisec, 200); // 200 ms? TimeSpec result = (*m_activeTimers.begin())->GetExpireTime() - now; if (result.IsNegative()) return TimeSpec(); return result; }
/** * Changes the start and expire time for the timer. * * @param startTime - The time of the last timer start. May be m_startTime. * @param micro - Time to expire from startTime in microseconds. * * @return bool - false on failure. */ bool setExpireTime(const struct timespec &startTime, uint64_t micro) { bool expireChange, startChange; TimeSpec expireTime(startTime); expireTime += TimeSpec(TimeSpec::Microsec, micro); startChange = (m_startTime != startTime); expireChange = (m_stopped || m_expireTime != expireTime); //LogOptional(Log::Temp, "Timer %s before change %zu items",m_name, m_activeTimers->size()); if (!expireChange && !startChange) { LogOptional(Log::TimerDetail, "Timer %s no change. %" PRIu64 " microseconds. Expires:%jd:%09ld", m_name, micro, (intmax_t)expireTime.tv_sec, expireTime.tv_nsec ); return true; } LogOptional(Log::TimerDetail, "%s timer %s for %" PRIu64 " microseconds from %jd:%09ld. Expires:%jd:%09ld", m_stopped ? "Starting": startChange ? "Resetting":"Advancing", m_name, micro, (intmax_t)startTime.tv_sec, startTime.tv_nsec, (intmax_t)expireTime.tv_sec, expireTime.tv_nsec ); // Start time does not effect sorting in active timer list, so we can set it now. // Stopped also should not matter. if (startChange) m_startTime = startTime; m_stopped = false; if (expireChange) { SchedulerBase::timer_set_it found = m_activeTimers->find(this); if (found != m_activeTimers->end()) { if (!willTimerBeSorted(found, expireTime)) { m_activeTimers->erase(found); found = m_activeTimers->end(); // cause it to be added back } } // Actually set the time m_expireTime = expireTime; if (found == m_activeTimers->end()) { try { m_activeTimers->insert(this); } catch (std::exception &e) { m_stopped = true; gLog.Message(Log::Error, "Failed to add timer: %s.", e.what()); return false; } } } //LogOptional(Log::Temp, "Timer %s after change %zu items",m_name, m_activeTimers->size()); return true; }
TimeSpec TimeSpec::operator+(const TimeSpec& other) const { const timespec ret = {ts.tv_sec + other.ts.tv_sec + (ts.tv_nsec + other.ts.tv_nsec) / secInNsec, (ts.tv_nsec + other.ts.tv_nsec) % secInNsec}; return TimeSpec(ret); }