少年修仙传客户端基础资源
hch
2024-04-01 d01413b00ef631ac20347716b23818b0b811f65f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/**
 * \file
 * Worker threads for parallel and concurrent GC.
 *
 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
 * Copyright (C) 2012 Xamarin Inc
 *
 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
 */
 
#ifndef __MONO_SGEN_WORKER_H__
#define __MONO_SGEN_WORKER_H__
 
#include "mono/sgen/sgen-thread-pool.h"
 
typedef struct _WorkerData WorkerData;
typedef struct _WorkerContext WorkerContext;
 
typedef gint32 State;
 
typedef void (*SgenWorkersFinishCallback) (void);
typedef void (*SgenWorkerCallback) (WorkerData *data);
 
struct _WorkerData {
    gint32 state;
    SgenGrayQueue private_gray_queue; /* only read/written by worker thread */
    /*
     * Workers allocate major objects only from here. It has same structure as the
     * global one. This is normally accessed from the worker_block_free_list_key.
     * We hold it here so we can clear free lists from all threads before sweep
     * starts.
     */
    gpointer free_block_lists;
    WorkerContext *context;
 
    /* Work time distribution. Measured in ticks. */
    gint64 major_scan_time, los_scan_time, total_time;
    /*
     * When changing the state of the worker from not working to work enqueued
     * we set the timestamp so we can compute for how long the worker did actual
     * work during the phase
     */
    gint64 last_start;
};
 
struct _WorkerContext {
    int workers_num;
    int active_workers_num;
    volatile gboolean started;
    volatile gboolean forced_stop;
    WorkerData *workers_data;
 
    /*
     * When using multiple workers, we need to have the last worker
     * enqueue the preclean jobs (if there are any). This lock ensures
     * that when the last worker takes it, all the other workers have
     * gracefully finished, so it can restart them.
     */
    mono_mutex_t finished_lock;
    volatile gboolean workers_finished;
    int worker_awakenings;
 
    SgenSectionGrayQueue workers_distribute_gray_queue;
 
    SgenObjectOperations * volatile idle_func_object_ops;
    SgenObjectOperations *idle_func_object_ops_par, *idle_func_object_ops_nopar;
 
    /*
     * finished_callback is called only when the workers finish work normally (when they
     * are not forced to finish). The callback is used to enqueue preclean jobs.
     */
    volatile SgenWorkersFinishCallback finish_callback;
 
    int generation;
    int thread_pool_context;
};
 
void sgen_workers_create_context (int generation, int num_workers);
void sgen_workers_stop_all_workers (int generation);
void sgen_workers_set_num_active_workers (int generation, int num_workers);
void sgen_workers_start_all_workers (int generation, SgenObjectOperations *object_ops_nopar, SgenObjectOperations *object_ops_par, SgenWorkersFinishCallback finish_job);
void sgen_workers_enqueue_job (int generation, SgenThreadPoolJob *job, gboolean enqueue);
void sgen_workers_join (int generation);
gboolean sgen_workers_have_idle_work (int generation);
gboolean sgen_workers_all_done (void);
void sgen_workers_assert_gray_queue_is_empty (int generation);
void sgen_workers_take_from_queue (int generation, SgenGrayQueue *queue);
SgenObjectOperations* sgen_workers_get_idle_func_object_ops (WorkerData *worker);
int sgen_workers_get_job_split_count (int generation);
void sgen_workers_foreach (int generation, SgenWorkerCallback callback);
gboolean sgen_workers_is_worker_thread (MonoNativeThreadId id);
 
#endif