Cygwin: clocks: fix a hang on pre-Windows 10 machines

when calling clocks too early in DLL init, the vtables are not correctly
set up for some reason.  Calls to init() from now() fail because the init
pointer in the vtable is NULL.

Real life example is mintty which runs into a minor problem at startup,
triggering a system_printf call.  Strace is another problem, it's called
the first time prior to any class initialization.

Workaround is to make sure that no virtual methods are called in an
early stage.  Make init() non-virtual and convert resolution() to a
virtual method instead.  Add a special non-virtual
clk_monotonic_t::strace_usecs.

While at it:

- Inline internal-only methods.

- Drop the `inited' member.  Convert period/ticks_per_sec toa union.
  Initialize period/ticks_per_sec via InterlockeExchange64.

- Fix GetTickCount64 usage.  No, it's not returning ticks but
  milliseconds since boot (unbiased).

- Fix comment indentation.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen
2018-11-30 22:39:57 +01:00
parent 166914ea8c
commit 2b72887ac8
3 changed files with 71 additions and 50 deletions

View File

@@ -82,14 +82,12 @@ strace::dll_info ()
int
strace::microseconds ()
{
/* Need a local clock instance because this function is called before
the global constructors of the inferior process have been called. */
static clk_monotonic_t clock_monotonic;
static LONGLONG process_start NO_COPY;
clk_monotonic_t *clk = (clk_monotonic_t *) get_clock (CLOCK_MONOTONIC);
if (!process_start)
process_start = clock_monotonic.usecs ();
return (int) (clock_monotonic.usecs () - process_start);
process_start = clk->strace_usecs ();
return (int) (clk->strace_usecs () - process_start);
}
static int __stdcall