Far more progress

This commit is contained in:
4lDO2
2023-11-01 11:29:30 +01:00
parent f4d270c7ce
commit baf46a3555
+45 -24
View File
@@ -48,14 +48,17 @@ pub fn allocate_frame() -> Option<Frame> {
allocate_frames(1)
}
pub fn allocate_frames_complex(count: usize, flags: (), strategy: Option<()>, min: usize) -> Option<(Frame, usize)> {
let before = get_freelist_pagecount();
//debug_freelist();
// TODO: Split into sub-power of two allocations.
let min_order = min.next_power_of_two().trailing_zeros();
let _req_order = count.next_power_of_two().trailing_zeros();
log::info!("PREALLOC 2^{min_order}");
/*if DEBUG.load(Ordering::Relaxed) > 0 {
log::info!("BEFORE");
log::info!("PREALLOC 2^{min_order}");
debug_freelist();
}*/
//let before = get_freelist_pagecount();
//debug_freelist();
let mut freelist = FREELIST.lock();
@@ -74,6 +77,7 @@ pub fn allocate_frames_complex(count: usize, flags: (), strategy: Option<()>, mi
//log::info!("FREE {frame:?} ORDER {frame_order} NEXT_FREE {next_free:?}");
if let Some(next) = next_free.frame() {
assert_ne!(next, frame);
assert!(next.is_aligned_to_order(frame_order), "NEXT {next:?} UNALIGNED");
get_free_alloc_page_info(next).set_prev(P2Frame::new(None, frame_order));
}
@@ -90,10 +94,9 @@ pub fn allocate_frames_complex(count: usize, flags: (), strategy: Option<()>, mi
let hi = frame.next_by(order_page_count);
//log::info!("SPLIT INTO {frame:?}:{hi:?} ORDER {order}");
if let Some(old_head) = freelist[order as usize].replace(hi) {
let hi_info = get_page_info(hi).expect("sub-p2frame of split p2flame lacked PageInfo").make_free(order);
assert!(!hi.is_aligned_to_order(frame_order));
assert_eq!(freelist[order as usize], None);
/*if let Some(old_head) = freelist[order as usize].replace(hi) {
hi_info.set_next(P2Frame::new(Some(old_head), order));
hi_info.set_prev(P2Frame::new(None, order));
//
@@ -103,13 +106,20 @@ pub fn allocate_frames_complex(count: usize, flags: (), strategy: Option<()>, mi
let old_head_info = get_free_alloc_page_info(old_head);
assert_eq!(old_head_info.prev().frame(), None);
old_head_info.set_prev(P2Frame::new(Some(hi), order));
}
}*/
let hi_info = get_page_info(hi).expect("sub-p2frame of split p2flame lacked PageInfo").make_free(order);
assert!(!hi.is_aligned_to_order(frame_order));
hi_info.set_next(P2Frame::new(None, order));
hi_info.set_prev(P2Frame::new(None, order));
freelist[order as usize] = Some(hi);
}
drop(freelist);
_get_freelist_pagecount(false, min_order, frame_order);
/*_get_freelist_pagecount(false, min_order, frame_order, true);
_get_freelist_pagecount(false, min_order, frame_order, false);*/
info.mark_used();
_get_freelist_pagecount(false, min_order, frame_order);
/*_get_freelist_pagecount(false, min_order, frame_order, false);
_get_freelist_pagecount(false, min_order, frame_order, true);*/
unsafe {
(RmmA::phys_to_virt(frame.start_address()).data() as *mut u8).write_bytes(0, PAGE_SIZE << min_order);
@@ -128,23 +138,27 @@ pub fn allocate_frames_complex(count: usize, flags: (), strategy: Option<()>, mi
}
assert!(found);
}*/
let after = _get_freelist_pagecount(false, min_order, frame_order);
/*let after = _get_freelist_pagecount(false, min_order, frame_order, false);
assert_eq!(after, before - (1 << min_order));
log::info!("ALLOCED {frame:?}+2^{min_order}");
if DEBUG.load(Ordering::Relaxed) > 0 {
log::info!("ALLOCED {frame:?}+2^{min_order}");
log::info!("AFTER");
debug_freelist();
}*/
Some((frame, PAGE_SIZE << min_order))
}
/// Deallocate a range of frames
pub unsafe fn deallocate_frames(frame: Frame, count: usize) {
log::info!("DEALLOC{frame:?}+{count}");
/*log::info!("DEALLOC{frame:?}+{count}");
let before = get_freelist_pagecount();
debug_freelist();
debug_freelist();*/
deallocate_frames_inner(frame, count);
debug_freelist();
/*debug_freelist();
//loop {}
let after = get_freelist_pagecount();
let after = get_freelist_pagecount();*/
}
unsafe fn deallocate_frames_inner(frame: Frame, count: usize) {
if count == 0 {
@@ -184,9 +198,10 @@ unsafe fn deallocate_frames_inner(frame: Frame, count: usize) {
}
}
fn get_freelist_pagecount() -> usize {
_get_freelist_pagecount(false, 100, 100)
_get_freelist_pagecount(false, 100, 100, false)
}
fn _get_freelist_pagecount(debug: bool, o: u32, f: u32) -> usize {
pub static DEBUG: AtomicUsize = AtomicUsize::new(0);
fn _get_freelist_pagecount(debug: bool, o: u32, f: u32, set_not_clear: bool) -> usize {
let mut pagecount = 0;
let freelist = FREELIST.lock();
@@ -214,10 +229,16 @@ fn _get_freelist_pagecount(debug: bool, o: u32, f: u32) -> usize {
drop(freelist);
if !debug {
log::info!("M{o}F{f}");
_get_freelist_pagecount(true, o, f);
//_get_freelist_pagecount(true, o, f, false);
debug_freelist();
}
panic!("i{i}o{order}");
};
if set_not_clear {
assert!(next_info.next.fetch_or(RC_USED_NOT_FREE, Ordering::Relaxed) & RC_USED_NOT_FREE == 0);
} else {
next_info.next.fetch_and(!RC_USED_NOT_FREE, Ordering::Relaxed);
}
let next_frame = next_info.next().frame();
/*if next_info.order() != order {
log::info!("BAD ORDER FOR {next_frame:?}");
@@ -282,7 +303,7 @@ unsafe fn deallocate_p2frame(mut frame: Frame, order: u32) {
if lo_info.next().order() != merge_order || hi_info.next().order() != merge_order {
break;
}
log::info!("MERGED {lo:?} WITH {hi:?} ORDER {order}");
//log::info!("MERGED {lo:?} WITH {hi:?} ORDER {order}");
let lo_next = lo_info.next();
let lo_prev = lo_info.prev();
@@ -356,7 +377,7 @@ unsafe fn deallocate_p2frame(mut frame: Frame, order: u32) {
old_head_info.set_prev(P2Frame::new(Some(new_head), largest_order));
}
log::info!("FREED {frame:?}+2^{order}");
//log::info!("FREED {frame:?}+2^{order}");
}
pub unsafe fn deallocate_frame(frame: Frame) {
@@ -387,9 +408,9 @@ impl P2Frame {
)
}
fn get(self) -> (Option<Frame>, u32) {
assert_ne!(self.0 & RC_USED_NOT_FREE, RC_USED_NOT_FREE);
//assert_ne!(self.0 & RC_USED_NOT_FREE, RC_USED_NOT_FREE);
let page_off_mask = PAGE_SIZE - 1;
(NonZeroUsize::new(self.0 & !page_off_mask).map(|physaddr| Frame { physaddr }), (self.0 & page_off_mask) as u32)
(NonZeroUsize::new(self.0 & !page_off_mask & !(RC_USED_NOT_FREE)).map(|physaddr| Frame { physaddr }), (self.0 & page_off_mask) as u32)
}
fn frame(self) -> Option<Frame> {
self.get().0
@@ -996,7 +1017,7 @@ pub fn get_page_info(frame: Frame) -> Option<&'static PageInfo> {
#[track_caller]
fn get_free_alloc_page_info(frame: Frame) -> PageInfoFree<'static> {
let i = get_page_info(frame).unwrap_or_else(|| panic!("allocator-owned frames need a PageInfo, but none for {frame:?}"));
i.as_free().unwrap_or_else(|| panic!("expected frame to be free, but {frame:?} wasn't, in {i:?}"))
i.as_free().unwrap()//.unwrap_or_else(|| panic!("expected frame to be free, but {frame:?} wasn't, in {i:?}"))
}
pub struct Segv;