| `<hex32>` | `0x%08X` | 32-bit hexadecimal number |
| `<hex64>` | `0x%016X` | 64-bit hexadecimal number |
| `<systime>` | `%Y-%m-%d %H:%M:%S.%03f` | System time in format of year, month, day, hour, minute, seconds and milliseconds |
+| `<bias>` | `+%H:%M` or `-%H:%M` | Signed tize zone offset as hour and minute |
| `<ms>` | `<num>` | Time (in milliseconds) |
| `<us>` | `<num>` | Time (in microseconds) |
| `<ptr>` | `<hex64>` | Memory pointer |
### Profiler Start Time: `prf stm`
```
-prf stm <systime>
+prf stm <systime> <bias>
```
-Local time of the profiling session start-up.
+Time of the profiling session start-up. Present as local time value and time
+offset relative to UTC: `UTC = local time + bias`.
### Profiler Configuration: `prf cfg`
arch/${ARCH_SOURCES_DIR}/archhelpers.cpp
)
+set_property(
+ SOURCE misc/localtime.cpp
+ PROPERTY COMPILE_DEFINITIONS
+ _GNU_SOURCE
+)
+
target_link_libraries(coreprof
libcorguids
# utilcodestaticnohost
#include "localtime.h"
-VOID
-PALAPI
-GetLocalTime(OUT LPSYSTEMTIME lpLocalTime)
+void GetLocalTimeAndBias(SYSTEMTIME *localTime, LONG *bias)
{
- time_t tt;
- struct tm ut;
- struct tm *utPtr;
+ int errc = 0;
struct timeval timeval;
- int timeofday_retval;
-
- tt = time(NULL);
+ struct tm ut;
+ struct tm *utPtr = NULL;
/* We can't get millisecond resolution from time(), so we get it from
gettimeofday() */
- timeofday_retval = gettimeofday(&timeval, NULL);
-
- utPtr = &ut;
- if (localtime_r(&tt, utPtr) == NULL)
+ errc = gettimeofday(&timeval, NULL);
+ if(errc == -1)
{
throw std::system_error(errno, std::system_category(),
- "localtime_r() failed");
+ "gettimeofday() failed");
}
- lpLocalTime->wYear = 1900 + utPtr->tm_year;
- lpLocalTime->wMonth = utPtr->tm_mon + 1;
- lpLocalTime->wDayOfWeek = utPtr->tm_wday;
- lpLocalTime->wDay = utPtr->tm_mday;
- lpLocalTime->wHour = utPtr->tm_hour;
- lpLocalTime->wMinute = utPtr->tm_min;
- lpLocalTime->wSecond = utPtr->tm_sec;
-
- if(-1 == timeofday_retval)
+ utPtr = localtime_r(&timeval.tv_sec, &ut);
+ if (utPtr == NULL)
{
- lpLocalTime->wMilliseconds = 0;
throw std::system_error(errno, std::system_category(),
- "gettimeofday() failed");
+ "localtime_r() failed");
}
- else
- {
- int old_seconds;
- int new_seconds;
-
- lpLocalTime->wMilliseconds = timeval.tv_usec / 1000;
- old_seconds = utPtr->tm_sec;
- new_seconds = timeval.tv_sec%60;
+ localTime->wYear = 1900 + ut.tm_year;
+ localTime->wMonth = ut.tm_mon + 1;
+ localTime->wDayOfWeek = ut.tm_wday;
+ localTime->wDay = ut.tm_mday;
+ localTime->wHour = ut.tm_hour;
+ localTime->wMinute = ut.tm_min;
+ localTime->wSecond = ut.tm_sec;
+ localTime->wMilliseconds = timeval.tv_usec / 1000;
- /* just in case we reached the next second in the interval between
- time() and gettimeofday() */
- if(old_seconds != new_seconds)
- {
- lpLocalTime->wMilliseconds = 999;
- }
- }
+ *bias = ut.tm_gmtoff / 60;
}
#include <pal.h>
-PALIMPORT
-VOID
-PALAPI
-GetLocalTime(OUT LPSYSTEMTIME lpLocalTime);
+// Returns local time structure and bias in minutes: local time = UTC + bias.
+void GetLocalTimeAndBias(SYSTEMTIME *localTime, LONG *bias);
_ASSERTE(m_initialized == false);
SYSTEMTIME systime;
- GetLocalTime(&systime);
+ LONG bias;
+ GetLocalTimeAndBias(&systime, &bias);
m_firstTickCount = GetTickCount();
HRESULT hr = S_OK;
// Announce start time.
//
- TRACE().DumpStartTime(systime);
+ TRACE().DumpStartTime(systime, bias);
//
// Initializing the Profiler Info.
#include <memory>
#include <mutex>
+#include <stdlib.h>
+
#include <windows.h>
#include <cor.h>
sep();
*m_stream
<< std::setw(4) << systime.wYear
- << '-' << std::setw(2) << systime.wMonth
- << '-' << std::setw(2) << systime.wDay
- << ' ' << std::setw(2) << systime.wHour
- << ':' << std::setw(2) << systime.wMinute
- << ':' << std::setw(2) << systime.wSecond
- << '.' << std::setw(3) << systime.wMilliseconds;
+ << '-' << std::setw(2) << systime.wMonth
+ << '-' << std::setw(2) << systime.wDay
+ << ' ' << std::setw(2) << systime.wHour
+ << ':' << std::setw(2) << systime.wMinute
+ << ':' << std::setw(2) << systime.wSecond
+ << '.' << std::setw(3) << systime.wMilliseconds;
m_stream->fill(fill);
return *this;
}
+ record& bias(LONG bias)
+ {
+ char fill = m_stream->fill('0');
+ char sign = '+';
+
+ if (bias < 0)
+ {
+ sign = '-';
+ bias = -bias;
+ }
+
+ ldiv_t hour_minute = ldiv(bias, 60);
+
+ sep();
+ *m_stream
+ << sign
+ << std::setw(2) << hour_minute.quot
+ << ':' << std::setw(2) << hour_minute.rem;
+ m_stream->fill(fill);
+
+ return *this;
+ }
+
template<typename T>
record& config(T&& value)
{
//
virtual void DumpStartTime(
- const SYSTEMTIME &systime) override
+ const SYSTEMTIME &systime,
+ LONG bias) override
{
- m_tracefmt.log("prf stm").systime(systime);
+ m_tracefmt.log("prf stm").systime(systime).bias(bias);
}
virtual void DumpProfilerConfig(
//
virtual void DumpStartTime(
- const SYSTEMTIME &systime) = 0;
+ const SYSTEMTIME &systime,
+ LONG bias) = 0;
virtual void DumpProfilerConfig(
const ProfilerConfig &config) = 0;