diff --git a/TimedExec.vcxproj b/TimedExec.vcxproj
index 4e8208d..5d90e99 100644
--- a/TimedExec.vcxproj
+++ b/TimedExec.vcxproj
@@ -23,7 +23,7 @@
Application
true
Unicode
- v120
+ v120_xp
Application
@@ -44,6 +44,8 @@
true
+ $(SolutionDir)\bin\$(Configuration)\
+ $(SolutionDir)\obj\$(Configuration)\
false
diff --git a/src/TimedExec.cpp b/src/TimedExec.cpp
index a314aa0..0f42a68 100644
--- a/src/TimedExec.cpp
+++ b/src/TimedExec.cpp
@@ -38,6 +38,33 @@
#define EXEC_LOOPS 5
#define WARMUP_LOOPS 1
+static bool getEnvVariable(const _TCHAR *const name, _TCHAR *const buffer, size_t buffSize)
+{
+ const DWORD ret = GetEnvironmentVariable(name, buffer, buffSize);
+ return ((ret > 0) && (ret < buffSize));
+}
+
+static LONGLONG getCurrentTime(void)
+{
+ LARGE_INTEGER timeValue;
+ if(!QueryPerformanceCounter(&timeValue))
+ {
+ std::cerr << "\nTimedExec: Failed to query performance counter!\n" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+ return timeValue.QuadPart;
+}
+
+static LONGLONG getTimerFrequency(void)
+{
+ LARGE_INTEGER timeValue;
+ if(!QueryPerformanceFrequency(&timeValue))
+ {
+ std::cerr << "\nTimedExec: Failed to query performance counter!\n" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+ return timeValue.QuadPart;
+}
int _tmain(int argc, _TCHAR* argv[])
{
@@ -71,7 +98,7 @@ int _tmain(int argc, _TCHAR* argv[])
if(szArglist == NULL)
{
std::cerr << std::endl << "Internal error: Initialization failed!" << std::endl;
- return -1;
+ return EXIT_FAILURE;
}
if(nArgs < 2)
@@ -82,7 +109,7 @@ int _tmain(int argc, _TCHAR* argv[])
std::cerr << " TIMED_EXEC_LOGFILE - Log File (default: \"" << LOG_FILE << "\")" << std::endl;
std::cerr << " TIMED_EXEC_LOOPS - Number of execution loops (default: " << EXEC_LOOPS << ")" << std::endl;
std::cerr << " TIMED_WARMUP_LOOPS - Number of warm-up loops (default: " << WARMUP_LOOPS << ")\n" << std::endl;
- return 1;
+ return EXIT_FAILURE;
}
for(int i = 1; i < nArgs; i++)
@@ -108,17 +135,17 @@ int _tmain(int argc, _TCHAR* argv[])
TCHAR *logFile = NULL;
int maxLoops = EXEC_LOOPS, warmupLoops = WARMUP_LOOPS;
- if(GetEnvironmentVariable(_T("TIMED_EXEC_LOOPS"), temp, len))
+ if(getEnvVariable(_T("TIMED_EXEC_LOOPS"), temp, len))
{
int maxLoops = std::max(1, _tstoi(temp));
}
- if(GetEnvironmentVariable(_T("TIMED_WARMUP_LOOPS"), temp, len))
+ if(getEnvVariable(_T("TIMED_WARMUP_LOOPS"), temp, len))
{
int warmupLoops = std::max(0, _tstoi(temp));
}
- if(GetEnvironmentVariable(_T("TIMED_EXEC_LOGFILE"), temp, len))
+ if(getEnvVariable(_T("TIMED_EXEC_LOGFILE"), temp, len))
{
logFile = _tcsdup(temp);
}
@@ -131,9 +158,8 @@ int _tmain(int argc, _TCHAR* argv[])
_ftprintf(stderr, _T("Command-line:\n%s\n\n"), myCmd);
- LARGE_INTEGER startTime, finishTime, frequency;
+ const LONGLONG timerFrequency = getTimerFrequency();
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
- QueryPerformanceFrequency(&frequency);
double *singleResults = new double[maxLoops];
memset(singleResults, 0, sizeof(double) * maxLoops);
@@ -158,7 +184,7 @@ int _tmain(int argc, _TCHAR* argv[])
if(!CreateProcess(NULL, myCmd, NULL, NULL, false, ABOVE_NORMAL_PRIORITY_CLASS, NULL, NULL, &startInfo, &processInfo))
{
std::cerr << "\nTimedExec: Failed to create process!" << std::endl;
- return -2;
+ return EXIT_FAILURE;
}
WaitForSingleObject(processInfo.hProcess, INFINITE);
@@ -178,15 +204,25 @@ int _tmain(int argc, _TCHAR* argv[])
if(!CreateProcess(NULL, myCmd, NULL, NULL, false, ABOVE_NORMAL_PRIORITY_CLASS | CREATE_SUSPENDED, NULL, NULL, &startInfo, &processInfo))
{
std::cerr << "\nTimedExec: Failed to create process!" << std::endl;
- return -2;
+ return EXIT_FAILURE;
}
- QueryPerformanceCounter(&startTime);
- ResumeThread(processInfo.hThread);
- WaitForSingleObject(processInfo.hProcess, INFINITE);
- QueryPerformanceCounter(&finishTime);
+ const LONGLONG timeStart = getCurrentTime();
- const double execTime = static_cast(finishTime.QuadPart - startTime.QuadPart) / static_cast(frequency.QuadPart);
+ if(ResumeThread(processInfo.hThread) == ((DWORD) -1))
+ {
+ std::cerr << "\nTimedExec: Failed to resume thread!" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ if(WaitForSingleObject(processInfo.hProcess, INFINITE) != WAIT_OBJECT_0)
+ {
+ std::cerr << "\nTimedExec: Failed to wait for process termination!" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ const LONGLONG timeFinish = getCurrentTime();
+ const double execTime = static_cast(timeFinish - timeStart) / static_cast(timerFrequency);
singleResults[loop] = execTime;
std::cerr << std::setprecision(3) << std::fixed;
@@ -219,10 +255,14 @@ int _tmain(int argc, _TCHAR* argv[])
if(_tfopen_s(&fLog, logFile, _T("a+")) == 0)
{
_tcsncpy_s(temp, len, szArglist[1], _TRUNCATE);
- TCHAR *ctx;
- TCHAR *exeName = _tcstok_s(temp, _T(":/\\"), &ctx);
+ TCHAR *ctx, *exeName = _tcstok_s(temp, _T(":/\\"), &ctx);
while(TCHAR *tok = _tcstok_s(NULL, _T(":/\\"), &ctx)) exeName = tok;
_ftprintf_s(fLog, _T("%s\t%d\t%f\t%f\t%f\t%f\t%s\n"), exeName, maxLoops, meanResult, fastestResult, slowestResult, standardDeviation, myCmd);
+ fclose(fLog); fLog = NULL;
+ }
+ else
+ {
+ std::cerr << "Error: Failed to append results to log file!\n" << std::endl;
}
/* ---------------------------------------------------------- */
@@ -234,6 +274,6 @@ int _tmain(int argc, _TCHAR* argv[])
LocalFree(szArglist);
if(logFile) free(logFile);
- return 0;
+ return EXIT_SUCCESS;
}