3 * Worker threads for parallel and concurrent GC.
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
6 * Copyright (C) 2012 Xamarin Inc
8 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
11 #ifndef __MONO_SGEN_WORKER_H__
12 #define __MONO_SGEN_WORKER_H__
14 #include "mono/sgen/sgen-thread-pool.h"
16 typedef struct _WorkerData WorkerData;
17 typedef struct _WorkerContext WorkerContext;
21 typedef void (*SgenWorkersFinishCallback) (void);
22 typedef void (*SgenWorkerCallback) (WorkerData *data);
26 SgenGrayQueue private_gray_queue; /* only read/written by worker thread */
28 * Workers allocate major objects only from here. It has same structure as the
29 * global one. This is normally accessed from the worker_block_free_list_key.
30 * We hold it here so we can clear free lists from all threads before sweep
33 gpointer free_block_lists;
34 WorkerContext *context;
37 struct _WorkerContext {
39 int active_workers_num;
40 volatile gboolean started;
41 volatile gboolean forced_stop;
42 WorkerData *workers_data;
45 * When using multiple workers, we need to have the last worker
46 * enqueue the preclean jobs (if there are any). This lock ensures
47 * that when the last worker takes it, all the other workers have
48 * gracefully finished, so it can restart them.
50 mono_mutex_t finished_lock;
51 volatile gboolean workers_finished;
52 int worker_awakenings;
54 SgenSectionGrayQueue workers_distribute_gray_queue;
56 SgenObjectOperations * volatile idle_func_object_ops;
57 SgenObjectOperations *idle_func_object_ops_par, *idle_func_object_ops_nopar;
60 * finished_callback is called only when the workers finish work normally (when they
61 * are not forced to finish). The callback is used to enqueue preclean jobs.
63 volatile SgenWorkersFinishCallback finish_callback;
66 int thread_pool_context;
69 void sgen_workers_create_context (int generation, int num_workers);
70 void sgen_workers_stop_all_workers (int generation);
71 void sgen_workers_set_num_active_workers (int generation, int num_workers);
72 void sgen_workers_start_all_workers (int generation, SgenObjectOperations *object_ops_nopar, SgenObjectOperations *object_ops_par, SgenWorkersFinishCallback finish_job);
73 void sgen_workers_enqueue_job (int generation, SgenThreadPoolJob *job, gboolean enqueue);
74 void sgen_workers_join (int generation);
75 gboolean sgen_workers_have_idle_work (int generation);
76 gboolean sgen_workers_all_done (void);
77 void sgen_workers_assert_gray_queue_is_empty (int generation);
78 void sgen_workers_take_from_queue (int generation, SgenGrayQueue *queue);
79 SgenObjectOperations* sgen_workers_get_idle_func_object_ops (WorkerData *worker);
80 int sgen_workers_get_job_split_count (int generation);
81 void sgen_workers_foreach (int generation, SgenWorkerCallback callback);
82 gboolean sgen_workers_is_worker_thread (MonoNativeThreadId id);