
use alloc::boxed::Box;
use alloc::vec;
use buddy_system_allocator::LockedHeap;
use crate::config::KERNEL_HEAP_SIZE;
use crate::println;


// 动态内存分配器
#[global_allocator]
static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty();

// 内存分配失败时, 会调用此错误处理函数

// 堆的空间
static mut HEAP_SPACE: [u8; KERNEL_HEAP_SIZE] = [0; KERNEL_HEAP_SIZE];


// 为内存分配器, 绑定一个空间用来实现动态内存分配
pub fn init_heap() {
    unsafe {
        HEAP_ALLOCATOR
            .lock()
            .init(HEAP_SPACE.as_ptr() as usize, KERNEL_HEAP_SIZE);
    }
    // heap_test()
}

pub fn heap_test() {
    use alloc::boxed::Box;
    use alloc::vec::Vec;
    extern "C" {
        fn sbss();
        fn ebss();
    }
    let bss_range = sbss as usize..ebss as usize;
    println!("bss_range {:?}", bss_range);

    let a = Box::new(5);
    println!("a: {:?}  ptr: {:p}", a, a.as_ref());
    let b = Box::new(6);
    println!("b: {:?}  ptr: {:p}", b, b.as_ref());


    unsafe {
        println!("HEAP_SPACE: {:?}", HEAP_SPACE.as_ptr())
    }

    let mut v = vec![];
    for i in 0..500{
        v.push(i);
    }

    for i in 0..500{
        v.pop();
    }

    println!("{:?}", v);

    // 通过输出打印, 发现 a 和b 均被分配在了 HEAP_SPACE 中, 且 HEAP_SPACE 被分配在了 bss段中, 这个段由我们 linker.ld 进行手动布局
    // 目前整个bss段的大小都是3M, 说明当前bss段中只有这一个 数据
}

#[alloc_error_handler]
pub fn handle_alloc_error(layout: core::alloc::Layout) -> ! {
    panic!("Heap allocation error, layout = {:?}", layout);
}
