Skip to content

Commit d9b40da

Browse files
qinsoonsepcnt
andauthored
OS interface (#1439)
This PR addresses #1420. This PR is based on top of #1418, and includes all the changes for Windows (for testing purpose). It is likely that Windows support will be removed from this PR, and will be merged separately. This PR does not try to refactor our malloc interface -- I am not sure if malloc should be included in the OS interface or not. This PR consolidates the current multiple mmap functions (such as dzmmap, mmap_fixed, mmap_noreplace, mmap_noreserve, etc), and use `MmapStrategy` to specify the expected mmap behavior. --------- Co-authored-by: sepcnt <30561671+sepcnt@users.noreply.github.com>
1 parent 1056614 commit d9b40da

34 files changed

+967
-861
lines changed

benches/mock_bench/mmapper.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ pub use criterion::Criterion;
33
use mmtk::{
44
memory_manager, mmap_anno_test,
55
util::{
6-
constants::BYTES_IN_PAGE, memory::MmapStrategy, test_private::MMAPPER,
7-
test_util::fixtures::*, Address,
6+
constants::BYTES_IN_PAGE, os::*, test_private::MMAPPER, test_util::fixtures::*, Address,
87
},
98
};
109

@@ -76,10 +75,17 @@ pub fn bench(c: &mut Criterion) {
7675
c.bench_function("ensure_mapped_regular", |b| {
7776
let start = regular.align_down(BYTES_IN_PAGE);
7877
assert!(start.is_mapped());
79-
let strategy = MmapStrategy::new(false, mmtk::util::memory::MmapProtection::ReadWrite);
8078
let anno = mmap_anno_test!();
8179
b.iter(|| {
82-
MMAPPER.ensure_mapped(start, 1, strategy, anno).unwrap();
80+
MMAPPER
81+
.ensure_mapped(
82+
start,
83+
1,
84+
HugePageSupport::No,
85+
MmapProtection::ReadWrite,
86+
anno,
87+
)
88+
.unwrap();
8389
})
8490
});
8591
}

src/plan/generational/gc_work.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::plan::PlanTraceObject;
44
use crate::plan::VectorObjectQueue;
55
use crate::policy::gc_work::TraceKind;
66
use crate::scheduler::{gc_work::*, GCWork, GCWorker, WorkBucketStage};
7+
use crate::util::os::*;
78
use crate::util::ObjectReference;
89
use crate::vm::slot::{MemorySlice, Slot};
910
use crate::vm::*;
@@ -117,7 +118,7 @@ impl<E: ProcessEdgesWork> GCWork<E::VM> for ProcessModBuf<E> {
117118
!gen.is_object_in_nursery(*obj),
118119
"{} was logged but is not mature. Dumping process memory maps:\n{}",
119120
*obj,
120-
crate::util::memory::get_process_memory_maps(),
121+
OS::get_process_memory_maps().unwrap(),
121122
);
122123
<E::VM as VMBinding>::VMObjectModel::GLOBAL_LOG_BIT_SPEC.store_atomic::<E::VM, u8>(
123124
*obj,

src/policy/copyspace.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ use crate::util::heap::{MonotonePageResource, PageResource};
1010
use crate::util::metadata::{extract_side_metadata, MetadataSpec};
1111
use crate::util::object_enum::ObjectEnumerator;
1212
use crate::util::object_forwarding;
13+
use crate::util::os::*;
1314
use crate::util::{copy::*, object_enum};
1415
use crate::util::{Address, ObjectReference};
1516
use crate::vm::*;
16-
use libc::{mprotect, PROT_EXEC, PROT_NONE, PROT_READ, PROT_WRITE};
1717
use std::sync::atomic::{AtomicBool, Ordering};
1818
use std::sync::Arc;
1919

@@ -293,8 +293,8 @@ impl<VM: VMBinding> CopySpace<VM> {
293293
}
294294
let start = self.common().start;
295295
let extent = self.common().extent;
296-
unsafe {
297-
mprotect(start.to_mut_ptr(), extent, PROT_NONE);
296+
if let Err(e) = OS::set_memory_access(start, extent, MmapProtection::NoAccess) {
297+
panic!("Failed to protect memory: {:?}", e);
298298
}
299299
trace!("Protect {:x} {:x}", start, start + extent);
300300
}
@@ -308,12 +308,8 @@ impl<VM: VMBinding> CopySpace<VM> {
308308
}
309309
let start = self.common().start;
310310
let extent = self.common().extent;
311-
unsafe {
312-
mprotect(
313-
start.to_mut_ptr(),
314-
extent,
315-
PROT_READ | PROT_WRITE | PROT_EXEC,
316-
);
311+
if let Err(e) = OS::set_memory_access(start, extent, self.common().mmap_protection()) {
312+
panic!("Failed to unprotect memory: {:?}", e);
317313
}
318314
trace!("Unprotect {:x} {:x}", start, start + extent);
319315
}

src/policy/largeobjectspace.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ impl<VM: VMBinding> LargeObjectSpace<VM> {
292292
FreeListPageResource::new_contiguous(common.start, common.extent, vm_map)
293293
};
294294
pr.protect_memory_on_release = if protect_memory_on_release {
295-
Some(common.mmap_strategy().prot)
295+
Some(common.mmap_protection())
296296
} else {
297297
None
298298
};

src/policy/lockfreeimmortalspace.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@ use crate::util::heap::gc_trigger::GCTrigger;
1414
use crate::util::heap::layout::vm_layout::vm_layout;
1515
use crate::util::heap::PageResource;
1616
use crate::util::heap::VMRequest;
17-
use crate::util::memory::MmapAnnotation;
18-
use crate::util::memory::MmapStrategy;
1917
use crate::util::metadata::side_metadata::SideMetadataContext;
2018
use crate::util::metadata::side_metadata::SideMetadataSanity;
2119
use crate::util::object_enum::ObjectEnumerator;
2220
use crate::util::opaque_pointer::*;
21+
use crate::util::os::*;
2322
use crate::util::ObjectReference;
2423
use crate::vm::VMBinding;
2524

@@ -255,11 +254,12 @@ impl<VM: VMBinding> LockFreeImmortalSpace<VM> {
255254
};
256255

257256
// Eagerly memory map the entire heap (also zero all the memory)
258-
let strategy = MmapStrategy::new(
259-
*args.options.transparent_hugepages,
260-
crate::util::memory::MmapProtection::ReadWrite,
261-
);
262-
crate::util::memory::dzmmap_noreplace(
257+
let strategy = MmapStrategy::default()
258+
.transparent_hugepages(*args.options.transparent_hugepages)
259+
.prot(crate::util::os::MmapProtection::ReadWrite)
260+
.replace(false)
261+
.reserve(true);
262+
crate::util::os::OS::dzmmap(
263263
start,
264264
aligned_total_bytes,
265265
strategy,

src/policy/space.rs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use crate::util::heap::layout::Mmapper;
3030
use crate::util::heap::layout::VMMap;
3131
use crate::util::heap::space_descriptor::SpaceDescriptor;
3232
use crate::util::heap::HeapMeta;
33-
use crate::util::memory::{self, HugePageSupport, MmapProtection, MmapStrategy};
33+
use crate::util::os::*;
3434
use crate::vm::VMBinding;
3535

3636
use std::marker::PhantomData;
@@ -191,8 +191,13 @@ pub trait Space<VM: VMBinding>: 'static + SFT + Sync + Downcast {
191191
.ensure_mapped(
192192
res.start,
193193
res.pages,
194-
self.common().mmap_strategy(),
195-
&memory::MmapAnnotation::Space {
194+
if *self.common().options.transparent_hugepages {
195+
HugePageSupport::TransparentHugePages
196+
} else {
197+
HugePageSupport::No
198+
},
199+
self.common().mmap_protection(),
200+
&MmapAnnotation::Space {
196201
name: self.get_name(),
197202
},
198203
)
@@ -202,7 +207,7 @@ pub trait Space<VM: VMBinding>: 'static + SFT + Sync + Downcast {
202207
self.get_name(),
203208
))
204209
{
205-
memory::handle_mmap_error::<VM>(mmap_error, tls, res.start, bytes);
210+
OS::handle_mmap_error::<VM>(mmap_error, tls, res.start, bytes);
206211
}
207212
};
208213
let grow_space = || {
@@ -227,7 +232,7 @@ pub trait Space<VM: VMBinding>: 'static + SFT + Sync + Downcast {
227232

228233
// TODO: Concurrent zeroing
229234
if self.common().zeroed {
230-
memory::zero(res.start, bytes);
235+
crate::util::memory::zero(res.start, bytes);
231236
}
232237

233238
// Some assertions
@@ -755,18 +760,11 @@ impl<VM: VMBinding> CommonSpace<VM> {
755760
self.vm_map
756761
}
757762

758-
pub fn mmap_strategy(&self) -> MmapStrategy {
759-
MmapStrategy {
760-
huge_page: if *self.options.transparent_hugepages {
761-
HugePageSupport::TransparentHugePages
762-
} else {
763-
HugePageSupport::No
764-
},
765-
prot: if self.permission_exec || cfg!(feature = "exec_permission_on_all_spaces") {
766-
MmapProtection::ReadWriteExec
767-
} else {
768-
MmapProtection::ReadWrite
769-
},
763+
pub fn mmap_protection(&self) -> MmapProtection {
764+
if self.permission_exec || cfg!(feature = "exec_permission_on_all_spaces") {
765+
MmapProtection::ReadWriteExec
766+
} else {
767+
MmapProtection::ReadWrite
770768
}
771769
}
772770

src/scheduler/affinity.rs

Lines changed: 3 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,6 @@
11
use super::worker::ThreadId;
22
use crate::util::options::AffinityKind;
3-
#[cfg(target_os = "linux")]
4-
use libc::{cpu_set_t, sched_getaffinity, sched_setaffinity, CPU_COUNT, CPU_SET, CPU_ZERO};
5-
6-
/// Represents the ID of a logical CPU on a system.
7-
pub type CoreId = u16;
8-
9-
// XXX: Maybe in the future we can use a library such as https://github.com/Elzair/core_affinity_rs
10-
// to have an OS agnostic way of setting thread affinity.
11-
#[cfg(target_os = "linux")]
12-
/// Return the total number of cores allocated to the program.
13-
pub fn get_total_num_cpus() -> u16 {
14-
use std::mem::MaybeUninit;
15-
unsafe {
16-
let mut cs = MaybeUninit::zeroed().assume_init();
17-
CPU_ZERO(&mut cs);
18-
sched_getaffinity(0, std::mem::size_of::<cpu_set_t>(), &mut cs);
19-
CPU_COUNT(&cs) as u16
20-
}
21-
}
22-
23-
#[cfg(not(target_os = "linux"))]
24-
/// Return the total number of cores allocated to the program.
25-
pub fn get_total_num_cpus() -> u16 {
26-
unimplemented!()
27-
}
3+
use crate::util::os::*;
284

295
impl AffinityKind {
306
/// Resolve affinity of GC thread. Has a side-effect of calling into the kernel to set the
@@ -36,51 +12,13 @@ impl AffinityKind {
3612
AffinityKind::AllInSet(cpuset) => {
3713
// Bind the current thread to all the cores in the set
3814
debug!("Set affinity for thread {} to cpuset {:?}", thread, cpuset);
39-
bind_current_thread_to_cpuset(cpuset.as_slice());
15+
OS::bind_current_thread_to_cpuset(cpuset.as_slice());
4016
}
4117
AffinityKind::RoundRobin(cpuset) => {
4218
let cpu = cpuset[thread % cpuset.len()];
4319
debug!("Set affinity for thread {} to core {}", thread, cpu);
44-
bind_current_thread_to_core(cpu);
20+
OS::bind_current_thread_to_core(cpu);
4521
}
4622
}
4723
}
4824
}
49-
50-
#[cfg(target_os = "linux")]
51-
/// Bind the current thread to the specified core.
52-
fn bind_current_thread_to_core(cpu: CoreId) {
53-
use std::mem::MaybeUninit;
54-
unsafe {
55-
let mut cs = MaybeUninit::zeroed().assume_init();
56-
CPU_ZERO(&mut cs);
57-
CPU_SET(cpu as usize, &mut cs);
58-
sched_setaffinity(0, std::mem::size_of::<cpu_set_t>(), &cs);
59-
}
60-
}
61-
62-
#[cfg(not(target_os = "linux"))]
63-
/// Bind the current thread to the specified core.
64-
fn bind_current_thread_to_core(_cpu: CoreId) {
65-
unimplemented!()
66-
}
67-
68-
#[cfg(any(target_os = "linux", target_os = "android"))]
69-
/// Bind the current thread to the specified core.
70-
fn bind_current_thread_to_cpuset(cpuset: &[CoreId]) {
71-
use std::mem::MaybeUninit;
72-
unsafe {
73-
let mut cs = MaybeUninit::zeroed().assume_init();
74-
CPU_ZERO(&mut cs);
75-
for cpu in cpuset {
76-
CPU_SET(*cpu as usize, &mut cs);
77-
}
78-
sched_setaffinity(0, std::mem::size_of::<cpu_set_t>(), &cs);
79-
}
80-
}
81-
82-
#[cfg(not(any(target_os = "linux", target_os = "android")))]
83-
/// Bind the current thread to the specified core.
84-
fn bind_current_thread_to_cpuset(_cpuset: &[CoreId]) {
85-
unimplemented!()
86-
}

src/util/alloc/free_list_allocator.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use std::sync::Arc;
44

5+
use super::allocator::AllocatorContext;
56
use crate::policy::marksweepspace::native_ms::*;
67
use crate::util::alloc::allocator;
78
use crate::util::alloc::Allocator;
@@ -10,8 +11,6 @@ use crate::util::Address;
1011
use crate::util::VMThread;
1112
use crate::vm::VMBinding;
1213

13-
use super::allocator::AllocatorContext;
14-
1514
/// A MiMalloc free list allocator
1615
#[repr(C)]
1716
pub struct FreeListAllocator<VM: VMBinding> {

src/util/heap/freelistpageresource.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use crate::util::heap::layout::vm_layout::*;
1414
use crate::util::heap::layout::CreateFreeListResult;
1515
use crate::util::heap::pageresource::CommonPageResource;
1616
use crate::util::heap::space_descriptor::SpaceDescriptor;
17-
use crate::util::memory;
1817
use crate::util::opaque_pointer::*;
18+
use crate::util::os::*;
1919
use crate::util::raw_memory_freelist::RawMemoryFreeList;
2020
use crate::vm::*;
2121
use std::marker::PhantomData;
@@ -27,7 +27,7 @@ pub struct FreeListPageResource<VM: VMBinding> {
2727
sync: Mutex<FreeListPageResourceSync>,
2828
_p: PhantomData<VM>,
2929
/// Protect memory on release, and unprotect on re-allocate.
30-
pub(crate) protect_memory_on_release: Option<memory::MmapProtection>,
30+
pub(crate) protect_memory_on_release: Option<MmapProtection>,
3131
}
3232

3333
unsafe impl<VM: VMBinding> Send for FreeListPageResource<VM> {}
@@ -219,7 +219,11 @@ impl<VM: VMBinding> FreeListPageResource<VM> {
219219
// > (e.g., read versus read/write protection) exceeding the
220220
// > allowed maximum.
221221
assert!(self.protect_memory_on_release.is_some());
222-
if let Err(e) = memory::mprotect(start, conversions::pages_to_bytes(pages)) {
222+
if let Err(e) = OS::set_memory_access(
223+
start,
224+
conversions::pages_to_bytes(pages),
225+
MmapProtection::NoAccess,
226+
) {
223227
panic!(
224228
"Failed at protecting memory (starting at {}): {:?}",
225229
start, e
@@ -230,7 +234,7 @@ impl<VM: VMBinding> FreeListPageResource<VM> {
230234
/// Unprotect the memory
231235
fn munprotect(&self, start: Address, pages: usize) {
232236
assert!(self.protect_memory_on_release.is_some());
233-
if let Err(e) = memory::munprotect(
237+
if let Err(e) = OS::set_memory_access(
234238
start,
235239
conversions::pages_to_bytes(pages),
236240
self.protect_memory_on_release.unwrap(),

src/util/heap/layout/map64.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::util::freelist::FreeList;
66
use crate::util::heap::layout::heap_parameters::*;
77
use crate::util::heap::layout::vm_layout::*;
88
use crate::util::heap::space_descriptor::SpaceDescriptor;
9-
use crate::util::memory::MmapStrategy;
9+
use crate::util::os::*;
1010
use crate::util::raw_memory_freelist::RawMemoryFreeList;
1111
use crate::util::Address;
1212
use std::cell::UnsafeCell;

0 commit comments

Comments
 (0)