Merge branch 'master' into 3D-NN-walkers-example

This commit is contained in:
Benelot
2017-05-28 15:10:45 +02:00
895 changed files with 953183 additions and 13171 deletions

View File

@@ -0,0 +1,272 @@
#include "ChromeTraceUtil.h"
#include "b3Clock.h"
#include "LinearMath/btQuickprof.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "Bullet3Common/b3Logging.h"
struct btTiming
{
const char* m_name;
int m_threadId;
unsigned long long int m_usStartTime;
unsigned long long int m_usEndTime;
};
FILE* gTimingFile = 0;
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif //__STDC_FORMAT_MACROS
//see http://stackoverflow.com/questions/18107426/printf-format-for-unsigned-int64-on-windows
#ifndef _WIN32
#include <inttypes.h>
#endif
#define BT_TIMING_CAPACITY 16*65536
static bool m_firstTiming = true;
struct btTimings
{
btTimings()
:m_numTimings(0),
m_activeBuffer(0)
{
}
void flush()
{
for (int i = 0; i<m_numTimings; i++)
{
const char* name = m_timings[m_activeBuffer][i].m_name;
int threadId = m_timings[m_activeBuffer][i].m_threadId;
unsigned long long int startTime = m_timings[m_activeBuffer][i].m_usStartTime;
unsigned long long int endTime = m_timings[m_activeBuffer][i].m_usEndTime;
if (!m_firstTiming)
{
fprintf(gTimingFile, ",\n");
}
m_firstTiming = false;
unsigned long long int startTimeDiv1000 = startTime / 1000;
unsigned long long int endTimeDiv1000 = endTime / 1000;
#if 0
fprintf(gTimingFile, "{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%" PRIu64 ".123 ,\"ph\":\"B\",\"name\":\"%s\",\"args\":{}},\n",
threadId, startTimeDiv1000, name);
fprintf(gTimingFile, "{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%" PRIu64 ".234 ,\"ph\":\"E\",\"name\":\"%s\",\"args\":{}}",
threadId, endTimeDiv1000, name);
#else
if (startTime>endTime)
{
endTime = startTime;
}
unsigned int startTimeRem1000 = startTime % 1000;
unsigned int endTimeRem1000 = endTime % 1000;
char startTimeRem1000Str[16];
char endTimeRem1000Str[16];
if (startTimeRem1000<10)
{
sprintf(startTimeRem1000Str, "00%d", startTimeRem1000);
}
else
{
if (startTimeRem1000<100)
{
sprintf(startTimeRem1000Str, "0%d", startTimeRem1000);
}
else
{
sprintf(startTimeRem1000Str, "%d", startTimeRem1000);
}
}
if (endTimeRem1000<10)
{
sprintf(endTimeRem1000Str, "00%d", endTimeRem1000);
}
else
{
if (endTimeRem1000<100)
{
sprintf(endTimeRem1000Str, "0%d", endTimeRem1000);
}
else
{
sprintf(endTimeRem1000Str, "%d", endTimeRem1000);
}
}
char newname[1024];
static int counter2 = 0;
sprintf(newname, "%s%d", name, counter2++);
#ifdef _WIN32
fprintf(gTimingFile, "{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%I64d.%s ,\"ph\":\"B\",\"name\":\"%s\",\"args\":{}},\n",
threadId, startTimeDiv1000, startTimeRem1000Str, newname);
fprintf(gTimingFile, "{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%I64d.%s ,\"ph\":\"E\",\"name\":\"%s\",\"args\":{}}",
threadId, endTimeDiv1000, endTimeRem1000Str, newname);
#else
fprintf(gTimingFile, "{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%" PRIu64 ".%s ,\"ph\":\"B\",\"name\":\"%s\",\"args\":{}},\n",
threadId, startTimeDiv1000, startTimeRem1000Str, newname);
fprintf(gTimingFile, "{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%" PRIu64 ".%s ,\"ph\":\"E\",\"name\":\"%s\",\"args\":{}}",
threadId, endTimeDiv1000, endTimeRem1000Str, newname);
#endif
#endif
}
m_numTimings = 0;
}
void addTiming(const char* name, int threadId, unsigned long long int startTime, unsigned long long int endTime)
{
if (m_numTimings >= BT_TIMING_CAPACITY)
{
return;
}
if (m_timings[0].size() == 0)
{
m_timings[0].resize(BT_TIMING_CAPACITY);
}
int slot = m_numTimings++;
m_timings[m_activeBuffer][slot].m_name = name;
m_timings[m_activeBuffer][slot].m_threadId = threadId;
m_timings[m_activeBuffer][slot].m_usStartTime = startTime;
m_timings[m_activeBuffer][slot].m_usEndTime = endTime;
}
int m_numTimings;
int m_activeBuffer;
btAlignedObjectArray<btTiming> m_timings[1];
};
#ifndef BT_NO_PROFILE
btTimings gTimings[BT_QUICKPROF_MAX_THREAD_COUNT];
#define MAX_NESTING 1024
int gStackDepths[BT_QUICKPROF_MAX_THREAD_COUNT] = { 0 };
const char* gFuncNames[BT_QUICKPROF_MAX_THREAD_COUNT][MAX_NESTING];
unsigned long long int gStartTimes[BT_QUICKPROF_MAX_THREAD_COUNT][MAX_NESTING];
#endif
btClock clk;
bool gProfileDisabled = true;
void MyDummyEnterProfileZoneFunc(const char* msg)
{
}
void MyDummyLeaveProfileZoneFunc()
{
}
void MyEnterProfileZoneFunc(const char* msg)
{
if (gProfileDisabled)
return;
#ifndef BT_NO_PROFILE
int threadId = btQuickprofGetCurrentThreadIndex2();
if (threadId<0)
return;
if (gStackDepths[threadId] >= MAX_NESTING)
{
btAssert(0);
return;
}
gFuncNames[threadId][gStackDepths[threadId]] = msg;
gStartTimes[threadId][gStackDepths[threadId]] = clk.getTimeNanoseconds();
if (gStartTimes[threadId][gStackDepths[threadId]] <= gStartTimes[threadId][gStackDepths[threadId] - 1])
{
gStartTimes[threadId][gStackDepths[threadId]] = 1 + gStartTimes[threadId][gStackDepths[threadId] - 1];
}
gStackDepths[threadId]++;
#endif
}
void MyLeaveProfileZoneFunc()
{
if (gProfileDisabled)
return;
#ifndef BT_NO_PROFILE
int threadId = btQuickprofGetCurrentThreadIndex2();
if (threadId<0)
return;
if (gStackDepths[threadId] <= 0)
{
return;
}
gStackDepths[threadId]--;
const char* name = gFuncNames[threadId][gStackDepths[threadId]];
unsigned long long int startTime = gStartTimes[threadId][gStackDepths[threadId]];
unsigned long long int endTime = clk.getTimeNanoseconds();
gTimings[threadId].addTiming(name, threadId, startTime, endTime);
#endif //BT_NO_PROFILE
}
void b3ChromeUtilsStartTimings()
{
m_firstTiming = true;
gProfileDisabled = false;//true;
b3SetCustomEnterProfileZoneFunc(MyEnterProfileZoneFunc);
b3SetCustomLeaveProfileZoneFunc(MyLeaveProfileZoneFunc);
//also for Bullet 2.x API
btSetCustomEnterProfileZoneFunc(MyEnterProfileZoneFunc);
btSetCustomLeaveProfileZoneFunc(MyLeaveProfileZoneFunc);
}
void b3ChromeUtilsStopTimingsAndWriteJsonFile(const char* fileNamePrefix)
{
b3SetCustomEnterProfileZoneFunc(MyDummyEnterProfileZoneFunc);
b3SetCustomLeaveProfileZoneFunc(MyDummyLeaveProfileZoneFunc);
//also for Bullet 2.x API
btSetCustomEnterProfileZoneFunc(MyDummyEnterProfileZoneFunc);
btSetCustomLeaveProfileZoneFunc(MyDummyLeaveProfileZoneFunc);
char fileName[1024];
static int fileCounter = 0;
sprintf(fileName,"%s_%d.json",fileNamePrefix, fileCounter++);
gTimingFile = fopen(fileName,"w");
fprintf(gTimingFile,"{\"traceEvents\":[\n");
//dump the content to file
for (int i=0;i<BT_QUICKPROF_MAX_THREAD_COUNT;i++)
{
if (gTimings[i].m_numTimings)
{
printf("Writing %d timings for thread %d\n", gTimings[i].m_numTimings, i);
gTimings[i].flush();
}
}
fprintf(gTimingFile,"\n],\n\"displayTimeUnit\": \"ns\"}");
fclose(gTimingFile);
gTimingFile = 0;
}
void b3ChromeUtilsEnableProfiling()
{
gProfileDisabled = false;
}

View File

@@ -0,0 +1,9 @@
#ifndef B3_CHROME_TRACE_UTIL_H
#define B3_CHROME_TRACE_UTIL_H
void b3ChromeUtilsStartTimings();
void b3ChromeUtilsStopTimingsAndWriteJsonFile(const char* fileNamePrefix);
void b3ChromeUtilsEnableProfiling();
#endif//B3_CHROME_TRACE_UTIL_H

View File

@@ -0,0 +1,275 @@
#include "RobotLoggingUtil.h"
#include <stdio.h>
#include "LinearMath/btAlignedObjectArray.h"
#include "../Importers/ImportURDFDemo/urdfStringSplit.h"
static bool readLine(FILE* file, btAlignedObjectArray<char>& line)
{
int c = 0;
for (c=fgetc(file);(c != EOF && c != '\n');c=fgetc(file))
{
line.push_back(c);
}
line.push_back(0);
return (c == EOF);
}
int readMinitaurLogFile(const char* fileName, btAlignedObjectArray<std::string>& structNames, std::string& structTypes, btAlignedObjectArray<MinitaurLogRecord>& logRecords, bool verbose)
{
int retVal = 0;
FILE* f = fopen(fileName,"rb");
if (f)
{
if (verbose)
{
printf("Opened file %s\n", fileName);
}
btAlignedObjectArray<char> line0Buf;
bool eof = readLine(f,line0Buf);
btAlignedObjectArray<char> line1Buf;
eof |= readLine(f,line1Buf);
std::string line0 = &line0Buf[0];
structTypes = &line1Buf[0];
btAlignedObjectArray<std::string> separators;
separators.push_back(",");
urdfStringSplit(structNames,line0,separators);
if (verbose)
{
printf("Num Fields = %d\n",structNames.size());
}
btAssert(structTypes.size() == structNames.size());
if (structTypes.size() != structNames.size())
{
retVal = eCorruptHeader;
}
int numStructsRead = 0;
if (structTypes.size() == structNames.size())
{
while (!eof)
{
unsigned char blaat[1024];
size_t s = fread(blaat,2,1,f);
if (s!=1)
{
eof=true;
retVal = eInvalidAABBAlignCheck;
break;
}
if ((blaat[0] != 0xaa) || (blaat[1] != 0xbb))
{
if (verbose)
{
printf("Expected 0xaa0xbb, terminating\n");
}
}
if (verbose)
{
printf("Reading structure %d\n",numStructsRead);
}
MinitaurLogRecord record;
for (int i=0;i<structNames.size();i++)
{
switch (structTypes[i])
{
case 'I':
{
size_t s = fread(blaat,sizeof(int),1,f);
if (s != 1)
{
eof = true;
retVal = eCorruptValue;
break;
}
int v = (int) *(unsigned int*)blaat;
if (s==1)
{
if (verbose)
{
printf("%s = %d\n",structNames[i].c_str(),v);
}
record.m_values.push_back(v);
}
break;
}
case 'i':
{
size_t s = fread(blaat,sizeof(int),1,f);
if (s != 1)
{
eof = true;
retVal = eCorruptValue;
break;
}
int v = *(int*)blaat;
if (s==1)
{
if (verbose)
{
printf("%s = %d\n",structNames[i].c_str(),v);
}
record.m_values.push_back(v);
}
break;
}
case 'f':
{
float v;
size_t s = fread(&v,sizeof(float),1,f);
if (s != 1)
{
eof = true;
break;
}
if (s==1)
{
if (verbose)
{
printf("%s = %f\n",structNames[i].c_str(),v);
}
record.m_values.push_back(v);
}
break;
}
case 'B':
{
char v;
size_t s = fread(&v,sizeof(char),1,f);
if (s != 1)
{
eof = true;
break;
}
if (s==1)
{
if (verbose)
{
printf("%s = %d\n",structNames[i].c_str(),v);
}
record.m_values.push_back(v);
}
break;
}
default:
{
if (verbose)
{
printf("Unknown type\n");
}
retVal = eUnknownType;
btAssert(0);
}
}
}
logRecords.push_back(record);
numStructsRead++;
}
if (verbose)
{
printf("numStructsRead = %d\n",numStructsRead);
}
if (retVal==0)
{
retVal = numStructsRead;
}
}
//read header and
} else
{
if (verbose)
{
printf("Could not open file %s", fileName);
}
retVal = eMinitaurFileNotFound;
}
return retVal;
}
FILE* createMinitaurLogFile(const char* fileName, btAlignedObjectArray<std::string>& structNames, std::string& structTypes)
{
FILE* f = fopen(fileName,"wb");
if (f)
{
for (int i=0;i<structNames.size();i++)
{
int len = strlen(structNames[i].c_str());
fwrite(structNames[i].c_str(),len,1,f);
if (i<structNames.size()-1)
{
fwrite(",",1,1,f);
}
}
int sz = sizeof("\n");
fwrite("\n",sz-1,1,f);
fwrite(structTypes.c_str(),strlen(structTypes.c_str()),1,f);
fwrite("\n",sz-1,1,f);
}
return f;
}
void appendMinitaurLogData(FILE* f, std::string& structTypes, const MinitaurLogRecord& logData)
{
if (f)
{
unsigned char buf[2] = {0xaa,0xbb};
fwrite(buf,2,1,f);
if (structTypes.length() == logData.m_values.size())
{
for (int i=0;i<logData.m_values.size();i++)
{
switch(structTypes[i])
{
case 'i':
case 'I':
{
fwrite(&logData.m_values[i].m_intVal,sizeof(int),1,f);
break;
}
case 'f':
{
fwrite(&logData.m_values[i].m_floatVal,sizeof(float),1,f);
break;
}
case 'B':
{
fwrite(&logData.m_values[i].m_charVal,sizeof(char),1,f);
break;
}
default:
{
}
}
}
}
}
}
void closeMinitaurLogFile(FILE* f)
{
if (f)
{
fclose(f);
}
}

View File

@@ -0,0 +1,54 @@
#ifndef ROBOT_LOGGING_UTIL_H
#define ROBOT_LOGGING_UTIL_H
#include "LinearMath/btAlignedObjectArray.h"
#include <string>
struct MinitaurLogValue
{
MinitaurLogValue()
:m_intVal(0xcdcdcdcd)
{
}
MinitaurLogValue(int iv)
:m_intVal(iv)
{
}
MinitaurLogValue(float fv)
:m_floatVal(fv)
{
}
MinitaurLogValue(char fv)
:m_charVal(fv)
{
}
union
{
char m_charVal;
int m_intVal;
float m_floatVal;
};
};
struct MinitaurLogRecord
{
btAlignedObjectArray<MinitaurLogValue> m_values;
};
enum MINITAUR_LOG_ERROR
{
eMinitaurFileNotFound = -1,
eCorruptHeader = -2,
eUnknownType = -3,
eCorruptValue = -4,
eInvalidAABBAlignCheck = -5,
};
int readMinitaurLogFile(const char* fileName, btAlignedObjectArray<std::string>& structNames, std::string& structTypes, btAlignedObjectArray<MinitaurLogRecord>& logRecords, bool verbose);
FILE* createMinitaurLogFile(const char* fileName, btAlignedObjectArray<std::string>& structNames, std::string& structTypes);
void appendMinitaurLogData(FILE* f, std::string& structTypes, const MinitaurLogRecord& logData);
void closeMinitaurLogFile(FILE* f);
#endif //ROBOT_LOGGING_UTIL_H

View File

@@ -47,8 +47,6 @@ struct b3ClockData
#ifdef B3_USE_WINDOWS_TIMERS
LARGE_INTEGER mClockFrequency;
DWORD mStartTick;
LONGLONG mPrevMilliTime;
LONGLONG mPrevElapsedTime;
LARGE_INTEGER mStartTime;
#else
#ifdef __CELLOS_LV2__
@@ -95,7 +93,6 @@ void b3Clock::reset()
#ifdef B3_USE_WINDOWS_TIMERS
QueryPerformanceCounter(&m_data->mStartTime);
m_data->mStartTick = GetTickCount();
m_data->mPrevElapsedTime = 0;
#else
#ifdef __CELLOS_LV2__
@@ -115,36 +112,14 @@ void b3Clock::reset()
unsigned long int b3Clock::getTimeMilliseconds()
{
#ifdef B3_USE_WINDOWS_TIMERS
LARGE_INTEGER currentTime;
QueryPerformanceCounter(&currentTime);
LONGLONG elapsedTime = currentTime.QuadPart -
m_data->mStartTime.QuadPart;
// Compute the number of millisecond ticks elapsed.
unsigned long msecTicks = (unsigned long)(1000 * elapsedTime /
m_data->mClockFrequency.QuadPart);
// Check for unexpected leaps in the Win32 performance counter.
// (This is caused by unexpected data across the PCI to ISA
// bridge, aka south bridge. See Microsoft KB274323.)
unsigned long elapsedTicks = GetTickCount() - m_data->mStartTick;
signed long msecOff = (signed long)(msecTicks - elapsedTicks);
if (msecOff < -100 || msecOff > 100)
{
// Adjust the starting time forwards.
LONGLONG msecAdjustment = b3ClockMin(msecOff *
m_data->mClockFrequency.QuadPart / 1000, elapsedTime -
m_data->mPrevElapsedTime);
m_data->mStartTime.QuadPart += msecAdjustment;
elapsedTime -= msecAdjustment;
LARGE_INTEGER currentTime, elapsedTime;
QueryPerformanceCounter(&currentTime);
elapsedTime.QuadPart = currentTime.QuadPart -
m_data->mStartTime.QuadPart;
elapsedTime.QuadPart *= 1000;
elapsedTime.QuadPart /= m_data->mClockFrequency.QuadPart;
// Recompute the number of millisecond ticks elapsed.
msecTicks = (unsigned long)(1000 * elapsedTime /
m_data->mClockFrequency.QuadPart);
}
// Store the current elapsed time for adjustments next time.
m_data->mPrevElapsedTime = elapsedTime;
return msecTicks;
return (unsigned long long) elapsedTime.QuadPart;
#else
#ifdef __CELLOS_LV2__
@@ -166,43 +141,54 @@ unsigned long int b3Clock::getTimeMilliseconds()
#endif
}
/// Returns the time in us since the last call to reset or since
/// the Clock was created.
/// Gets the system time in milliseconds
unsigned long int b3Clock::getSystemTimeMilliseconds() {
#ifdef B3_USE_WINDOWS_TIMERS
LARGE_INTEGER currentTime, elapsedTime;
QueryPerformanceCounter(&currentTime);
elapsedTime.QuadPart = currentTime.QuadPart;
elapsedTime.QuadPart *= 1000;
elapsedTime.QuadPart /= m_data->mClockFrequency.QuadPart;
return (unsigned long long) elapsedTime.QuadPart;
#else
#ifdef __CELLOS_LV2__
uint64_t freq = sys_time_get_timebase_frequency();
double dFreq = ((double)freq) / 1000.0;
typedef uint64_t ClockSize;
ClockSize newTime;
SYS_TIMEBASE_GET(newTime);
//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
return (unsigned long int)((double(newTime)) / dFreq);
#else
struct timeval currentTime;
gettimeofday(&currentTime, 0);
return (currentTime.tv_sec) * 1000 +
(currentTime.tv_usec) / 1000;
#endif //__CELLOS_LV2__
#endif
}
/// Returns the time in us since the last call to reset or since
/// the Clock was created.
unsigned long long int b3Clock::getTimeMicroseconds()
{
#ifdef B3_USE_WINDOWS_TIMERS
LARGE_INTEGER currentTime;
//see https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx
LARGE_INTEGER currentTime, elapsedTime;
QueryPerformanceCounter(&currentTime);
LONGLONG elapsedTime = currentTime.QuadPart -
elapsedTime.QuadPart = currentTime.QuadPart -
m_data->mStartTime.QuadPart;
elapsedTime.QuadPart *= 1000000;
elapsedTime.QuadPart /= m_data->mClockFrequency.QuadPart;
// Compute the number of millisecond ticks elapsed.
unsigned long long msecTicks = (unsigned long long)(1000 * elapsedTime /
m_data->mClockFrequency.QuadPart);
// Check for unexpected leaps in the Win32 performance counter.
// (This is caused by unexpected data across the PCI to ISA
// bridge, aka south bridge. See Microsoft KB274323.)
unsigned long long elapsedTicks = GetTickCount() - m_data->mStartTick;
signed long long msecOff = (signed long)(msecTicks - elapsedTicks);
if (msecOff < -100 || msecOff > 100)
{
// Adjust the starting time forwards.
LONGLONG msecAdjustment = b3ClockMin(msecOff *
m_data->mClockFrequency.QuadPart / 1000, elapsedTime -
m_data->mPrevElapsedTime);
m_data->mStartTime.QuadPart += msecAdjustment;
elapsedTime -= msecAdjustment;
}
// Store the current elapsed time for adjustments next time.
m_data->mPrevElapsedTime = elapsedTime;
// Convert to microseconds.
unsigned long long usecTicks = (unsigned long)(1000000 * elapsedTime /
m_data->mClockFrequency.QuadPart);
return usecTicks;
return (unsigned long long) elapsedTime.QuadPart;
#else
#ifdef __CELLOS_LV2__
@@ -229,74 +215,27 @@ double b3Clock::getTimeInSeconds()
return double(getTimeMicroseconds()/1.e6);
}
/// Gets the system time in milliseconds
double b3Clock::getSystemTimeMilliseconds() {
#ifdef B3_USE_WINDOWS_TIMERS
LARGE_INTEGER currentTime;
QueryPerformanceCounter(&currentTime);
LONGLONG elapsedTime = currentTime.QuadPart;
// Compute the number of millisecond ticks elapsed.
unsigned long msecTicks = (unsigned long)(1000 * elapsedTime /
m_data->mClockFrequency.QuadPart);
// Check for unexpected leaps in the Win32 performance counter.
// (This is caused by unexpected data across the PCI to ISA
// bridge, aka south bridge. See Microsoft KB274323.)
unsigned long elapsedTicks = GetTickCount();
signed long msecOff = (signed long)(msecTicks - elapsedTicks);
if (msecOff < -100 || msecOff > 100)
{
// Adjust the starting time forwards.
LONGLONG msecAdjustment = b3ClockMin(msecOff *
m_data->mClockFrequency.QuadPart / 1000, elapsedTime -
m_data->mPrevMilliTime);
elapsedTime -= msecAdjustment;
// Recompute the number of millisecond ticks elapsed.
msecTicks = (unsigned long)(1000 * elapsedTime /
m_data->mClockFrequency.QuadPart);
}
// Store the current elapsed time for adjustments next time.
m_data->mPrevMilliTime = elapsedTime;
return msecTicks;
#else
#ifdef __CELLOS_LV2__
uint64_t freq = sys_time_get_timebase_frequency();
double dFreq = ((double)freq) / 1000.0;
typedef uint64_t ClockSize;
ClockSize newTime;
SYS_TIMEBASE_GET(newTime);
//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
return (unsigned long int)((double(newTime)) / dFreq);
#else
struct timeval currentTime;
gettimeofday(&currentTime, 0);
return (currentTime.tv_sec) * 1000 +
(currentTime.tv_usec) / 1000;
#endif //__CELLOS_LV2__
#endif
}
void b3Clock::usleep(int microSeconds)
{
#ifdef _WIN32
int millis = microSeconds/1000;
if (millis < 1)
if (microSeconds==0)
{
millis = 1;
Sleep(0);
} else
{
int millis = microSeconds/1000;
if (millis<1)
millis=1;
Sleep(millis);
}
Sleep(millis);
#else
::usleep(microSeconds);
//struct timeval tv;
//tv.tv_sec = microSeconds/1000000L;
//tv.tv_usec = microSeconds%1000000L;
//return select(0, 0, 0, 0, &tv);
if (microSeconds>0)
{
::usleep(microSeconds);
//struct timeval tv;
//tv.tv_sec = microSeconds/1000000L;
//tv.tv_usec = microSeconds%1000000L;
//return select(0, 0, 0, 0, &tv);
}
#endif
}

View File

@@ -20,6 +20,9 @@ public:
/// the b3Clock was created.
unsigned long int getTimeMilliseconds();
/// Gets the system time in milliseconds
unsigned long int getSystemTimeMilliseconds();
/// Returns the time in us since the last call to reset or since
/// the Clock was created.
unsigned long long int getTimeMicroseconds();
@@ -28,9 +31,6 @@ public:
/// the Clock was created.
double getTimeInSeconds();
/// Gets the system time in milliseconds
double getSystemTimeMilliseconds();
///Sleep for 'microSeconds', to yield to other threads and not waste 100% CPU cycles.
///Note that some operating systems may sleep a longer time.
static void usleep(int microSeconds);