This example uses GetProcessTimes()
but can easily be modified to use GetThreadTimes()
.
ISO C's clock()
is SUPPOSED to give you elapsed CPU-seconds when divided by CLOCKS_PER_SEC
. However the Visual Studio 2019 web page says:
The clock function tells how much wall-clock time has passed since the
CRT initialization during process start. Note that this function does
not strictly conform to ISO C, which specifies net CPU time as the
return value.
So, here is a stand-in I made. On Windows 7/Visual Studio 2017, CLOCKS_PER_SEC
is 1000 and GetProcessTimes()
only has millisecond accuracy, so no accuracy is lost returning clock_t
instead of double
, say.
clock_t AKClock() {
#ifdef WIN32
FILETIME ftimeCreate, ftimeExit, ftimeKernel, ftimeUser;
SYSTEMTIME stimeKernel, stimeUser;
if ( ! GetProcessTimes( GetCurrentProcess(), &ftimeCreate, &ftimeExit,
&ftimeKernel, &ftimeUser ) ||
! FileTimeToSystemTime( &ftimeKernel, &stimeKernel ) ||
! FileTimeToSystemTime( &ftimeUser, &stimeUser ) ) {
char szError[ 1024 ];
MyLoggingFunction( "AKClock() failed; returning -1: %s",
AKGetLastError( szError, sizeof( szError ) ) );
return (clock_t) -1.0;
}
return (clock_t)
( ( stimeKernel.wHour * 3600.0 +
stimeKernel.wMinute * 60.0 +
stimeKernel.wSecond +
stimeKernel.wMilliseconds / 1000.0 +
stimeUser.wHour * 3600.0 +
stimeUser.wMinute * 60.0 +
stimeUser.wSecond +
stimeUser.wMilliseconds / 1000.0 ) * CLOCKS_PER_SEC );
#else
return clock();
#endif
}
And for completeness, here's AKGetLastError():
void AKstrncpy( char *pszDest, const char *pszSrc, const size_t sDest ) {
strncpy( pszDest, pszSrc, sDest );
pszDest[ sDest - 1 ] = '\0';
}
char* AKGetLastError( char* szBuf, int iBufSize ) {
DWORD errorMessageID = GetLastError();
char* pszError = NULL;
size_t sizeBuf;
if( errorMessageID == 0 ) {
AKstrncpy( szBuf, "(no error)", iBufSize );
return szBuf;
}
sizeBuf = FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorMessageID, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
(LPSTR) &pszError, 0, NULL );
AKstrncpy( szBuf, pszError, iBufSize );
LocalFree( pszError );
int iLen = strlen( szBuf );
if ( strcmp( szBuf + iLen - 2, "\r\n" ) == 0 )
szBuf[ iLen - 2 ] = '\0';
return szBuf;
}