time.h: time, difftime calls

This commit is contained in:
bumbread 2022-06-27 23:34:13 +11:00
parent 441320f888
commit 81feacd996
4 changed files with 116 additions and 78 deletions

View File

@ -4,6 +4,14 @@
#define _COL_IGNORE_SPACE 0x1 #define _COL_IGNORE_SPACE 0x1
#define _COL_IGNORE_SYMBOL 0x2 #define _COL_IGNORE_SYMBOL 0x2
// Locale categories
#define LC_ALL 0
#define LC_COLLATE 1
#define LC_CTYPE 2
#define LC_MONETARY 3
#define LC_NUMERIC 4
#define LC_TIME 5
struct lconv { struct lconv {
// LC_NUMERIC // LC_NUMERIC
char *decimal_point; // "." char *decimal_point; // "."
@ -33,13 +41,5 @@ struct lconv {
char int_n_sign_posn; // CHAR_MAX char int_n_sign_posn; // CHAR_MAX
}; };
// Locale categories
#define LC_ALL 0
#define LC_COLLATE 1
#define LC_CTYPE 2
#define LC_MONETARY 3
#define LC_NUMERIC 4
#define LC_TIME 5
char *setlocale(int category, const char *locale); char *setlocale(int category, const char *locale);
struct lconv *localeconv(void); struct lconv *localeconv(void);

View File

@ -1,45 +1,51 @@
#pragma once #pragma once
#include <stddef.h>
#include <stdint.h>
#if !defined(NULL) #if !defined(NULL)
#define NULL ((void *)0) #define NULL ((void *)0)
#endif #endif
// The number of clock ticks per second
#define CLOCKS_PER_SEC ((clock_t)1000)
#define TIME_UTC 1 #define TIME_UTC 1
typedef size_t clock_t; #define CLOCKS_PER_SEC ((clock_t)1000000)
typedef size_t time_t;
typedef uint64_t clock_t;
typedef uint64_t time_t;
struct timespec { struct timespec {
time_t tv_sec; // Seconds - >= 0 time_t tv_sec;
long tv_nsec; // Nanoseconds - [0, 999999999] long tv_nsec;
}; };
struct tm { struct tm {
int tm_sec; // seconds after the minute - [0, 60] including leap second int tm_sec;
int tm_min; // minutes after the hour - [0, 59] int tm_min;
int tm_hour; // hours since midnight - [0, 23] int tm_hour;
int tm_mday; // day of the month - [1, 31] int tm_mon;
int tm_mon; // months since January - [0, 11] int tm_mday; // Days passed within 1st of current month
int tm_year; // years since 1900 int tm_year; // Years since year 1900
int tm_wday; // days since Sunday - [0, 6] int tm_wday; // Days passed since sunday
int tm_yday; // days since January 1 - [0, 365] int tm_yday; // Days passed since Jan 1
int tm_isdst; // daylight savings time flag int tm_isdst;
}; };
clock_t clock (void); clock_t clock (void);
double difftime(time_t time1, time_t time0);
time_t mktime(struct tm *timeptr);
time_t time (time_t *timer); time_t time (time_t *timer);
time_t mktime (struct tm *timeptr);
double difftime (time_t time1, time_t time0);
int timespec_get(struct timespec *ts, int base); int timespec_get(struct timespec *ts, int base);
char *asctime (const struct tm *timeptr); char *asctime (const struct tm *timeptr);
char *ctime (const time_t *timer); char *ctime (const time_t *timer);
struct tm *gmtime (const time_t *timer); struct tm *gmtime (const time_t *timer);
struct tm *localtime (const time_t *timer); struct tm *localtime (const time_t *timer);
size_t strftime(char * restrict s, size_t maxsize, const char * restrict format, const struct tm * restrict timeptr);
size_t strftime(
char *restrict s,
size_t maxsize,
const char *restrict format,
const struct tm *restrict timeptr
);
#ifdef __STDC_WANT_LIB_EXT1__ #ifdef __STDC_WANT_LIB_EXT1__
errno_t asctime_s(char *s, rsize_t maxsize, const struct tm *timeptr); errno_t asctime_s(char *s, rsize_t maxsize, const struct tm *timeptr);

View File

@ -3,6 +3,15 @@
#include <stdint.h> #include <stdint.h>
#include <win.h> #include <win.h>
#define TIME_TICKS_PER_SEC 1000
#define FILE_TICKS_PER_SEC 10000000
#define FILE_TICKS_UNTIL_UNIX_EPOCH 116444736000000000ULL
#define NANOS_PER_SEC 1000000000
#define NANOS_PER_FILE_TICK (NANOS_PER_SEC / FILE_TICKS_PER_SEC)
#define NANOS_PER_TIME_TICK (NANOS_PER_SEC / TIME_TICKS_PER_SEC)
// Store the time since we started running the process // Store the time since we started running the process
static uint64_t timer_freq; static uint64_t timer_freq;
static uint64_t timer_start; static uint64_t timer_start;
@ -15,21 +24,17 @@ void _setup_timer(void) {
timer_freq = freq.QuadPart; timer_freq = freq.QuadPart;
} }
int timespec_get(struct timespec *ts, int base) { static ULONGLONG win32_get_unix_nanos() {
if (base != TIME_UTC) return 0;
FILETIME ft; FILETIME ft;
GetSystemTimeAsFileTime(&ft); GetSystemTimeAsFileTime(&ft);
ULARGE_INTEGER ft64 = {
ULARGE_INTEGER s = {
.LowPart = ft.dwLowDateTime, .LowPart = ft.dwLowDateTime,
.HighPart = ft.dwHighDateTime .HighPart = ft.dwHighDateTime,
}; };
ULONGLONG fticks = ft64.QuadPart;
ULONGLONG t = s.QuadPart - 116444736000000000ULL; ULONGLONG unix_fticks = fticks - FILE_TICKS_UNTIL_UNIX_EPOCH;
ts->tv_sec = t / 10000000; ULONGLONG unix_nanos = unix_fticks * NANOS_PER_FILE_TICK;
ts->tv_nsec = ((int) (t % 10000000)) * 100; return unix_nanos;
return base;
} }
clock_t clock(void) { clock_t clock(void) {
@ -37,17 +42,34 @@ clock_t clock(void) {
if (!QueryPerformanceCounter(&curr)) { if (!QueryPerformanceCounter(&curr)) {
return -1; return -1;
} }
// time travel?
if (curr.QuadPart < timer_start) { if (curr.QuadPart < timer_start) {
return -1; return -1;
} }
clock_t ticks = curr.QuadPart - timer_start;
uint64_t time_from_start = curr.QuadPart - timer_start; // Basically millis / timer_freq * CLOCKS_PER_SEC but more precise
return ticks / timer_freq * CLOCKS_PER_SEC
uint64_t scaled_millis = (time_from_start / timer_freq) * CLOCKS_PER_SEC; + ticks % timer_freq * CLOCKS_PER_SEC / timer_freq;
// helps reduce error when doing integer division }
scaled_millis += ((time_from_start % timer_freq) * CLOCKS_PER_SEC) / timer_freq;
time_t time(time_t *timer) {
return scaled_millis; ULONGLONG unix_nanos = win32_get_unix_nanos();
time_t timer_ticks = unix_nanos / NANOS_PER_TIME_TICK;
if(timer != NULL) {
*timer = timer_ticks;
}
return timer_ticks;
}
double difftime(time_t time1, time_t time0) {
double resolution = (double)TIME_TICKS_PER_SEC;
if(time1 >= time0) return (double)(time1 - time0) / resolution;
else return -(double)(time0 - time1) / resolution;
}
int timespec_get(struct timespec *ts, int base) {
if (base != TIME_UTC) return 0;
ULONGLONG unix_nanos = win32_get_unix_nanos();
ts->tv_sec = unix_nanos / NANOS_PER_SEC;
ts->tv_nsec = unix_nanos;
return base;
} }

10
test/test_time.c Normal file
View File

@ -0,0 +1,10 @@
#include <time.h>
#include <stdio.h>
int main() {
time_t t1 = time(NULL);
time_t t2 = time(NULL);
double s = difftime(t2, t1);
return 0;
}