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
;
36 /* Work time distribution. Measured in ticks. */
37 gint64 major_scan_time
, los_scan_time
, total_time
;
39 * When changing the state of the worker from not working to work enqueued
40 * we set the timestamp so we can compute for how long the worker did actual
41 * work during the phase
46 struct _WorkerContext
{
48 int active_workers_num
;
49 volatile gboolean started
;
50 volatile gboolean forced_stop
;
51 WorkerData
*workers_data
;
54 * When using multiple workers, we need to have the last worker
55 * enqueue the preclean jobs (if there are any). This lock ensures
56 * that when the last worker takes it, all the other workers have
57 * gracefully finished, so it can restart them.
59 mono_mutex_t finished_lock
;
60 volatile gboolean workers_finished
;
61 int worker_awakenings
;
63 SgenSectionGrayQueue workers_distribute_gray_queue
;
65 SgenObjectOperations
* volatile idle_func_object_ops
;
66 SgenObjectOperations
*idle_func_object_ops_par
, *idle_func_object_ops_nopar
;
69 * finished_callback is called only when the workers finish work normally (when they
70 * are not forced to finish). The callback is used to enqueue preclean jobs.
72 volatile SgenWorkersFinishCallback finish_callback
;
75 int thread_pool_context
;
78 void sgen_workers_create_context (int generation
, int num_workers
);
79 void sgen_workers_stop_all_workers (int generation
);
80 void sgen_workers_set_num_active_workers (int generation
, int num_workers
);
81 void sgen_workers_start_all_workers (int generation
, SgenObjectOperations
*object_ops_nopar
, SgenObjectOperations
*object_ops_par
, SgenWorkersFinishCallback finish_job
);
82 void sgen_workers_enqueue_job (int generation
, SgenThreadPoolJob
*job
, gboolean enqueue
);
83 void sgen_workers_join (int generation
);
84 gboolean
sgen_workers_have_idle_work (int generation
);
85 gboolean
sgen_workers_all_done (void);
86 void sgen_workers_assert_gray_queue_is_empty (int generation
);
87 void sgen_workers_take_from_queue (int generation
, SgenGrayQueue
*queue
);
88 SgenObjectOperations
* sgen_workers_get_idle_func_object_ops (WorkerData
*worker
);
89 int sgen_workers_get_job_split_count (int generation
);
90 int sgen_workers_get_active_worker_count (int generation
);
91 void sgen_workers_foreach (int generation
, SgenWorkerCallback callback
);
92 gboolean
sgen_workers_is_worker_thread (MonoNativeThreadId id
);