Merge branch 'master' into 3D-NN-walkers-example
This commit is contained in:
272
examples/Utils/ChromeTraceUtil.cpp
Normal file
272
examples/Utils/ChromeTraceUtil.cpp
Normal 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;
|
||||
}
|
||||
9
examples/Utils/ChromeTraceUtil.h
Normal file
9
examples/Utils/ChromeTraceUtil.h
Normal 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
|
||||
275
examples/Utils/RobotLoggingUtil.cpp
Normal file
275
examples/Utils/RobotLoggingUtil.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
54
examples/Utils/RobotLoggingUtil.h
Normal file
54
examples/Utils/RobotLoggingUtil.h
Normal 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
|
||||
@@ -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(¤tTime);
|
||||
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(¤tTime);
|
||||
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(¤tTime);
|
||||
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(¤tTime, 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(¤tTime);
|
||||
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(¤tTime);
|
||||
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(¤tTime, 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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user