@@ -20,7 +20,7 @@ lazy_static! {
20
20
local: vec![ ] ,
21
21
} ;
22
22
23
- // lock to synchronize the mapping for the active chunk space
23
+ // lock to synchronize the mapping of side metadata for a newly allocated chunk by malloc
24
24
static ref CHUNK_MAP_LOCK : Mutex <( ) > = Mutex :: new( ( ) ) ;
25
25
}
26
26
@@ -110,27 +110,37 @@ fn map_active_chunk_metadata(chunk_start: Address) {
110
110
// We map the active chunk metadata (if not previously mapped), as well as the alloc bit metadata
111
111
// and active page metadata here
112
112
pub fn map_meta_space_for_chunk ( metadata : & SideMetadataContext , chunk_start : Address ) {
113
- {
114
- // In order to prevent race conditions, we synchronize on the lock first and then
115
- // check if we need to map the active chunk metadata for `chunk_start`
116
- let _lock = CHUNK_MAP_LOCK . lock ( ) . unwrap ( ) ;
117
- if !is_chunk_mapped ( chunk_start) {
118
- map_active_chunk_metadata ( chunk_start) ;
119
- }
113
+ // In order to prevent race conditions, we synchronize on the lock first and then
114
+ // check if we need to map the active chunk metadata for `chunk_start`
115
+ let _lock = CHUNK_MAP_LOCK . lock ( ) . unwrap ( ) ;
116
+
117
+ // Check if the chunk bit metadata is mapped. If it is not mapped, map it.
118
+ // Note that the chunk bit metadata is global. It may have been mapped because other policy mapped it.
119
+ if !is_chunk_mapped ( chunk_start) {
120
+ map_active_chunk_metadata ( chunk_start) ;
120
121
}
121
122
123
+ // If we have set the chunk bit, return. This is needed just in case another thread has done this before
124
+ // we can acquire the lock.
122
125
if is_chunk_marked ( chunk_start) {
123
126
return ;
124
127
}
125
128
126
- set_chunk_mark ( chunk_start) ;
129
+ // Attempt to map the local metadata for the policy.
130
+ // Note that this might fail. For example, we have marked a chunk as active but later we freed all
131
+ // the objects in it, and unset its chunk bit. However, we do not free its metadata. So for the chunk,
132
+ // its chunk bit is mapped, but not marked, and all its local metadata is also mapped.
127
133
let mmap_metadata_result = metadata. try_map_metadata_space ( chunk_start, BYTES_IN_CHUNK ) ;
128
- trace ! ( "set chunk mark bit for {}" , chunk_start) ;
129
134
debug_assert ! (
130
135
mmap_metadata_result. is_ok( ) ,
131
136
"mmap sidemetadata failed for chunk_start ({})" ,
132
137
chunk_start
133
138
) ;
139
+
140
+ // Set the chunk mark at the end. So if we have chunk mark set, we know we have mapped side metadata
141
+ // for the chunk.
142
+ trace ! ( "set chunk mark bit for {}" , chunk_start) ;
143
+ set_chunk_mark ( chunk_start) ;
134
144
}
135
145
136
146
// Check if a given object was allocated by malloc
0 commit comments