mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
Refactor gettimeofday()
This commit is contained in:
parent
4238e4def9
commit
af3df0893b
11 changed files with 195 additions and 36 deletions
29
examples/gettimeofday.c
Normal file
29
examples/gettimeofday.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/time/struct/tm.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "net/http/http.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int rc;
|
||||
int64_t t;
|
||||
char p[30];
|
||||
struct tm tm;
|
||||
struct timeval tv;
|
||||
rc = gettimeofday(&tv, 0);
|
||||
assert(!rc);
|
||||
t = tv.tv_sec;
|
||||
gmtime_r(&t, &tm);
|
||||
FormatHttpDateTime(p, &tm);
|
||||
printf("%s\n", p);
|
||||
}
|
|
@ -18,13 +18,13 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
.initbss 201,_init___clock_gettime
|
||||
.initbss 301,_init___clock_gettime
|
||||
__clock_gettime:
|
||||
.quad 0
|
||||
.endobj __clock_gettime,globl,hidden
|
||||
.previous
|
||||
|
||||
.init.start 201,_init___clock_gettime
|
||||
.init.start 301,_init___clock_gettime
|
||||
ezlea __clock_gettime_init,ax
|
||||
stosq
|
||||
.init.end 201,_init___clock_gettime
|
||||
.init.end 301,_init___clock_gettime
|
||||
|
|
30
libc/calls/__gettimeofday.S
Normal file
30
libc/calls/__gettimeofday.S
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
.initbss 301,_init___gettimeofday
|
||||
__gettimeofday:
|
||||
.quad 0
|
||||
.endobj __gettimeofday,globl,hidden
|
||||
.previous
|
||||
|
||||
.init.start 301,_init___gettimeofday
|
||||
ezlea __gettimeofday_init,ax
|
||||
stosq
|
||||
.init.end 301,_init___gettimeofday
|
24
libc/calls/gettimeofday-metal.c
Normal file
24
libc/calls/gettimeofday-metal.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
|
||||
axdx_t sys_gettimeofday_metal(struct timeval *tv, struct timezone *tz,
|
||||
void *wut) {
|
||||
return (axdx_t){-1, 0};
|
||||
}
|
|
@ -16,18 +16,17 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/nt/struct/filetime.h"
|
||||
#include "libc/nt/struct/systemtime.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/time/struct/timezone.h"
|
||||
|
||||
textwindows int sys_gettimeofday_nt(struct timeval *tv, struct timezone *tz) {
|
||||
textwindows axdx_t sys_gettimeofday_nt(struct timeval *tv, struct timezone *tz,
|
||||
void *wut) {
|
||||
struct NtFileTime ft;
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
if (tv) *tv = FileTimeToTimeVal(ft);
|
||||
if (tz) bzero(tz, sizeof(*tz));
|
||||
return 0;
|
||||
return (axdx_t){0, 0};
|
||||
}
|
||||
|
|
31
libc/calls/gettimeofday-xnu.c
Normal file
31
libc/calls/gettimeofday-xnu.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
|
||||
axdx_t sys_gettimeofday_xnu(struct timeval *tv, struct timezone *tz,
|
||||
void *wut) {
|
||||
axdx_t ad;
|
||||
ad = sys_gettimeofday(tv, tz, wut);
|
||||
if (ad.ax > 0 && tv) {
|
||||
tv->tv_sec = ad.ax;
|
||||
tv->tv_usec = ad.dx;
|
||||
ad.ax = 0;
|
||||
}
|
||||
return ad;
|
||||
}
|
|
@ -18,52 +18,86 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/calls/syscall_support-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/time/struct/timezone.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
static typeof(sys_gettimeofday) *__gettimeofday = sys_gettimeofday;
|
||||
typedef axdx_t gettimeofday_f(struct timeval *, struct timezone *, void *);
|
||||
|
||||
extern gettimeofday_f *__gettimeofday;
|
||||
|
||||
/**
|
||||
* Returns system wall time in microseconds.
|
||||
* Returns system wall time in microseconds, e.g.
|
||||
*
|
||||
* int64_t t;
|
||||
* char p[30];
|
||||
* struct tm tm;
|
||||
* struct timeval tv;
|
||||
* gettimeofday(&tv, 0);
|
||||
* t = tv.tv_sec;
|
||||
* gmtime_r(&t, &tm);
|
||||
* FormatHttpDateTime(p, &tm);
|
||||
* printf("%s\n", p);
|
||||
*
|
||||
* @param tv points to timeval that receives result if non-NULL
|
||||
* @param tz receives UTC timezone if non-NULL
|
||||
* @error EFAULT if `tv` or `tz` isn't valid memory
|
||||
* @see clock_gettime() for nanosecond precision
|
||||
* @see strftime() for string formatting
|
||||
*/
|
||||
int gettimeofday(struct timeval *tv, struct timezone *tz) {
|
||||
int rc;
|
||||
axdx_t ad;
|
||||
if (IsAsan() && ((tv && !__asan_is_valid(tv, sizeof(*tv))) ||
|
||||
(tz && !__asan_is_valid(tz, sizeof(*tz))))) {
|
||||
return efault();
|
||||
}
|
||||
if (!IsWindows() && !IsMetal()) {
|
||||
ad = __gettimeofday(tv, tz, NULL);
|
||||
assert(ad.ax != -1);
|
||||
if (SupportsXnu() && ad.ax && tv) {
|
||||
tv->tv_sec = ad.ax;
|
||||
tv->tv_usec = ad.dx;
|
||||
}
|
||||
return 0;
|
||||
} else if (IsMetal()) {
|
||||
return enosys();
|
||||
rc = efault();
|
||||
} else {
|
||||
return sys_gettimeofday_nt(tv, tz);
|
||||
rc = __gettimeofday(tv, tz, 0).ax;
|
||||
}
|
||||
#if SYSDEBUG
|
||||
if (!__time_critical) {
|
||||
STRACE("gettimeofday([%s], %p) → %d% m", DescribeTimeval(rc, tv), tz, rc);
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
static textstartup void __gettimeofday_init(void) {
|
||||
void *vdso;
|
||||
if ((vdso = __vdsosym("LINUX_2.6", "__vdso_gettimeofday"))) {
|
||||
__gettimeofday = vdso;
|
||||
/**
|
||||
* Returns pointer to fastest gettimeofday().
|
||||
*/
|
||||
gettimeofday_f *__gettimeofday_get(bool *opt_out_isfast) {
|
||||
bool isfast;
|
||||
gettimeofday_f *res;
|
||||
if (IsLinux() && (res = __vdsosym("LINUX_2.6", "__vdso_gettimeofday"))) {
|
||||
isfast = true;
|
||||
} else if (IsWindows()) {
|
||||
isfast = true;
|
||||
res = sys_gettimeofday_nt;
|
||||
} else if (IsXnu()) {
|
||||
isfast = false;
|
||||
res = sys_gettimeofday_xnu;
|
||||
} else if (IsMetal()) {
|
||||
isfast = false;
|
||||
res = sys_gettimeofday_metal;
|
||||
} else {
|
||||
isfast = false;
|
||||
res = sys_gettimeofday;
|
||||
}
|
||||
if (opt_out_isfast) {
|
||||
*opt_out_isfast = isfast;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
const void *const __gettimeofday_ctor[] initarray = {
|
||||
__gettimeofday_init,
|
||||
};
|
||||
hidden int __gettimeofday_init(struct timeval *tv, struct timezone *tz) {
|
||||
gettimeofday_f *gettime;
|
||||
__gettimeofday = gettime = __gettimeofday_get(0);
|
||||
return gettime(tv, tz, 0).ax;
|
||||
}
|
||||
|
|
|
@ -157,17 +157,18 @@ void __rusage2linux(struct rusage *) hidden;
|
|||
void __sigenter_xnu(void *, i32, i32, struct siginfo_xnu *,
|
||||
struct __darwin_ucontext *) hidden;
|
||||
void __stat2cosmo(struct stat *restrict, const union metastat *) hidden;
|
||||
axdx_t sys_gettimeofday_xnu(struct timeval *, struct timezone *, void *) hidden;
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § syscalls » windows nt » veneers ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
axdx_t sys_gettimeofday_nt(struct timeval *, struct timezone *, void *) hidden;
|
||||
int ioctl_tiocgwinsz_nt(struct Fd *, struct winsize *) hidden;
|
||||
int sys_close_nt(struct Fd *) hidden;
|
||||
int sys_fstat_nt(i64, struct stat *) hidden;
|
||||
int sys_fstatat_nt(int, const char *, struct stat *, int) hidden;
|
||||
int sys_getrusage_nt(int, struct rusage *) hidden;
|
||||
int sys_gettimeofday_nt(struct timeval *, struct timezone *) hidden;
|
||||
int sys_lstat_nt(const char *, struct stat *) hidden;
|
||||
int sys_nanosleep_nt(const struct timespec *, struct timespec *) hidden;
|
||||
int sys_setitimer_nt(int, const struct itimerval *, struct itimerval *) hidden;
|
||||
|
@ -196,6 +197,7 @@ struct NtOverlapped *_offset2overlap(int64_t, int64_t,
|
|||
│ cosmopolitan § syscalls » metal ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
axdx_t sys_gettimeofday_metal(struct timeval *, struct timezone *, void *);
|
||||
int sys_fstat_metal(int, struct stat *);
|
||||
int sys_openat_metal(int, const char *, int, unsigned);
|
||||
ssize_t sys_readv_metal(struct Fd *, const struct iovec *, int) hidden;
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
|
@ -29,9 +32,16 @@
|
|||
int64_t time(int64_t *opt_out_ret) {
|
||||
int64_t secs;
|
||||
struct timeval tv;
|
||||
secs = nowl();
|
||||
if (opt_out_ret) {
|
||||
*opt_out_ret = secs;
|
||||
if (IsAsan() && opt_out_ret &&
|
||||
!__asan_is_valid(opt_out_ret, sizeof(*opt_out_ret))) {
|
||||
secs = efault();
|
||||
} else if (gettimeofday(&tv, 0) != -1) {
|
||||
secs = tv.tv_sec;
|
||||
if (opt_out_ret) {
|
||||
*opt_out_ret = secs;
|
||||
}
|
||||
} else {
|
||||
secs = -1;
|
||||
}
|
||||
return secs;
|
||||
}
|
||||
|
|
2
third_party/tidy/sprtf.c
vendored
2
third_party/tidy/sprtf.c
vendored
|
@ -172,7 +172,7 @@ void set_log_file( char * nf, int open )
|
|||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
int gettimeofday(struct timeval *tp, void *tzp)
|
||||
int _gettimeofday(struct timeval *tp, void *tzp)
|
||||
{
|
||||
#ifdef WIN32
|
||||
struct _timeb timebuffer;
|
||||
|
|
|
@ -83,7 +83,7 @@ static void LoadElfLoadSegment(struct Machine *m, void *code, size_t codesize,
|
|||
static void LoadElf(struct Machine *m, struct Elf *elf) {
|
||||
unsigned i;
|
||||
Elf64_Phdr *phdr;
|
||||
m->ip = elf->base = elf->ehdr->e_entry;
|
||||
m->ip = elf->base = 0x400000 /* elf->ehdr->e_entry */;
|
||||
VERBOSEF("LOADELF ENTRY %012lx", m->ip);
|
||||
for (i = 0; i < elf->ehdr->e_phnum; ++i) {
|
||||
phdr = GetElfSegmentHeaderAddress(elf->ehdr, elf->size, i);
|
||||
|
|
Loading…
Reference in a new issue