Bug 38666

Summary: Review (and fix) uses of mono_msec_ticks
Product: [Mono] Runtime Reporter: Rolf Bjarne Kvinge [MSFT] <rolf>
Component: GeneralAssignee: Ludovic Henry <ludovic>
Status: RESOLVED FIXED    
Severity: normal CC: marcos.henrich, mono-bugs+mono, mono-bugs+runtime
Priority: ---    
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Mac OS   
Tags: Is this bug a regression?: ---
Last known good build:

Description Rolf Bjarne Kvinge [MSFT] 2016-02-11 11:38:18 UTC
mono_msec_ticks overflows after ~20 days of uptime (of the machine), which means it's never safe to use for measuring elapsed time unless special care is taken to take overflows into account.

A quick grep shows it's used in several places:

> > git grep mono_msec_ticks
> mono/io-layer/processes.c:      start = mono_msec_ticks ();
> mono/io-layer/processes.c:              now = mono_msec_ticks ();
> mono/io-layer/timefuncs.c:      return mono_msec_ticks ();
> mono/metadata/gc.c:                     guint32 start_ticks = mono_msec_ticks ();
> mono/metadata/gc.c:                             guint32 current_ticks = mono_msec_ticks ();
> mono/metadata/icall-def.h:ICALL(ENV_15, "get_TickCount", mono_msec_ticks)
> mono/metadata/monitor.c:                then = mono_msec_ticks ();
> mono/metadata/monitor.c:                                now = mono_msec_ticks ();
> mono/metadata/threadpool-ms.c:  return mono_msec_ticks () >= threadpool->heuristic_last_dequeue + threshold;
> mono/metadata/threadpool-ms.c:                  ts = mono_msec_ticks ();
> mono/metadata/threadpool-ms.c:                  interval_left -= mono_msec_ticks () - ts;
> mono/metadata/threadpool-ms.c:  threadpool->heuristic_last_dequeue = mono_msec_ticks ();
> mono/metadata/threadpool-ms.c:          guint32 sample_end = mono_msec_ticks ();
> mono/metadata/threadpool-ms.c:                  threadpool->heuristic_last_adjustment = mono_msec_ticks ();
> mono/metadata/threadpool-ms.c:          start = mono_msec_ticks ();
> mono/metadata/threadpool-ms.c:          timeout -= mono_msec_ticks () - start;
> mono/metadata/threadpool-ms.c:                  timeout -= mono_msec_ticks () - start;
> mono/metadata/threads.c:        start_time = mono_msec_ticks ();
> mono/metadata/threads.c:                timeout -= mono_msec_ticks () - start_time;
> mono/metadata/threads.c:                start_time = mono_msec_ticks ();
> mono/mini/debugger-agent.c:                             msecs = mono_msec_ticks ();
> mono/utils/mono-proclib.c:                              boot_time = mono_100ns_datetime () - ((guint64)mono_msec_ticks ()) * 10000;

and none without looking deeply my guess is that most of these are broken (just like bug #38663).

My suggestion would be to use mono_100ns_ticks instead, which overflows in ~500 years (if I got the math right).
Comment 1 Ludovic Henry 2016-02-11 11:39:14 UTC
*** Bug 38663 has been marked as a duplicate of this bug. ***
Comment 2 Ludovic Henry 2016-02-11 11:40:04 UTC
To fix it, I will use mono_nsec_ticks for the threadpool-ms.c and threads.c ones.
Comment 3 Ludovic Henry 2016-03-04 11:50:44 UTC
This is fixed with https://github.com/mono/mono/pull/2721