1
1
//! Statistics for work packets
2
2
use super :: work_counter:: { WorkCounter , WorkCounterBase , WorkDuration } ;
3
+ #[ cfg( feature = "perf_counter" ) ]
4
+ use crate :: scheduler:: work_counter:: WorkPerfEvent ;
5
+ use crate :: scheduler:: Context ;
6
+ use crate :: vm:: VMBinding ;
7
+ use crate :: MMTK ;
3
8
use std:: any:: TypeId ;
4
9
use std:: collections:: HashMap ;
10
+ use std:: marker:: PhantomData ;
5
11
use std:: sync:: atomic:: { AtomicBool , Ordering } ;
6
12
7
13
/// Merge and print the work-packet level statistics from all worker threads
@@ -99,7 +105,7 @@ impl SchedulerStat {
99
105
stat
100
106
}
101
107
/// Merge work counters from different worker threads
102
- pub fn merge ( & mut self , stat : & WorkerLocalStat ) {
108
+ pub fn merge < C > ( & mut self , stat : & WorkerLocalStat < C > ) {
103
109
// Merge work packet type ID to work packet name mapping
104
110
for ( id, name) in & stat. work_id_name_map {
105
111
self . work_id_name_map . insert ( * id, * name) ;
@@ -144,7 +150,7 @@ impl WorkStat {
144
150
/// Stop all work counters for the work packet type of the just executed
145
151
/// work packet
146
152
#[ inline( always) ]
147
- pub fn end_of_work ( & self , worker_stat : & mut WorkerLocalStat ) {
153
+ pub fn end_of_work < C : Context > ( & self , worker_stat : & mut WorkerLocalStat < C > ) {
148
154
if !worker_stat. is_enabled ( ) {
149
155
return ;
150
156
} ;
@@ -165,15 +171,27 @@ impl WorkStat {
165
171
}
166
172
167
173
/// Worker thread local counterpart of [`SchedulerStat`]
168
- #[ derive( Default ) ]
169
- pub struct WorkerLocalStat {
174
+ pub struct WorkerLocalStat < C > {
170
175
work_id_name_map : HashMap < TypeId , & ' static str > ,
171
176
work_counts : HashMap < TypeId , usize > ,
172
177
work_counters : HashMap < TypeId , Vec < Box < dyn WorkCounter > > > ,
173
178
enabled : AtomicBool ,
179
+ _phantom : PhantomData < C > ,
180
+ }
181
+
182
+ impl < C > Default for WorkerLocalStat < C > {
183
+ fn default ( ) -> Self {
184
+ WorkerLocalStat {
185
+ work_id_name_map : Default :: default ( ) ,
186
+ work_counts : Default :: default ( ) ,
187
+ work_counters : Default :: default ( ) ,
188
+ enabled : AtomicBool :: new ( false ) ,
189
+ _phantom : Default :: default ( ) ,
190
+ }
191
+ }
174
192
}
175
193
176
- impl WorkerLocalStat {
194
+ impl < C : Context > WorkerLocalStat < C > {
177
195
#[ inline]
178
196
pub fn is_enabled ( & self ) -> bool {
179
197
self . enabled . load ( Ordering :: SeqCst )
@@ -185,23 +203,48 @@ impl WorkerLocalStat {
185
203
/// Measure the execution of a work packet by starting all counters for that
186
204
/// type
187
205
#[ inline]
188
- pub fn measure_work ( & mut self , work_id : TypeId , work_name : & ' static str ) -> WorkStat {
206
+ pub fn measure_work (
207
+ & mut self ,
208
+ work_id : TypeId ,
209
+ work_name : & ' static str ,
210
+ context : & ' static C ,
211
+ ) -> WorkStat {
189
212
let stat = WorkStat {
190
213
type_id : work_id,
191
214
type_name : work_name,
192
215
} ;
193
216
if self . is_enabled ( ) {
194
217
self . work_counters
195
218
. entry ( work_id)
196
- . or_insert_with ( WorkerLocalStat :: counter_set)
219
+ . or_insert_with ( || C :: counter_set ( context ) )
197
220
. iter_mut ( )
198
221
. for_each ( |c| c. start ( ) ) ;
199
222
}
200
223
stat
201
224
}
225
+ }
202
226
203
- // The set of work counters for all work packet types
204
- fn counter_set ( ) -> Vec < Box < dyn WorkCounter > > {
227
+ /// Private trait to let different contexts supply different sets of default
228
+ /// counters
229
+ trait HasCounterSet {
230
+ fn counter_set ( context : & ' static Self ) -> Vec < Box < dyn WorkCounter > > ;
231
+ }
232
+
233
+ impl < C > HasCounterSet for C {
234
+ default fn counter_set ( _context : & ' static Self ) -> Vec < Box < dyn WorkCounter > > {
205
235
vec ! [ Box :: new( WorkDuration :: new( ) ) ]
206
236
}
207
237
}
238
+
239
+ /// Specialization for MMTk to read the options
240
+ #[ allow( unused_variables, unused_mut) ]
241
+ impl < VM : VMBinding > HasCounterSet for MMTK < VM > {
242
+ fn counter_set ( mmtk : & ' static Self ) -> Vec < Box < dyn WorkCounter > > {
243
+ let mut counters: Vec < Box < dyn WorkCounter > > = vec ! [ Box :: new( WorkDuration :: new( ) ) ] ;
244
+ #[ cfg( feature = "perf_counter" ) ]
245
+ for e in & mmtk. options . perf_events . events {
246
+ counters. push ( box WorkPerfEvent :: new ( & e. 0 , e. 1 , e. 2 ) ) ;
247
+ }
248
+ counters
249
+ }
250
+ }
0 commit comments