[sgen] Make job waiting reliable
authorVlad Brezae <brezaevlad@gmail.com>
Tue, 27 Jun 2017 20:52:04 +0000 (23:52 +0300)
committerVlad Brezae <brezaevlad@gmail.com>
Wed, 28 Jun 2017 10:12:06 +0000 (13:12 +0300)
While this is not an issue yet, sgen_thread_pool_wait_for_all_jobs is logically expected to be called by the main thread and resume execution after all jobs have been executed. Concurrent M&S can enqueue additional jobs as part of its finishing phase, which means that we could detect early that no more jobs are to be processed. Make sure this is not the case.

mono/sgen/sgen-workers.c

index 8a615ede6388b42fd1e4b90f50347264e64bba94..7eb3740cc15cc15bcec3866f2f750f2acec917fa 100644 (file)
@@ -383,8 +383,10 @@ sgen_workers_stop_all_workers (int generation)
 {
        WorkerContext *context = &worker_contexts [generation];
 
+       mono_os_mutex_lock (&context->finished_lock);
        context->finish_callback = NULL;
-       mono_memory_write_barrier ();
+       mono_os_mutex_unlock (&context->finished_lock);
+
        context->forced_stop = TRUE;
 
        sgen_thread_pool_wait_for_all_jobs (context->thread_pool_context);
@@ -435,6 +437,7 @@ sgen_workers_join (int generation)
        WorkerContext *context = &worker_contexts [generation];
        int i;
 
+       SGEN_ASSERT (0, !context->finish_callback, "Why are we joining concurrent mark early");
        /*
         * It might be the case that a worker didn't get to run anything
         * in this context, because it was stuck working on a long job