@@ -6,28 +6,62 @@ use mmtk::vm::ActivePlan;
6
6
use mmtk:: Mutator ;
7
7
use mmtk:: Plan ;
8
8
use std:: mem;
9
- use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
10
9
use JikesRVM ;
11
10
use JTOC_BASE ;
12
11
use SINGLETON ;
13
12
14
- static MUTATOR_COUNTER : AtomicUsize = AtomicUsize :: new ( 0 ) ;
13
+ use std:: sync:: { Mutex , MutexGuard } ;
14
+
15
+ lazy_static ! {
16
+ static ref MUTATOR_LOCK : Mutex <( ) > = Mutex :: new( ( ) ) ;
17
+ }
18
+
19
+ struct JikesRVMMutatorIterator < ' a > {
20
+ _guard : MutexGuard < ' a , ( ) > ,
21
+ counter : usize ,
22
+ }
23
+
24
+ impl < ' a > JikesRVMMutatorIterator < ' a > {
25
+ fn new ( guard : MutexGuard < ' a , ( ) > ) -> Self {
26
+ Self {
27
+ _guard : guard,
28
+ counter : 0 ,
29
+ }
30
+ }
31
+ }
32
+
33
+ impl < ' a > Iterator for JikesRVMMutatorIterator < ' a > {
34
+ type Item = & ' a mut Mutator < JikesRVM > ;
35
+
36
+ fn next ( & mut self ) -> Option < Self :: Item > {
37
+ // We don't need this in the loop for STW-GC
38
+ let num_threads = unsafe { ( JTOC_BASE + NUM_THREADS_FIELD_OFFSET ) . load :: < usize > ( ) } ;
39
+ loop {
40
+ let idx = self . counter ;
41
+ self . counter += 1 ;
42
+ if idx >= num_threads {
43
+ return None ;
44
+ } else {
45
+ let t = unsafe { VMCollection :: thread_from_index ( idx) } ;
46
+ let is_mutator = unsafe { !( t + IS_COLLECTOR_FIELD_OFFSET ) . load :: < bool > ( ) } ;
47
+ if is_mutator {
48
+ unsafe {
49
+ let mutator = ( t + MMTK_HANDLE_FIELD_OFFSET ) . load :: < usize > ( ) ;
50
+ let ret = & mut * ( mutator as * mut Mutator < JikesRVM > ) ;
51
+ return Some ( ret) ;
52
+ }
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
15
58
16
59
#[ derive( Default ) ]
17
60
pub struct VMActivePlan { }
18
61
19
62
impl ActivePlan < JikesRVM > for VMActivePlan {
20
63
fn number_of_mutators ( ) -> usize {
21
- let num_threads = unsafe { ( JTOC_BASE + NUM_THREADS_FIELD_OFFSET ) . load :: < usize > ( ) } ;
22
- let mut num_mutators = 0usize ;
23
- for idx in 0 ..num_threads {
24
- let t = unsafe { VMCollection :: thread_from_index ( idx) } ;
25
- let is_mutator = unsafe { !( t + IS_COLLECTOR_FIELD_OFFSET ) . load :: < bool > ( ) } ;
26
- if is_mutator {
27
- num_mutators += 1 ;
28
- }
29
- }
30
- num_mutators
64
+ Self :: mutators ( ) . count ( )
31
65
}
32
66
33
67
fn global ( ) -> & ' static dyn Plan < VM = JikesRVM > {
@@ -48,28 +82,8 @@ impl ActivePlan<JikesRVM> for VMActivePlan {
48
82
}
49
83
}
50
84
51
- fn reset_mutator_iterator ( ) {
52
- MUTATOR_COUNTER . store ( 0 , Ordering :: Relaxed ) ;
53
- }
54
-
55
- fn get_next_mutator ( ) -> Option < & ' static mut Mutator < JikesRVM > > {
56
- // We don't need this in the loop for STW-GC
57
- let num_threads = unsafe { ( JTOC_BASE + NUM_THREADS_FIELD_OFFSET ) . load :: < usize > ( ) } ;
58
- loop {
59
- let idx = MUTATOR_COUNTER . fetch_add ( 1 , Ordering :: Relaxed ) ;
60
- if idx >= num_threads {
61
- return None ;
62
- } else {
63
- let t = unsafe { VMCollection :: thread_from_index ( idx) } ;
64
- let is_mutator = unsafe { !( t + IS_COLLECTOR_FIELD_OFFSET ) . load :: < bool > ( ) } ;
65
- if is_mutator {
66
- unsafe {
67
- let mutator = ( t + MMTK_HANDLE_FIELD_OFFSET ) . load :: < usize > ( ) ;
68
- let ret = & mut * ( mutator as * mut Mutator < JikesRVM > ) ;
69
- return Some ( ret) ;
70
- }
71
- }
72
- }
73
- }
85
+ fn mutators < ' a > ( ) -> Box < dyn Iterator < Item = & ' a mut Mutator < JikesRVM > > + ' a > {
86
+ let guard = MUTATOR_LOCK . lock ( ) . unwrap ( ) ;
87
+ Box :: new ( JikesRVMMutatorIterator :: new ( guard) )
74
88
}
75
89
}
0 commit comments