Add Dqn_Timer using Win32 api

This commit is contained in:
doyle 2021-05-17 21:10:20 +10:00
parent 21cf140ba3
commit ba3b8db967

View File

@ -249,6 +249,7 @@
#define DQN_API #define DQN_API
#endif #endif
#define DQN_LOCAL_PERSIST static #define DQN_LOCAL_PERSIST static
#define DQN_FILE_SCOPE static
// ------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------
// //
@ -344,6 +345,31 @@ static_assert(sizeof(int) == sizeof(Dqn_i32), "Sanity check int typedef is
static_assert(sizeof(Dqn_u64) == 8, "Sanity check Dqn_u64 typedef is correct"); static_assert(sizeof(Dqn_u64) == 8, "Sanity check Dqn_u64 typedef is correct");
static_assert(sizeof(void *) == sizeof(Dqn_usize), "Require: Pointer can be held in usize (size_t)"); static_assert(sizeof(void *) == sizeof(Dqn_usize), "Require: Pointer can be held in usize (size_t)");
// ------------------------------------------------------------------------------------------------
//
// NOTE: Win32 Minimal Header
//
// ------------------------------------------------------------------------------------------------
#if defined(DQN_OS_WIN32)
#if !defined(DQN_NO_WIN32_WINDOWS_H)
// Taken from Windows.h
typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef union {
struct {
DWORD LowPart;
long HighPart;
};
struct {
DWORD LowPart;
long HighPart;
} u;
Dqn_i64 QuadPart;
} LARGE_INTEGER;
#endif // !defined(DQN_NO_WIN32_MINIMAL_HEADER)
#endif // !defined(DQN_OS_WIN32)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// //
// NOTE: Compile Time Utilities // NOTE: Compile Time Utilities
@ -685,29 +711,44 @@ char const *Dqn_LogTypeString[] = {
// Internal global variables for tracking the current logging function // Internal global variables for tracking the current logging function
typedef void Dqn_LogProc(Dqn_LogType type, void *user_data, char const *file, Dqn_usize file_len, char const *func, Dqn_usize func_len, Dqn_usize line, char const *fmt, ...); typedef void Dqn_LogProc(Dqn_LogType type, void *user_data, char const *file, Dqn_usize file_len, char const *func, Dqn_usize func_len, Dqn_usize line, char const *fmt, ...);
extern Dqn_LogProc *Dqn__LogCallback;
extern void * dqn__log_user_data;
// ------------------------------------------------------------------------------------------------
//
// NOTE: Logging Macros
//
// ------------------------------------------------------------------------------------------------
// Macro logging functions, prefer this is you want to log messages // Macro logging functions, prefer this is you want to log messages
#define DQN_LOG_E(fmt, ...) Dqn__LogCallback(Dqn_LogType::Error, dqn__log_user_data, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__) #define DQN_LOG_E(fmt, ...) dqn__lib.LogCallback(Dqn_LogType::Error, dqn__lib.log_user_data, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__)
#define DQN_LOG_D(fmt, ...) Dqn__LogCallback(Dqn_LogType::Debug, dqn__log_user_data, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__) #define DQN_LOG_D(fmt, ...) dqn__lib.LogCallback(Dqn_LogType::Debug, dqn__lib.log_user_data, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__)
#define DQN_LOG_W(fmt, ...) Dqn__LogCallback(Dqn_LogType::Warning, dqn__log_user_data, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__) #define DQN_LOG_W(fmt, ...) dqn__lib.LogCallback(Dqn_LogType::Warning, dqn__lib.log_user_data, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__)
#define DQN_LOG_I(fmt, ...) Dqn__LogCallback(Dqn_LogType::Info, dqn__log_user_data, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__) #define DQN_LOG_I(fmt, ...) dqn__lib.LogCallback(Dqn_LogType::Info, dqn__lib.log_user_data, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__)
#define DQN_LOG_M(fmt, ...) Dqn__LogCallback(Dqn_LogType::Memory, dqn__log_user_data, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__) #define DQN_LOG_M(fmt, ...) dqn__lib.LogCallback(Dqn_LogType::Memory, dqn__lib.log_user_data, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__)
#define DQN_LOG(log_type, fmt, ...) Dqn__LogCallback(log_type, dqn__log_user_data, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__) #define DQN_LOG(log_type, fmt, ...) dqn__lib.LogCallback(log_type, dqn__lib.log_user_data, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__)
// Update the default logging function, all logging functions will run through this callback // Update the default logging function, all logging functions will run through this callback
// proc: The new logging function // proc: The new logging function, set to nullptr to revert back to the default logger.
// user_data: A user defined parameter to pass to the callback // user_data: A user defined parameter to pass to the callback
DQN_API void Dqn_Log_SetCallback (Dqn_LogProc *proc, void *user_data); DQN_API void Dqn_Log_SetCallback (Dqn_LogProc *proc, void *user_data);
// Revert the logger callback to Dqn_Log with a nullptr user_data
DQN_API void Dqn_Log_SetDefaultCallback();
// Internal logging functions, prefer the logging macros above // Internal logging functions, prefer the logging macros above
DQN_API void Dqn_LogV (Dqn_LogType type, char const *file, Dqn_usize file_len, char const *func, Dqn_usize func_len, Dqn_usize line, char const *fmt, va_list va); DQN_API void Dqn_LogV (Dqn_LogType type, char const *file, Dqn_usize file_len, char const *func, Dqn_usize func_len, Dqn_usize line, char const *fmt, va_list va);
DQN_API void Dqn_Log (Dqn_LogType type, char const *file, Dqn_usize file_len, char const *func, Dqn_usize func_len, Dqn_usize line, char const *fmt, ...); DQN_API void Dqn_Log (Dqn_LogType type, char const *file, Dqn_usize file_len, char const *func, Dqn_usize func_len, Dqn_usize line, char const *fmt, ...);
// ------------------------------------------------------------------------------------------------
//
// NOTE: Library variables
//
// ------------------------------------------------------------------------------------------------
struct Dqn_Lib
{
Dqn_LogProc *LogCallback;
void * log_user_data;
#if defined(DQN_OS_WIN32)
LARGE_INTEGER win32_qpc_frequency;
#endif
};
extern Dqn_Lib dqn__lib;
// ------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------
// //
// NOTE: Dqn_Align // NOTE: Dqn_Align
@ -1526,6 +1567,22 @@ enum struct Dqn_EpochTimeFormat
// Produces a string representing the date in local machine time. // Produces a string representing the date in local machine time.
// timestamp: Unix epoch timestamp // timestamp: Unix epoch timestamp
DQN_API char *Dqn_EpochTimeToLocalDate(Dqn_i64 timestamp, char *buf, Dqn_isize buf_len); DQN_API char *Dqn_EpochTimeToLocalDate(Dqn_i64 timestamp, char *buf, Dqn_isize buf_len);
struct Dqn_Timer
{
#if defined(DQN_OS_WIN32)
LARGE_INTEGER start;
LARGE_INTEGER end;
#endif
};
DQN_API Dqn_Timer Dqn_Timer_Begin ();
DQN_API void Dqn_Timer_End (Dqn_Timer *timer);
DQN_API Dqn_u64 Dqn_Timer_S (Dqn_Timer const *timer);
DQN_API Dqn_u64 Dqn_Timer_Ms (Dqn_Timer const *timer);
DQN_API Dqn_u64 Dqn_Timer_MicroS(Dqn_Timer const *timer);
DQN_API Dqn_u64 Dqn_Timer_Ns (Dqn_Timer const *timer);
DQN_API char *Dqn_U64ToStr (Dqn_u64 val, Dqn_U64Str *result, Dqn_b32 comma_sep); DQN_API char *Dqn_U64ToStr (Dqn_u64 val, Dqn_U64Str *result, Dqn_b32 comma_sep);
DQN_API char *Dqn_U64ToTempStr (Dqn_u64 val, Dqn_b32 comma_sep = true); DQN_API char *Dqn_U64ToTempStr (Dqn_u64 val, Dqn_b32 comma_sep = true);
@ -2772,8 +2829,6 @@ Dqn_b32 Dqn_List_Iterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
#pragma comment(lib, "shlwapi.lib") #pragma comment(lib, "shlwapi.lib")
// Taken from Windows.h // Taken from Windows.h
typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef int BOOL; typedef int BOOL;
typedef union { typedef union {
@ -2788,18 +2843,6 @@ Dqn_b32 Dqn_List_Iterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
Dqn_u64 QuadPart; Dqn_u64 QuadPart;
} ULARGE_INTEGER; } ULARGE_INTEGER;
typedef union {
struct {
DWORD LowPart;
long HighPart;
};
struct {
DWORD LowPart;
long HighPart;
} u;
Dqn_i64 QuadPart;
} LARGE_INTEGER;
typedef struct typedef struct
{ {
DWORD dwLowDateTime; DWORD dwLowDateTime;
@ -2901,6 +2944,8 @@ Dqn_b32 Dqn_List_Iterate(Dqn_List<T> *list, Dqn_ListIterator<T> *iterator)
#include <unistd.h> // access #include <unistd.h> // access
#endif #endif
Dqn_Lib dqn__lib;
DQN_API void Dqn__ZeroMemBytes(void *ptr, Dqn_usize count, Dqn_ZeroMem zero_mem) DQN_API void Dqn__ZeroMemBytes(void *ptr, Dqn_usize count, Dqn_ZeroMem zero_mem)
{ {
if (zero_mem == Dqn_ZeroMem::Yes) if (zero_mem == Dqn_ZeroMem::Yes)
@ -3050,18 +3095,10 @@ DQN_API void Dqn_Log(Dqn_LogType type, void *user_data, char const *file, Dqn_us
va_end(va); va_end(va);
} }
Dqn_LogProc *Dqn__LogCallback = Dqn_Log; DQN_API void Dqn_Log_SetCallback(Dqn_LogProc *proc, void *user_data)
void * dqn__log_user_data = nullptr;
void Dqn_Log_SetCallback(Dqn_LogProc *proc, void *user_data)
{ {
Dqn__LogCallback = proc; dqn__lib.LogCallback = proc;
dqn__log_user_data = user_data; dqn__lib.log_user_data = user_data;
}
void Dqn_Log_SetDefaultCallback()
{
Dqn__LogCallback = Dqn_Log;
dqn__log_user_data = nullptr;
} }
// ------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------
@ -4710,6 +4747,71 @@ DQN_API Dqn_isize Dqn_EpochTimeToLocalDate(Dqn_i64 timestamp, Dqn_EpochTimeForma
return result; return result;
} }
DQN_API Dqn_Timer Dqn_Timer_Begin()
{
#if defined(DQN_OS_WIN32)
Dqn_Timer result = {};
BOOL qpc_result = QueryPerformanceCounter(&result.start);
DQN_ASSERT_MSG(qpc_result, "MSDN says this can only fail when running on a version older than Windows XP");
#endif
return result;
}
DQN_API void Dqn_Timer_End(Dqn_Timer *timer)
{
#if defined(DQN_OS_WIN32)
QueryPerformanceCounter(&timer->end);
#endif
}
DQN_FILE_SCOPE void Dqn_Timer__Init()
{
#if defined(DQN_OS_WIN32)
if (dqn__lib.win32_qpc_frequency.QuadPart == 0)
QueryPerformanceFrequency(&dqn__lib.win32_qpc_frequency);
#endif
}
DQN_API Dqn_u64 Dqn_Timer_S(Dqn_Timer const *timer)
{
Dqn_Timer__Init();
#if defined(DQN_OS_WIN32)
Dqn_u64 ticks = timer->end.QuadPart - timer->start.QuadPart;
Dqn_u64 result = ticks / dqn__lib.win32_qpc_frequency.QuadPart;
#endif
return result;
}
DQN_API Dqn_u64 Dqn_Timer_Ms(Dqn_Timer const *timer)
{
Dqn_Timer__Init();
#if defined(DQN_OS_WIN32)
Dqn_u64 ticks = timer->end.QuadPart - timer->start.QuadPart;
Dqn_u64 result = (ticks * 1000) / dqn__lib.win32_qpc_frequency.QuadPart;
#endif
return result;
}
DQN_API Dqn_u64 Dqn_Timer_MicroS(Dqn_Timer const *timer)
{
Dqn_Timer__Init();
#if defined(DQN_OS_WIN32)
Dqn_u64 ticks = timer->end.QuadPart - timer->start.QuadPart;
Dqn_u64 result = (ticks * 1000000) / dqn__lib.win32_qpc_frequency.QuadPart;
#endif
return result;
}
DQN_API Dqn_u64 Dqn_Timer_Ns(Dqn_Timer const *timer)
{
Dqn_Timer__Init();
#if defined(DQN_OS_WIN32)
Dqn_u64 ticks = timer->end.QuadPart - timer->start.QuadPart;
Dqn_u64 result = (ticks * 1000000000) / dqn__lib.win32_qpc_frequency.QuadPart;
#endif
return result;
}
DQN_API char *Dqn_U64ToStr(Dqn_u64 val, Dqn_U64Str *result, Dqn_b32 comma_sep) DQN_API char *Dqn_U64ToStr(Dqn_u64 val, Dqn_U64Str *result, Dqn_b32 comma_sep)
{ {
int buf_index = (int)(Dqn_ArrayCount(result->buf) - 1); int buf_index = (int)(Dqn_ArrayCount(result->buf) - 1);