Make use of posix clocks if available.
Have a more general timestamp implementation. Very useful for higher accuracy timings. Modified Files: simgear/structure/subsystem_mgr.cxx simgear/structure/subsystem_mgr.hxx simgear/timing/testtimestamp.cxx simgear/timing/timestamp.cxx simgear/timing/timestamp.hxx
This commit is contained in:
@@ -74,29 +74,27 @@ SGSubsystem::is_suspended () const
|
|||||||
void
|
void
|
||||||
SGSubsystem::printTimingInformation ()
|
SGSubsystem::printTimingInformation ()
|
||||||
{
|
{
|
||||||
SGTimeStamp startTime, endTime;
|
SGTimeStamp startTime;
|
||||||
long duration;
|
|
||||||
for ( eventTimeVecIterator i = timingInfo.begin();
|
for ( eventTimeVecIterator i = timingInfo.begin();
|
||||||
i != timingInfo.end();
|
i != timingInfo.end();
|
||||||
i++) {
|
i++) {
|
||||||
if (i == timingInfo.begin()) {
|
if (i == timingInfo.begin()) {
|
||||||
startTime = i->getTime();
|
startTime = i->getTime();
|
||||||
} else {
|
} else {
|
||||||
endTime = i->getTime();
|
SGTimeStamp endTime = i->getTime();
|
||||||
duration = (endTime - startTime);
|
SG_LOG(SG_GENERAL, SG_ALERT, "- Getting to timestamp : "
|
||||||
|
<< i->getName() << " takes " << endTime - startTime
|
||||||
|
<< " sec.");
|
||||||
startTime = endTime;
|
startTime = endTime;
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "- Getting to timestamp : " << i->getName() << " takes " << duration << " usec.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SGSubsystem::stamp(string name)
|
void SGSubsystem::stamp(const string& name)
|
||||||
{
|
{
|
||||||
SGTimeStamp now;
|
timingInfo.push_back(TimingInfo(name, SGTimeStamp::now()));
|
||||||
now.stamp();
|
|
||||||
timingInfo.push_back(TimingInfo(name, now));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -157,11 +155,10 @@ SGSubsystemGroup::update (double delta_time_sec)
|
|||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < _members.size(); i++)
|
for (unsigned int i = 0; i < _members.size(); i++)
|
||||||
{
|
{
|
||||||
SGTimeStamp start, now;
|
SGTimeStamp timeStamp = SGTimeStamp::now();
|
||||||
start.stamp();
|
|
||||||
_members[i]->update(delta_time_sec); // indirect call
|
_members[i]->update(delta_time_sec); // indirect call
|
||||||
now.stamp();
|
timeStamp = timeStamp - SGTimeStamp::now();
|
||||||
long b = ( now - start );
|
double b = timeStamp.toUSecs();
|
||||||
_members[i]->updateExecutionTime(b);
|
_members[i]->updateExecutionTime(b);
|
||||||
double threshold = _members[i]->getTimeWarningThreshold();
|
double threshold = _members[i]->getTimeWarningThreshold();
|
||||||
if (( b > threshold ) && (b > 10000)) {
|
if (( b > threshold ) && (b > 10000)) {
|
||||||
|
|||||||
@@ -45,9 +45,11 @@ private:
|
|||||||
SGTimeStamp time;
|
SGTimeStamp time;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TimingInfo(string name, SGTimeStamp &t) { eventName = name; time = t;};
|
TimingInfo(const string& name, const SGTimeStamp &t) :
|
||||||
string getName() { return eventName; };
|
eventName(name), time(t)
|
||||||
SGTimeStamp getTime() { return time; };
|
{ }
|
||||||
|
const string& getName() const { return eventName; }
|
||||||
|
const SGTimeStamp& getTime() const { return time; }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef vector<TimingInfo> eventTimeVec;
|
typedef vector<TimingInfo> eventTimeVec;
|
||||||
@@ -271,7 +273,7 @@ public:
|
|||||||
* Place time stamps at strategic points in the execution of subsystems
|
* Place time stamps at strategic points in the execution of subsystems
|
||||||
* update() member functions. Predominantly for debugging purposes.
|
* update() member functions. Predominantly for debugging purposes.
|
||||||
*/
|
*/
|
||||||
void stamp(string name);
|
void stamp(const string& name);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ int main()
|
|||||||
do {
|
do {
|
||||||
nb += 1;
|
nb += 1;
|
||||||
now.stamp();
|
now.stamp();
|
||||||
} while ( ( now - start ) < 5000000 );
|
} while ( ( now - start ).toMicroSeconds() < 5000000 );
|
||||||
|
|
||||||
cout << ( nb / 5 ) << " iterations per seconds. Press ENTER to quit." << endl;
|
cout << ( nb / 5 ) << " iterations per seconds. Press ENTER to quit." << endl;
|
||||||
c = cin.get();
|
c = cin.get();
|
||||||
|
|||||||
@@ -36,12 +36,17 @@
|
|||||||
# include <sys/timeb.h> // for ftime() and struct timeb
|
# include <sys/timeb.h> // for ftime() and struct timeb
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
# include <unistd.h> // for gettimeofday()
|
# include <unistd.h> // for gettimeofday() and the _POSIX_TIMERS define
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SYS_TIME_H
|
#ifdef HAVE_SYS_TIME_H
|
||||||
# include <sys/time.h> // for get/setitimer, gettimeofday, struct timeval
|
# include <sys/time.h> // for get/setitimer, gettimeofday, struct timeval
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(_POSIX_TIMERS) && (0 < _POSIX_TIMERS)
|
||||||
|
# include <time.h>
|
||||||
|
# include <errno.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
# if defined( __CYGWIN__ ) || defined( __CYGWIN32__ )
|
# if defined( __CYGWIN__ ) || defined( __CYGWIN32__ )
|
||||||
@@ -53,43 +58,49 @@
|
|||||||
|
|
||||||
#include "timestamp.hxx"
|
#include "timestamp.hxx"
|
||||||
|
|
||||||
|
|
||||||
void SGTimeStamp::stamp() {
|
void SGTimeStamp::stamp() {
|
||||||
#if defined( WIN32 ) && !defined(__CYGWIN__)
|
#if defined( WIN32 ) && !defined(__CYGWIN__)
|
||||||
unsigned int t;
|
unsigned int t;
|
||||||
t = timeGetTime();
|
t = timeGetTime();
|
||||||
seconds = t / 1000;
|
_sec = t / 1000;
|
||||||
usec = ( t - ( seconds * 1000 ) ) * 1000;
|
_nsec = ( t - ( seconds * 1000 ) ) * 1000 * 1000;
|
||||||
|
#elif defined(_POSIX_TIMERS) && (0 < _POSIX_TIMERS)
|
||||||
|
struct timespec ts;
|
||||||
|
#if defined(_POSIX_MONOTONIC_CLOCK)
|
||||||
|
static clockid_t clockid = CLOCK_MONOTONIC;
|
||||||
|
static bool firstTime = true;
|
||||||
|
if (firstTime) {
|
||||||
|
firstTime = false;
|
||||||
|
// For the first time test if the monotonic clock is available.
|
||||||
|
// If so use this if not use the realtime clock.
|
||||||
|
if (-1 == clock_gettime(clockid, &ts) && errno == EINVAL)
|
||||||
|
clockid = CLOCK_REALTIME;
|
||||||
|
}
|
||||||
|
clock_gettime(clockid, &ts);
|
||||||
|
#else
|
||||||
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
#endif
|
||||||
|
_sec = ts.tv_sec;
|
||||||
|
_nsec = ts.tv_nsec;
|
||||||
#elif defined( HAVE_GETTIMEOFDAY )
|
#elif defined( HAVE_GETTIMEOFDAY )
|
||||||
struct timeval current;
|
struct timeval current;
|
||||||
struct timezone tz;
|
struct timezone tz;
|
||||||
// sg_timestamp currtime;
|
// sg_timestamp currtime;
|
||||||
gettimeofday(¤t, &tz);
|
gettimeofday(¤t, &tz);
|
||||||
seconds = current.tv_sec;
|
_sec = current.tv_sec;
|
||||||
usec = current.tv_usec;
|
_nsec = current.tv_usec * 1000;
|
||||||
#elif defined( HAVE_GETLOCALTIME )
|
#elif defined( HAVE_GETLOCALTIME )
|
||||||
SYSTEMTIME current;
|
SYSTEMTIME current;
|
||||||
GetLocalTime(¤t);
|
GetLocalTime(¤t);
|
||||||
seconds = current.wSecond;
|
_sec = current.wSecond;
|
||||||
usec = current.wMilliseconds * 1000;
|
_nsec = current.wMilliseconds * 1000 * 1000;
|
||||||
#elif defined( HAVE_FTIME )
|
#elif defined( HAVE_FTIME )
|
||||||
struct timeb current;
|
struct timeb current;
|
||||||
ftime(¤t);
|
ftime(¤t);
|
||||||
seconds = current.time;
|
_sec = current.time;
|
||||||
usec = current.millitm * 1000;
|
_nsec = current.millitm * 1000 * 1000;
|
||||||
#else
|
#else
|
||||||
# error Port me
|
# error Port me
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// increment the time stamp by the number of microseconds (usec)
|
|
||||||
SGTimeStamp operator + (const SGTimeStamp& t, const long& m) {
|
|
||||||
return SGTimeStamp( t.seconds + ( t.usec + m ) / 1000000,
|
|
||||||
( t.usec + m ) % 1000000 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// difference between time stamps in microseconds (usec)
|
|
||||||
long operator - (const SGTimeStamp& a, const SGTimeStamp& b)
|
|
||||||
{
|
|
||||||
return 1000000 * (a.seconds - b.seconds) + (a.usec - b.usec);
|
|
||||||
}
|
|
||||||
|
|||||||
+209
-47
@@ -32,81 +32,243 @@
|
|||||||
# error This library requires C++
|
# error This library requires C++
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <iosfwd>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
|
#include <simgear/math/SGCMath.hxx>
|
||||||
|
|
||||||
// MSVC++ 6.0 kuldge - Need forward declaration of friends.
|
|
||||||
class SGTimeStamp;
|
|
||||||
SGTimeStamp operator + (const SGTimeStamp& t, const long& m);
|
|
||||||
long operator - (const SGTimeStamp& a, const SGTimeStamp& b);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The SGTimeStamp class allows you to mark and compare time stamps
|
* The SGTimeStamp class allows you to mark and compare time stamps
|
||||||
* with microsecond accuracy (if your system has support for this
|
* with nanosecond accuracy (if your system has support for this
|
||||||
* level of accuracy.)
|
* level of accuracy).
|
||||||
*
|
*
|
||||||
* The SGTimeStamp is useful for tracking the elapsed time of various
|
* The SGTimeStamp is useful for tracking the elapsed time of various
|
||||||
* events in your program. You can also use it to keep constistant
|
* events in your program. You can also use it to keep constistant
|
||||||
* motion across varying frame rates.
|
* motion across varying frame rates.
|
||||||
|
*
|
||||||
|
* Note SGTimestamp does not deliver the time of day. The content of this
|
||||||
|
* stamps might be, dependent on the implementation, a time to an arbitrary
|
||||||
|
* base time.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class SGTimeStamp {
|
class SGTimeStamp {
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
long seconds;
|
|
||||||
long usec;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
typedef long sec_type;
|
||||||
|
typedef int nsec_type;
|
||||||
|
|
||||||
/** Default constructor */
|
/** Default constructor, initialize time to zero. */
|
||||||
SGTimeStamp();
|
SGTimeStamp() :
|
||||||
|
_sec(0),
|
||||||
|
_nsec(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
/**
|
/** Hmm, might reenable them at some time, but since it is not clear
|
||||||
* This creates an instance of the SGTimeStamp object. When
|
what the input unit of the int is, omit them for now.
|
||||||
* calling the constructor you may provide initial seconds an
|
Use the static constructor functions where it is clear from the method
|
||||||
* microseconds values.
|
name how the arguments are meant.
|
||||||
* @param s initial seconds value
|
|
||||||
* @param m initial microseconds value
|
|
||||||
*/
|
*/
|
||||||
SGTimeStamp( const long s, const long m );
|
// SGTimeStamp(sec_type sec)
|
||||||
|
// { setTime(sec, 0); }
|
||||||
|
// SGTimeStamp(int sec)
|
||||||
|
// { setTime(sec, 0); }
|
||||||
|
// SGTimeStamp(const double& sec)
|
||||||
|
// { setTime(sec); }
|
||||||
|
|
||||||
/** Update stored time to current time (seconds and microseconds) */
|
/** Update stored time to current time (seconds and nanoseconds) */
|
||||||
void stamp();
|
void stamp();
|
||||||
|
|
||||||
/**
|
/** Set the time from a double value */
|
||||||
* Increment the saved time by the specified number of microseconds
|
void setTime(const double& seconds)
|
||||||
* @param t time stamp
|
{
|
||||||
* @param m microseconds increment
|
sec_type wholeSecs = sec_type(floor(seconds));
|
||||||
* @return new time stamp
|
nsec_type reminder;
|
||||||
*/
|
reminder = nsec_type(floor((seconds - wholeSecs)*(1000*1000*1000)));
|
||||||
friend SGTimeStamp operator + (const SGTimeStamp& t, const long& m);
|
setTime(wholeSecs, reminder);
|
||||||
|
}
|
||||||
|
/** Set the time from a seconds/nanoseconds pair */
|
||||||
|
void setTime(sec_type sec, nsec_type nsec)
|
||||||
|
{
|
||||||
|
if (0 <= nsec) {
|
||||||
|
_sec = sec + nsec / (1000*1000*1000);
|
||||||
|
_nsec = nsec % (1000*1000*1000);
|
||||||
|
} else {
|
||||||
|
_sec = sec - 1 + nsec / (1000*1000*1000);
|
||||||
|
_nsec = (1000*1000*1000) + nsec % (1000*1000*1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Subtract two time stamps returning the difference in microseconds.
|
|
||||||
* @param a timestamp 1
|
|
||||||
* @param b timestame 2
|
|
||||||
* @return difference in microseconds
|
|
||||||
*/
|
|
||||||
friend long operator - (const SGTimeStamp& a, const SGTimeStamp& b);
|
|
||||||
|
|
||||||
/** @return the saved seconds of this time stamp */
|
/** @return the saved seconds of this time stamp */
|
||||||
inline long get_seconds() const { return seconds; }
|
long get_seconds() const { return _sec; }
|
||||||
|
|
||||||
/** @return the saved microseconds of this time stamp */
|
/** @return the saved microseconds of this time stamp */
|
||||||
inline long get_usec() const { return usec; }
|
int get_usec() const { return _nsec/1000; }
|
||||||
|
|
||||||
|
/** @return the saved seconds of this time stamp */
|
||||||
|
const sec_type& getSeconds() const
|
||||||
|
{ return _sec; }
|
||||||
|
/** @return the saved nanoseconds of this time stamp */
|
||||||
|
const nsec_type& getNanoSeconds() const
|
||||||
|
{ return _nsec; }
|
||||||
|
|
||||||
|
/** @return the value of the timestamp in nanoseconds,
|
||||||
|
* use doubles to avoid overflow.
|
||||||
|
* If you need real nanosecond accuracy for time differences, build up a
|
||||||
|
* SGTimeStamp reference time and compare SGTimeStamps directly.
|
||||||
|
*/
|
||||||
|
double toNSecs() const
|
||||||
|
{ return _nsec + double(_sec)*1000*1000*1000; }
|
||||||
|
|
||||||
|
/** @return the value of the timestamp in microseconds,
|
||||||
|
* use doubles to avoid overflow.
|
||||||
|
* If you need real nanosecond accuracy for time differences, build up a
|
||||||
|
* SGTimeStamp reference time and compare SGTimeStamps directly.
|
||||||
|
*/
|
||||||
|
double toUSecs() const
|
||||||
|
{ return 1e-3*_nsec + double(_sec)*1000*1000; }
|
||||||
|
|
||||||
|
/** @return the value of the timestamp in milliseconds,
|
||||||
|
* use doubles to avoid overflow.
|
||||||
|
* If you need real nanosecond accuracy for time differences, build up a
|
||||||
|
* SGTimeStamp reference time and compare SGTimeStamps directly.
|
||||||
|
*/
|
||||||
|
double toMSecs() const
|
||||||
|
{ return 1e-6*_nsec + double(_sec)*1000; }
|
||||||
|
|
||||||
|
/** @return the value of the timestamp in seconds,
|
||||||
|
* use doubles to avoid overflow.
|
||||||
|
* If you need real nanosecond accuracy for time differences, build up a
|
||||||
|
* SGTimeStamp reference time and compare SGTimeStamps directly.
|
||||||
|
*/
|
||||||
|
double toSecs() const
|
||||||
|
{ return 1e-9*_nsec + _sec; }
|
||||||
|
|
||||||
|
/** Inplace addition.
|
||||||
|
*/
|
||||||
|
SGTimeStamp& operator+=(const SGTimeStamp& c)
|
||||||
|
{
|
||||||
|
_sec += c._sec;
|
||||||
|
_nsec += c._nsec;
|
||||||
|
if ((1000*1000*1000) <= _nsec) {
|
||||||
|
_nsec -= (1000*1000*1000);
|
||||||
|
_sec += 1;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Inplace subtraction.
|
||||||
|
*/
|
||||||
|
SGTimeStamp& operator-=(const SGTimeStamp& c)
|
||||||
|
{
|
||||||
|
_sec -= c._sec;
|
||||||
|
_nsec -= c._nsec;
|
||||||
|
if (_nsec < 0) {
|
||||||
|
_nsec += (1000*1000*1000);
|
||||||
|
_sec -= 1;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create SGTimeStamps from input with given units
|
||||||
|
*/
|
||||||
|
static SGTimeStamp fromSecMSec(sec_type sec, nsec_type msec)
|
||||||
|
{ return SGTimeStamp(sec, 1000*1000*msec); }
|
||||||
|
static SGTimeStamp fromSecUSec(sec_type sec, nsec_type usec)
|
||||||
|
{ return SGTimeStamp(sec, 1000*usec); }
|
||||||
|
static SGTimeStamp fromSecNSec(sec_type sec, nsec_type nsec)
|
||||||
|
{ return SGTimeStamp(sec, nsec); }
|
||||||
|
|
||||||
|
static SGTimeStamp fromSec(int sec)
|
||||||
|
{ SGTimeStamp ts; ts.setTime(sec); return ts; }
|
||||||
|
static SGTimeStamp fromSec(const double& sec)
|
||||||
|
{ SGTimeStamp ts; ts.setTime(sec); return ts; }
|
||||||
|
static SGTimeStamp fromUSec(nsec_type usec)
|
||||||
|
{ return SGTimeStamp(0, 1000*usec); }
|
||||||
|
static SGTimeStamp fromNSec(nsec_type nsec)
|
||||||
|
{ return SGTimeStamp(0, nsec); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a timestamp with the current time.
|
||||||
|
*/
|
||||||
|
static SGTimeStamp now()
|
||||||
|
{ SGTimeStamp ts; ts.stamp(); return ts; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
SGTimeStamp(sec_type sec, nsec_type nsec)
|
||||||
|
{ setTime(sec, nsec); }
|
||||||
|
|
||||||
|
nsec_type _nsec;
|
||||||
|
sec_type _sec;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline SGTimeStamp::SGTimeStamp() :
|
inline bool
|
||||||
seconds(0),
|
operator==(const SGTimeStamp& c1, const SGTimeStamp& c2)
|
||||||
usec(0)
|
|
||||||
{
|
{
|
||||||
|
if (c1.getNanoSeconds() != c2.getNanoSeconds())
|
||||||
|
return false;
|
||||||
|
return c1.getSeconds() == c2.getSeconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline SGTimeStamp::SGTimeStamp( const long s, const long u ) {
|
inline bool
|
||||||
seconds = s;
|
operator!=(const SGTimeStamp& c1, const SGTimeStamp& c2)
|
||||||
usec = u;
|
{ return !operator==(c1, c2); }
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
operator<(const SGTimeStamp& c1, const SGTimeStamp& c2)
|
||||||
|
{
|
||||||
|
if (c1.getSeconds() < c2.getSeconds())
|
||||||
|
return true;
|
||||||
|
if (c1.getSeconds() > c2.getSeconds())
|
||||||
|
return false;
|
||||||
|
return c1.getNanoSeconds() < c2.getNanoSeconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
operator>(const SGTimeStamp& c1, const SGTimeStamp& c2)
|
||||||
|
{ return c2 < c1; }
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
operator>=(const SGTimeStamp& c1, const SGTimeStamp& c2)
|
||||||
|
{ return !(c1 < c2); }
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
operator<=(const SGTimeStamp& c1, const SGTimeStamp& c2)
|
||||||
|
{ return !(c1 > c2); }
|
||||||
|
|
||||||
|
inline SGTimeStamp
|
||||||
|
operator+(const SGTimeStamp& c1)
|
||||||
|
{ return c1; }
|
||||||
|
|
||||||
|
inline SGTimeStamp
|
||||||
|
operator-(const SGTimeStamp& c1)
|
||||||
|
{ return SGTimeStamp::fromSec(0) -= c1; }
|
||||||
|
|
||||||
|
inline SGTimeStamp
|
||||||
|
operator+(const SGTimeStamp& c1, const SGTimeStamp& c2)
|
||||||
|
{ return SGTimeStamp(c1) += c2; }
|
||||||
|
|
||||||
|
inline SGTimeStamp
|
||||||
|
operator-(const SGTimeStamp& c1, const SGTimeStamp& c2)
|
||||||
|
{ return SGTimeStamp(c1) -= c2; }
|
||||||
|
|
||||||
|
template<typename char_type, typename traits_type>
|
||||||
|
inline
|
||||||
|
std::basic_ostream<char_type, traits_type>&
|
||||||
|
operator<<(std::basic_ostream<char_type, traits_type>& os, const SGTimeStamp& c)
|
||||||
|
{
|
||||||
|
std::basic_stringstream<char_type, traits_type> stream;
|
||||||
|
|
||||||
|
SGTimeStamp pos = c;
|
||||||
|
if (c.getSeconds() < 0) {
|
||||||
|
stream << stream.widen('-');
|
||||||
|
pos = - c;
|
||||||
|
}
|
||||||
|
stream << pos.getSeconds() << stream.widen('.');
|
||||||
|
stream << std::setw(9) << std::setfill('0') << pos.getNanoSeconds();
|
||||||
|
|
||||||
|
return os << stream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _TIMESTAMP_HXX
|
#endif // _TIMESTAMP_HXX
|
||||||
|
|||||||
Reference in New Issue
Block a user