Incorrect warning message on thread pool startup in full AOT:ed Windows build.
authorlateralusX <lateralusx.github@gmail.com>
Fri, 20 May 2016 09:27:48 +0000 (11:27 +0200)
committerlateralusX <lateralusx.github@gmail.com>
Fri, 20 May 2016 09:27:48 +0000 (11:27 +0200)
When running mono/mini aot-tests.exe on full AOT:ed Windows build the following
warning message is incorrectly written to the console several times:

g_warning ("failed to get 100ns ticks");

This happens since the check triggering this warning is not taking into account
that startup time between first call to mono_ns100_ticks storing the start time
and the launch of the thread pool requesting 100ns ticks and convert it to
elapsed seconds can occur during the first second of the process lifetime.
This is more likely to happen in a full AOT:ed image since nothing needs to
be JIT:ed at startup, making it more likely to exploit the problem reaching this
code within the first second of process lifetime.

The purpose of the check is to validate that mono_ns100_ticks is returning “valid”
data, but currently it checks it after converting it to seconds, meaning that the result
of the division gets truncated to 0 during the first second. The only invalid, deterministic error
from mono_ns100_ticks that could be used to trigger this warning is either 0 or a negative time value,
but currently it just checks for 0 as an error. The fix is to make the check on the return from
mono_ns100_ticks instead of on the result of the division by 10 000 000 as it is today.

mono/metadata/threadpool-ms.c

index 6151395688005d2ba455d7684bfec5f3bdb67d8c..6ee1e8bcd72b51c146627ffb68bf9d1087fe8e4a 100644 (file)
@@ -708,13 +708,15 @@ worker_try_create (void)
 {
        ThreadPoolCounter counter;
        MonoInternalThread *thread;
+       gint64 current_ticks;
        gint32 now;
 
        mono_coop_mutex_lock (&threadpool->worker_creation_lock);
 
        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_THREADPOOL, "[%p] try create worker", mono_native_thread_id_get ());
-
-       if ((now = mono_100ns_ticks () / 10 / 1000 / 1000) == 0) {
+       current_ticks = mono_100ns_ticks ();
+       now = current_ticks / (10 * 1000 * 1000);
+       if (0 == current_ticks) {
                g_warning ("failed to get 100ns ticks");
        } else {
                if (threadpool->worker_creation_current_second != now) {