Merge pull request #3028 from lateralusX/jlorenss/threadpool_warning
authorLudovic Henry <ludovic@xamarin.com>
Thu, 26 May 2016 13:26:51 +0000 (15:26 +0200)
committerLudovic Henry <ludovic@xamarin.com>
Thu, 26 May 2016 13:26:51 +0000 (15:26 +0200)
Incorrect warning message on thread pool startup in full AOT:ed Windows build.

1  2 
mono/metadata/threadpool-ms.c

index 9e18e8c3eff9a66a2d5a06c22805a3a17e8d56ea,6ee1e8bcd72b51c146627ffb68bf9d1087fe8e4a..1f4a6cc605237a36e6f13c3a28acc3c229086dff
@@@ -140,10 -140,10 +140,10 @@@ typedef struct 
        MonoCoopMutex worker_creation_lock;
  
        gint32 heuristic_completions;
 -      guint32 heuristic_sample_start;
 -      guint32 heuristic_last_dequeue; // ms
 -      guint32 heuristic_last_adjustment; // ms
 -      guint32 heuristic_adjustment_interval; // ms
 +      gint64 heuristic_sample_start;
 +      gint64 heuristic_last_dequeue; // ms
 +      gint64 heuristic_last_adjustment; // ms
 +      gint64 heuristic_adjustment_interval; // ms
        ThreadPoolHillClimbing heuristic_hill_climbing;
        MonoCoopMutex heuristic_lock;
  
@@@ -708,13 -708,15 +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) {
@@@ -855,7 -857,7 +857,7 @@@ monitor_should_keep_running (void
  static gboolean
  monitor_sufficient_delay_since_last_dequeue (void)
  {
 -      guint32 threshold;
 +      gint64 threshold;
  
        g_assert (threadpool);
  
@@@ -893,7 -895,7 +895,7 @@@ monitor_thread (void
                mono_gc_set_skip_thread (TRUE);
  
                do {
 -                      guint32 ts;
 +                      gint64 ts;
                        gboolean alerted = FALSE;
  
                        if (mono_runtime_is_shutting_down ())
@@@ -1052,7 -1054,7 +1054,7 @@@ hill_climbing_get_wave_component (gdoub
  }
  
  static gint16
 -hill_climbing_update (gint16 current_thread_count, guint32 sample_duration, gint32 completions, guint32 *adjustment_interval)
 +hill_climbing_update (gint16 current_thread_count, guint32 sample_duration, gint32 completions, gint64 *adjustment_interval)
  {
        ThreadPoolHillClimbing *hc;
        ThreadPoolHeuristicStateTransition transition;
@@@ -1292,8 -1294,8 +1294,8 @@@ heuristic_adjust (void
  
        if (mono_coop_mutex_trylock (&threadpool->heuristic_lock) == 0) {
                gint32 completions = InterlockedExchange (&threadpool->heuristic_completions, 0);
 -              guint32 sample_end = mono_msec_ticks ();
 -              guint32 sample_duration = sample_end - threadpool->heuristic_sample_start;
 +              gint64 sample_end = mono_msec_ticks ();
 +              gint64 sample_duration = sample_end - threadpool->heuristic_sample_start;
  
                if (sample_duration >= threadpool->heuristic_adjustment_interval / 2) {
                        ThreadPoolCounter counter;
@@@ -1341,8 -1343,7 +1343,8 @@@ mono_threadpool_ms_begin_invoke (MonoDo
  
        mono_error_init (error);
  
 -      message = mono_method_call_message_new (method, params, mono_get_delegate_invoke (method->klass), (params != NULL) ? (&async_callback) : NULL, (params != NULL) ? (&state) : NULL);
 +      message = mono_method_call_message_new (method, params, mono_get_delegate_invoke (method->klass), (params != NULL) ? (&async_callback) : NULL, (params != NULL) ? (&state) : NULL, error);
 +      return_val_if_nok (error, NULL);
  
        async_call = (MonoAsyncCall*) mono_object_new_checked (domain, async_call_klass, error);
        return_val_if_nok (error, NULL);
                MONO_OBJECT_SETREF (async_call, cb_target, async_callback);
        }
  
 -      async_result = mono_async_result_new (domain, NULL, async_call->state, NULL, (MonoObject*) async_call);
 +      async_result = mono_async_result_new (domain, NULL, async_call->state, NULL, (MonoObject*) async_call, error);
 +      return_val_if_nok (error, NULL);
        MONO_OBJECT_SETREF (async_result, async_delegate, target);
  
        mono_threadpool_ms_enqueue_work_item (domain, (MonoObject*) async_result, error);
  }
  
  MonoObject *
 -mono_threadpool_ms_end_invoke (MonoAsyncResult *ares, MonoArray **out_args, MonoObject **exc)
 +mono_threadpool_ms_end_invoke (MonoAsyncResult *ares, MonoArray **out_args, MonoObject **exc, MonoError *error)
  {
 -      MonoError error;
        MonoAsyncCall *ac;
  
 +      mono_error_init (error);
        g_assert (exc);
        g_assert (out_args);
  
        mono_monitor_enter ((MonoObject*) ares);
  
        if (ares->endinvoke_called) {
 -              *exc = (MonoObject*) mono_get_exception_invalid_operation (NULL);
 +              mono_error_set_invalid_operation(error, "Delegate EndInvoke method called more than once");
                mono_monitor_exit ((MonoObject*) ares);
                return NULL;
        }
                } else {
                        wait_event = CreateEvent (NULL, TRUE, FALSE, NULL);
                        g_assert(wait_event);
 -                      MonoWaitHandle *wait_handle = mono_wait_handle_new (mono_object_domain (ares), wait_event, &error);
 -                      mono_error_raise_exception (&error); /* FIXME don't raise here */
 +                      MonoWaitHandle *wait_handle = mono_wait_handle_new (mono_object_domain (ares), wait_event, error);
 +                      if (!is_ok (error)) {
 +                              CloseHandle (wait_event);
 +                              return NULL;
 +                      }
                        MONO_OBJECT_SETREF (ares, handle, (MonoObject*) wait_handle);
                }
                mono_monitor_exit ((MonoObject*) ares);
 -              MONO_PREPARE_BLOCKING;
 +              MONO_ENTER_GC_SAFE;
                WaitForSingleObjectEx (wait_event, INFINITE, TRUE);
 -              MONO_FINISH_BLOCKING;
 +              MONO_EXIT_GC_SAFE;
        }
  
        ac = (MonoAsyncCall*) ares->object_data;
@@@ -1423,7 -1420,7 +1425,7 @@@ gboolea
  mono_threadpool_ms_remove_domain_jobs (MonoDomain *domain, int timeout)
  {
        gboolean res = TRUE;
 -      guint32 start;
 +      gint64 end;
        gpointer sem;
  
        g_assert (domain);
        g_assert (mono_domain_is_unloading (domain));
  
        if (timeout != -1)
 -              start = mono_msec_ticks ();
 +              end = mono_msec_ticks () + timeout;
  
  #ifndef DISABLE_SOCKETS
        mono_threadpool_ms_io_remove_domain_jobs (domain);
        if (timeout != -1) {
 -              timeout -= mono_msec_ticks () - start;
 -              if (timeout < 0)
 +              if (mono_msec_ticks () > end)
                        return FALSE;
        }
  #endif
        mono_memory_write_barrier ();
  
        while (domain->threadpool_jobs) {
 -              MONO_PREPARE_BLOCKING;
 -              WaitForSingleObject (sem, timeout);
 -              MONO_FINISH_BLOCKING;
 +              gint64 now;
 +
                if (timeout != -1) {
 -                      timeout -= mono_msec_ticks () - start;
 -                      if (timeout <= 0) {
 +                      now = mono_msec_ticks ();
 +                      if (now > end) {
                                res = FALSE;
                                break;
                        }
                }
 +
 +              MONO_ENTER_GC_SAFE;
 +              WaitForSingleObject (sem, timeout != -1 ? end - now : timeout);
 +              MONO_EXIT_GC_SAFE;
        }
  
        domain->cleanup_semaphore = NULL;