Skip to main content

BuddyAllocator

Struct BuddyAllocator 

Source
pub struct BuddyAllocator<const N: usize, O: OligarchyCollection, B: BuddyCollection> { /* private fields */ }
Expand description

伙伴分配器。

Implementations§

Source§

impl<const N: usize, O: OligarchyCollection, B: BuddyCollection> BuddyAllocator<N, O, B>

Source

pub const fn new() -> Self

构造分配器。

Examples found in repository?
examples/bitmap.rs (line 16)
15fn main() {
16    let mut allocator = Allocator::<7>::new();
17    let ptr = NonNull::new(addr_of_mut!(MEMORY).cast::<u8>()).unwrap();
18    let len = size_of::<Page>();
19    allocator.init(3, ptr);
20    unsafe { allocator.transfer(ptr, len) };
21    println!("{allocator:?}");
22    let (_, size) = allocator.allocate_type::<usize>().unwrap();
23    assert_eq!(size, 8);
24    println!("{allocator:?}");
25}
More examples
Hide additional examples
examples/debug.rs (line 7)
6fn main() {
7    let mut allocator = BuddyAllocator::<16, BuddySet, LinkedListBuddy>::new();
8    allocator.init(12, non_null(0x1000));
9    println!();
10    assert!(allocator.allocate_type::<usize>().is_err());
11    println!();
12    unsafe { allocator.transfer(non_null(0x1000), 0x7fff_f000) };
13
14    println!();
15    println!("A {allocator:?}");
16    let (ptr0, size0) = allocator.allocate_type::<[u8; 2048]>().unwrap();
17    println!("B {allocator:?}");
18    let (ptr1, size1) = allocator.allocate_type::<[u8; 4096]>().unwrap();
19    println!("C {allocator:?}");
20    let (ptr2, size2) = allocator.allocate_type::<[u8; 4096 * 3 - 100]>().unwrap();
21    println!("D {allocator:?}");
22
23    assert_eq!(4096, size0);
24    assert_eq!(4096, size1);
25    assert_eq!(4096 * 3, size2);
26
27    println!();
28    println!("{allocator:?}");
29    allocator.deallocate(ptr0, size0);
30    println!("{allocator:?}");
31    allocator.deallocate(ptr1, size1);
32    println!("{allocator:?}");
33    allocator.deallocate(ptr2, size2);
34    println!("{allocator:?}");
35}
examples/bench.rs (line 22)
20fn main() -> Result<(), BuddyError> {
21    // 创建全局分配器
22    let mut allocator = Allocator::<12>::new();
23    // 从本机操作系统获取一块内存给程序
24    let ptr = NonNull::new(addr_of_mut!(MEMORY).cast::<u8>()).unwrap();
25    let len = size_of_val(unsafe { &*addr_of!(MEMORY) });
26    // 使用最小阶数和初始地址初始化程序
27    allocator.init(12, ptr);
28    println!(
29        "MEMORY: {:#x}..{:#x}",
30        ptr.as_ptr() as usize,
31        ptr.as_ptr() as usize + len
32    );
33    // 计时
34    let t = Instant::now();
35    // 将地址空间放入分配器进行分配
36    unsafe { allocator.transfer(ptr, len) };
37    println!("transfer {:?}", t.elapsed());
38
39    assert_eq!(len, allocator.capacity());
40    assert_eq!(len, allocator.free());
41
42    println!(
43        "
44BEFORE
45{allocator:#x?}"
46    );
47
48    // 创建页面大小的指针?
49    let mut blocks = [null_mut::<Page>(); 65536];
50    let layout = Layout::new::<Page>();
51    let t = Instant::now();
52    for block in blocks.iter_mut() {
53        // 将指向对应page大小的地址指定给对应指针(将地址从buddyLine内删除)
54        let (ptr, size) = allocator.allocate_type::<Page>()?;
55        debug_assert_eq!(layout.size(), size);
56        *block = ptr.as_ptr();
57    }
58    let ta = t.elapsed();
59
60    // 由于将等同于分配空间大小的页面全部收回
61    println!(
62        "
63EMPTY
64{allocator:#x?}"
65    );
66
67    // 感觉这个地方应该 有问题, 不应该总容量不变
68    assert_eq!(len, allocator.capacity());
69    assert_eq!(len - blocks.len() * layout.size(), allocator.free());
70
71    let t = Instant::now();
72    for block in blocks.iter_mut() {
73        // 释放指针所指向的空间给分配器进行调配
74        allocator.deallocate(NonNull::new(*block).unwrap(), layout.size());
75        *block = null_mut();
76        // println!("{allocator:#x?}");
77    }
78    let td = t.elapsed();
79
80    assert_eq!(len, allocator.capacity());
81    assert_eq!(len, allocator.free());
82
83    println!(
84        "
85AFTER
86{allocator:#x?}"
87    );
88
89    println!(
90        "allocate   {:?} ({} times)",
91        ta / blocks.len() as u32,
92        blocks.len()
93    );
94    println!(
95        "deallocate {:?} ({} times)",
96        td / blocks.len() as u32,
97        blocks.len()
98    );
99
100    Ok(())
101}
examples/avl.rs (line 24)
22fn main() -> Result<(), BuddyError> {
23    // 创建全局分配器
24    let mut allocator = Allocator::<12>::new();
25    // 从本机操作系统获取一块内存给程序
26    let ptr = NonNull::new(addr_of_mut!(MEMORY).cast::<u8>()).unwrap();
27    let len = size_of_val(unsafe { &*addr_of!(MEMORY) });
28    // 使用最小阶数和初始地址初始化程序
29    allocator.init(12, ptr);
30    println!(
31        "MEMORY: {:#x}..{:#x}",
32        ptr.as_ptr() as usize,
33        ptr.as_ptr() as usize + len
34    );
35    // 计时
36    let t = Instant::now();
37    // 将地址空间放入分配器进行分配【此时生成的结果应该是默认分配情况下的】
38    unsafe { allocator.transfer(ptr, len) };
39    println!("transfer {:?}", t.elapsed());
40
41    assert_eq!(len, allocator.capacity());
42    assert_eq!(len, allocator.free());
43
44    println!(
45        "
46BEFORE
47{allocator:#x?}"
48    );
49
50    // 创建页面大小的指针?
51    let mut blocks = [null_mut::<Page>(); 65536];
52    let layout = Layout::new::<Page>();
53    let t = Instant::now();
54    for block in blocks.iter_mut() {
55        // 将指向对应page大小的地址指定给对应指针(将地址从buddyLine内删除)
56        let (ptr, size) = allocator.allocate_type::<Page>()?;
57        debug_assert_eq!(layout.size(), size);
58        *block = ptr.as_ptr();
59    }
60    // let (ptr, size) = allocator.allocate_type::<Page>()?;
61    // debug_assert_eq!(layout.size(), size);
62    // blocks[i] = ptr.as_ptr();
63    // for i in 0..DIVICE_PIECE {
64    //     // 对于所有的blocks我们便利四次,但是由于LinkedList 和 AVL 都在同等情况下进行测试,因此不会因为循环过多的次数影响到输出的结果
65    //     let mut cnt = 0;
66    //     for j in 0..50 {
67    //         if cnt == i {
68    //             let (ptr, size) = allocator.allocate_type::<Page>()?;
69    //             debug_assert_eq!(layout.size(), size);
70    //             blocks[j] = ptr.as_ptr();
71    //         }
72    //         cnt += 1;
73    //         if cnt == DIVICE_PIECE {
74    //             cnt = 0;
75    //         }
76    //     }
77    // }
78    let ta = t.elapsed();
79
80    // 呈现出全部都被收回的结果
81    println!(
82        "
83EMPTY
84{allocator:#x?}"
85    );
86
87    assert_eq!(len, allocator.capacity());
88    assert_eq!(len - blocks.len() * layout.size(), allocator.free());
89
90    println!("here");
91    let t = Instant::now();
92    // for block in blocks.iter_mut() {
93    //     // 释放指针所指向的空间给分配器进行调配
94    //     allocator.deallocate(NonNull::new(*block).unwrap(), layout.size());
95    //     *block = null_mut();
96    //     // println!("{allocator:#x?}");
97    // }
98    for i in 0..DIVICE_PIECE {
99        let mut cnt = 0;
100        for j in 0..blocks.len() {
101            if cnt == i {
102                allocator.deallocate(NonNull::new(blocks[j]).unwrap(), layout.size());
103                blocks[i] = null_mut();
104            }
105            // println!("{:#x?} , cnt: {cnt:?}, i: {i:?}", blocks[j]);
106            cnt += 1;
107            if cnt == DIVICE_PIECE {
108                cnt = 0;
109            }
110        }
111        println!("{allocator:#x?}");
112    }
113    let td = t.elapsed();
114
115    assert_eq!(len, allocator.capacity());
116    assert_eq!(len, allocator.free());
117
118    println!(
119        "
120AFTER
121{allocator:#x?}"
122    );
123
124    println!(
125        "allocate   {:?} ({} times)",
126        ta / blocks.len() as u32,
127        blocks.len()
128    );
129    println!(
130        "deallocate {:?} ({} times)",
131        td / blocks.len() as u32,
132        blocks.len()
133    );
134
135    Ok(())
136}
Source§

impl<const N: usize, O: OligarchyCollection, B: BuddyCollection> BuddyAllocator<N, O, B>

Source

pub fn capacity(&self) -> usize

返回分配器管理的总容量。

Examples found in repository?
examples/bench.rs (line 39)
20fn main() -> Result<(), BuddyError> {
21    // 创建全局分配器
22    let mut allocator = Allocator::<12>::new();
23    // 从本机操作系统获取一块内存给程序
24    let ptr = NonNull::new(addr_of_mut!(MEMORY).cast::<u8>()).unwrap();
25    let len = size_of_val(unsafe { &*addr_of!(MEMORY) });
26    // 使用最小阶数和初始地址初始化程序
27    allocator.init(12, ptr);
28    println!(
29        "MEMORY: {:#x}..{:#x}",
30        ptr.as_ptr() as usize,
31        ptr.as_ptr() as usize + len
32    );
33    // 计时
34    let t = Instant::now();
35    // 将地址空间放入分配器进行分配
36    unsafe { allocator.transfer(ptr, len) };
37    println!("transfer {:?}", t.elapsed());
38
39    assert_eq!(len, allocator.capacity());
40    assert_eq!(len, allocator.free());
41
42    println!(
43        "
44BEFORE
45{allocator:#x?}"
46    );
47
48    // 创建页面大小的指针?
49    let mut blocks = [null_mut::<Page>(); 65536];
50    let layout = Layout::new::<Page>();
51    let t = Instant::now();
52    for block in blocks.iter_mut() {
53        // 将指向对应page大小的地址指定给对应指针(将地址从buddyLine内删除)
54        let (ptr, size) = allocator.allocate_type::<Page>()?;
55        debug_assert_eq!(layout.size(), size);
56        *block = ptr.as_ptr();
57    }
58    let ta = t.elapsed();
59
60    // 由于将等同于分配空间大小的页面全部收回
61    println!(
62        "
63EMPTY
64{allocator:#x?}"
65    );
66
67    // 感觉这个地方应该 有问题, 不应该总容量不变
68    assert_eq!(len, allocator.capacity());
69    assert_eq!(len - blocks.len() * layout.size(), allocator.free());
70
71    let t = Instant::now();
72    for block in blocks.iter_mut() {
73        // 释放指针所指向的空间给分配器进行调配
74        allocator.deallocate(NonNull::new(*block).unwrap(), layout.size());
75        *block = null_mut();
76        // println!("{allocator:#x?}");
77    }
78    let td = t.elapsed();
79
80    assert_eq!(len, allocator.capacity());
81    assert_eq!(len, allocator.free());
82
83    println!(
84        "
85AFTER
86{allocator:#x?}"
87    );
88
89    println!(
90        "allocate   {:?} ({} times)",
91        ta / blocks.len() as u32,
92        blocks.len()
93    );
94    println!(
95        "deallocate {:?} ({} times)",
96        td / blocks.len() as u32,
97        blocks.len()
98    );
99
100    Ok(())
101}
More examples
Hide additional examples
examples/avl.rs (line 41)
22fn main() -> Result<(), BuddyError> {
23    // 创建全局分配器
24    let mut allocator = Allocator::<12>::new();
25    // 从本机操作系统获取一块内存给程序
26    let ptr = NonNull::new(addr_of_mut!(MEMORY).cast::<u8>()).unwrap();
27    let len = size_of_val(unsafe { &*addr_of!(MEMORY) });
28    // 使用最小阶数和初始地址初始化程序
29    allocator.init(12, ptr);
30    println!(
31        "MEMORY: {:#x}..{:#x}",
32        ptr.as_ptr() as usize,
33        ptr.as_ptr() as usize + len
34    );
35    // 计时
36    let t = Instant::now();
37    // 将地址空间放入分配器进行分配【此时生成的结果应该是默认分配情况下的】
38    unsafe { allocator.transfer(ptr, len) };
39    println!("transfer {:?}", t.elapsed());
40
41    assert_eq!(len, allocator.capacity());
42    assert_eq!(len, allocator.free());
43
44    println!(
45        "
46BEFORE
47{allocator:#x?}"
48    );
49
50    // 创建页面大小的指针?
51    let mut blocks = [null_mut::<Page>(); 65536];
52    let layout = Layout::new::<Page>();
53    let t = Instant::now();
54    for block in blocks.iter_mut() {
55        // 将指向对应page大小的地址指定给对应指针(将地址从buddyLine内删除)
56        let (ptr, size) = allocator.allocate_type::<Page>()?;
57        debug_assert_eq!(layout.size(), size);
58        *block = ptr.as_ptr();
59    }
60    // let (ptr, size) = allocator.allocate_type::<Page>()?;
61    // debug_assert_eq!(layout.size(), size);
62    // blocks[i] = ptr.as_ptr();
63    // for i in 0..DIVICE_PIECE {
64    //     // 对于所有的blocks我们便利四次,但是由于LinkedList 和 AVL 都在同等情况下进行测试,因此不会因为循环过多的次数影响到输出的结果
65    //     let mut cnt = 0;
66    //     for j in 0..50 {
67    //         if cnt == i {
68    //             let (ptr, size) = allocator.allocate_type::<Page>()?;
69    //             debug_assert_eq!(layout.size(), size);
70    //             blocks[j] = ptr.as_ptr();
71    //         }
72    //         cnt += 1;
73    //         if cnt == DIVICE_PIECE {
74    //             cnt = 0;
75    //         }
76    //     }
77    // }
78    let ta = t.elapsed();
79
80    // 呈现出全部都被收回的结果
81    println!(
82        "
83EMPTY
84{allocator:#x?}"
85    );
86
87    assert_eq!(len, allocator.capacity());
88    assert_eq!(len - blocks.len() * layout.size(), allocator.free());
89
90    println!("here");
91    let t = Instant::now();
92    // for block in blocks.iter_mut() {
93    //     // 释放指针所指向的空间给分配器进行调配
94    //     allocator.deallocate(NonNull::new(*block).unwrap(), layout.size());
95    //     *block = null_mut();
96    //     // println!("{allocator:#x?}");
97    // }
98    for i in 0..DIVICE_PIECE {
99        let mut cnt = 0;
100        for j in 0..blocks.len() {
101            if cnt == i {
102                allocator.deallocate(NonNull::new(blocks[j]).unwrap(), layout.size());
103                blocks[i] = null_mut();
104            }
105            // println!("{:#x?} , cnt: {cnt:?}, i: {i:?}", blocks[j]);
106            cnt += 1;
107            if cnt == DIVICE_PIECE {
108                cnt = 0;
109            }
110        }
111        println!("{allocator:#x?}");
112    }
113    let td = t.elapsed();
114
115    assert_eq!(len, allocator.capacity());
116    assert_eq!(len, allocator.free());
117
118    println!(
119        "
120AFTER
121{allocator:#x?}"
122    );
123
124    println!(
125        "allocate   {:?} ({} times)",
126        ta / blocks.len() as u32,
127        blocks.len()
128    );
129    println!(
130        "deallocate {:?} ({} times)",
131        td / blocks.len() as u32,
132        blocks.len()
133    );
134
135    Ok(())
136}
Source

pub fn free(&self) -> usize

返回分配器剩余的空间容量。

Examples found in repository?
examples/bench.rs (line 40)
20fn main() -> Result<(), BuddyError> {
21    // 创建全局分配器
22    let mut allocator = Allocator::<12>::new();
23    // 从本机操作系统获取一块内存给程序
24    let ptr = NonNull::new(addr_of_mut!(MEMORY).cast::<u8>()).unwrap();
25    let len = size_of_val(unsafe { &*addr_of!(MEMORY) });
26    // 使用最小阶数和初始地址初始化程序
27    allocator.init(12, ptr);
28    println!(
29        "MEMORY: {:#x}..{:#x}",
30        ptr.as_ptr() as usize,
31        ptr.as_ptr() as usize + len
32    );
33    // 计时
34    let t = Instant::now();
35    // 将地址空间放入分配器进行分配
36    unsafe { allocator.transfer(ptr, len) };
37    println!("transfer {:?}", t.elapsed());
38
39    assert_eq!(len, allocator.capacity());
40    assert_eq!(len, allocator.free());
41
42    println!(
43        "
44BEFORE
45{allocator:#x?}"
46    );
47
48    // 创建页面大小的指针?
49    let mut blocks = [null_mut::<Page>(); 65536];
50    let layout = Layout::new::<Page>();
51    let t = Instant::now();
52    for block in blocks.iter_mut() {
53        // 将指向对应page大小的地址指定给对应指针(将地址从buddyLine内删除)
54        let (ptr, size) = allocator.allocate_type::<Page>()?;
55        debug_assert_eq!(layout.size(), size);
56        *block = ptr.as_ptr();
57    }
58    let ta = t.elapsed();
59
60    // 由于将等同于分配空间大小的页面全部收回
61    println!(
62        "
63EMPTY
64{allocator:#x?}"
65    );
66
67    // 感觉这个地方应该 有问题, 不应该总容量不变
68    assert_eq!(len, allocator.capacity());
69    assert_eq!(len - blocks.len() * layout.size(), allocator.free());
70
71    let t = Instant::now();
72    for block in blocks.iter_mut() {
73        // 释放指针所指向的空间给分配器进行调配
74        allocator.deallocate(NonNull::new(*block).unwrap(), layout.size());
75        *block = null_mut();
76        // println!("{allocator:#x?}");
77    }
78    let td = t.elapsed();
79
80    assert_eq!(len, allocator.capacity());
81    assert_eq!(len, allocator.free());
82
83    println!(
84        "
85AFTER
86{allocator:#x?}"
87    );
88
89    println!(
90        "allocate   {:?} ({} times)",
91        ta / blocks.len() as u32,
92        blocks.len()
93    );
94    println!(
95        "deallocate {:?} ({} times)",
96        td / blocks.len() as u32,
97        blocks.len()
98    );
99
100    Ok(())
101}
More examples
Hide additional examples
examples/avl.rs (line 42)
22fn main() -> Result<(), BuddyError> {
23    // 创建全局分配器
24    let mut allocator = Allocator::<12>::new();
25    // 从本机操作系统获取一块内存给程序
26    let ptr = NonNull::new(addr_of_mut!(MEMORY).cast::<u8>()).unwrap();
27    let len = size_of_val(unsafe { &*addr_of!(MEMORY) });
28    // 使用最小阶数和初始地址初始化程序
29    allocator.init(12, ptr);
30    println!(
31        "MEMORY: {:#x}..{:#x}",
32        ptr.as_ptr() as usize,
33        ptr.as_ptr() as usize + len
34    );
35    // 计时
36    let t = Instant::now();
37    // 将地址空间放入分配器进行分配【此时生成的结果应该是默认分配情况下的】
38    unsafe { allocator.transfer(ptr, len) };
39    println!("transfer {:?}", t.elapsed());
40
41    assert_eq!(len, allocator.capacity());
42    assert_eq!(len, allocator.free());
43
44    println!(
45        "
46BEFORE
47{allocator:#x?}"
48    );
49
50    // 创建页面大小的指针?
51    let mut blocks = [null_mut::<Page>(); 65536];
52    let layout = Layout::new::<Page>();
53    let t = Instant::now();
54    for block in blocks.iter_mut() {
55        // 将指向对应page大小的地址指定给对应指针(将地址从buddyLine内删除)
56        let (ptr, size) = allocator.allocate_type::<Page>()?;
57        debug_assert_eq!(layout.size(), size);
58        *block = ptr.as_ptr();
59    }
60    // let (ptr, size) = allocator.allocate_type::<Page>()?;
61    // debug_assert_eq!(layout.size(), size);
62    // blocks[i] = ptr.as_ptr();
63    // for i in 0..DIVICE_PIECE {
64    //     // 对于所有的blocks我们便利四次,但是由于LinkedList 和 AVL 都在同等情况下进行测试,因此不会因为循环过多的次数影响到输出的结果
65    //     let mut cnt = 0;
66    //     for j in 0..50 {
67    //         if cnt == i {
68    //             let (ptr, size) = allocator.allocate_type::<Page>()?;
69    //             debug_assert_eq!(layout.size(), size);
70    //             blocks[j] = ptr.as_ptr();
71    //         }
72    //         cnt += 1;
73    //         if cnt == DIVICE_PIECE {
74    //             cnt = 0;
75    //         }
76    //     }
77    // }
78    let ta = t.elapsed();
79
80    // 呈现出全部都被收回的结果
81    println!(
82        "
83EMPTY
84{allocator:#x?}"
85    );
86
87    assert_eq!(len, allocator.capacity());
88    assert_eq!(len - blocks.len() * layout.size(), allocator.free());
89
90    println!("here");
91    let t = Instant::now();
92    // for block in blocks.iter_mut() {
93    //     // 释放指针所指向的空间给分配器进行调配
94    //     allocator.deallocate(NonNull::new(*block).unwrap(), layout.size());
95    //     *block = null_mut();
96    //     // println!("{allocator:#x?}");
97    // }
98    for i in 0..DIVICE_PIECE {
99        let mut cnt = 0;
100        for j in 0..blocks.len() {
101            if cnt == i {
102                allocator.deallocate(NonNull::new(blocks[j]).unwrap(), layout.size());
103                blocks[i] = null_mut();
104            }
105            // println!("{:#x?} , cnt: {cnt:?}, i: {i:?}", blocks[j]);
106            cnt += 1;
107            if cnt == DIVICE_PIECE {
108                cnt = 0;
109            }
110        }
111        println!("{allocator:#x?}");
112    }
113    let td = t.elapsed();
114
115    assert_eq!(len, allocator.capacity());
116    assert_eq!(len, allocator.free());
117
118    println!(
119        "
120AFTER
121{allocator:#x?}"
122    );
123
124    println!(
125        "allocate   {:?} ({} times)",
126        ta / blocks.len() as u32,
127        blocks.len()
128    );
129    println!(
130        "deallocate {:?} ({} times)",
131        td / blocks.len() as u32,
132        blocks.len()
133    );
134
135    Ok(())
136}
Source

pub fn init<T>(&mut self, min_order: usize, base: NonNull<T>)

运行时初始化。

设置分配器分配的最小阶数和基址。

Examples found in repository?
examples/bitmap.rs (line 19)
15fn main() {
16    let mut allocator = Allocator::<7>::new();
17    let ptr = NonNull::new(addr_of_mut!(MEMORY).cast::<u8>()).unwrap();
18    let len = size_of::<Page>();
19    allocator.init(3, ptr);
20    unsafe { allocator.transfer(ptr, len) };
21    println!("{allocator:?}");
22    let (_, size) = allocator.allocate_type::<usize>().unwrap();
23    assert_eq!(size, 8);
24    println!("{allocator:?}");
25}
More examples
Hide additional examples
examples/debug.rs (line 8)
6fn main() {
7    let mut allocator = BuddyAllocator::<16, BuddySet, LinkedListBuddy>::new();
8    allocator.init(12, non_null(0x1000));
9    println!();
10    assert!(allocator.allocate_type::<usize>().is_err());
11    println!();
12    unsafe { allocator.transfer(non_null(0x1000), 0x7fff_f000) };
13
14    println!();
15    println!("A {allocator:?}");
16    let (ptr0, size0) = allocator.allocate_type::<[u8; 2048]>().unwrap();
17    println!("B {allocator:?}");
18    let (ptr1, size1) = allocator.allocate_type::<[u8; 4096]>().unwrap();
19    println!("C {allocator:?}");
20    let (ptr2, size2) = allocator.allocate_type::<[u8; 4096 * 3 - 100]>().unwrap();
21    println!("D {allocator:?}");
22
23    assert_eq!(4096, size0);
24    assert_eq!(4096, size1);
25    assert_eq!(4096 * 3, size2);
26
27    println!();
28    println!("{allocator:?}");
29    allocator.deallocate(ptr0, size0);
30    println!("{allocator:?}");
31    allocator.deallocate(ptr1, size1);
32    println!("{allocator:?}");
33    allocator.deallocate(ptr2, size2);
34    println!("{allocator:?}");
35}
examples/bench.rs (line 27)
20fn main() -> Result<(), BuddyError> {
21    // 创建全局分配器
22    let mut allocator = Allocator::<12>::new();
23    // 从本机操作系统获取一块内存给程序
24    let ptr = NonNull::new(addr_of_mut!(MEMORY).cast::<u8>()).unwrap();
25    let len = size_of_val(unsafe { &*addr_of!(MEMORY) });
26    // 使用最小阶数和初始地址初始化程序
27    allocator.init(12, ptr);
28    println!(
29        "MEMORY: {:#x}..{:#x}",
30        ptr.as_ptr() as usize,
31        ptr.as_ptr() as usize + len
32    );
33    // 计时
34    let t = Instant::now();
35    // 将地址空间放入分配器进行分配
36    unsafe { allocator.transfer(ptr, len) };
37    println!("transfer {:?}", t.elapsed());
38
39    assert_eq!(len, allocator.capacity());
40    assert_eq!(len, allocator.free());
41
42    println!(
43        "
44BEFORE
45{allocator:#x?}"
46    );
47
48    // 创建页面大小的指针?
49    let mut blocks = [null_mut::<Page>(); 65536];
50    let layout = Layout::new::<Page>();
51    let t = Instant::now();
52    for block in blocks.iter_mut() {
53        // 将指向对应page大小的地址指定给对应指针(将地址从buddyLine内删除)
54        let (ptr, size) = allocator.allocate_type::<Page>()?;
55        debug_assert_eq!(layout.size(), size);
56        *block = ptr.as_ptr();
57    }
58    let ta = t.elapsed();
59
60    // 由于将等同于分配空间大小的页面全部收回
61    println!(
62        "
63EMPTY
64{allocator:#x?}"
65    );
66
67    // 感觉这个地方应该 有问题, 不应该总容量不变
68    assert_eq!(len, allocator.capacity());
69    assert_eq!(len - blocks.len() * layout.size(), allocator.free());
70
71    let t = Instant::now();
72    for block in blocks.iter_mut() {
73        // 释放指针所指向的空间给分配器进行调配
74        allocator.deallocate(NonNull::new(*block).unwrap(), layout.size());
75        *block = null_mut();
76        // println!("{allocator:#x?}");
77    }
78    let td = t.elapsed();
79
80    assert_eq!(len, allocator.capacity());
81    assert_eq!(len, allocator.free());
82
83    println!(
84        "
85AFTER
86{allocator:#x?}"
87    );
88
89    println!(
90        "allocate   {:?} ({} times)",
91        ta / blocks.len() as u32,
92        blocks.len()
93    );
94    println!(
95        "deallocate {:?} ({} times)",
96        td / blocks.len() as u32,
97        blocks.len()
98    );
99
100    Ok(())
101}
examples/avl.rs (line 29)
22fn main() -> Result<(), BuddyError> {
23    // 创建全局分配器
24    let mut allocator = Allocator::<12>::new();
25    // 从本机操作系统获取一块内存给程序
26    let ptr = NonNull::new(addr_of_mut!(MEMORY).cast::<u8>()).unwrap();
27    let len = size_of_val(unsafe { &*addr_of!(MEMORY) });
28    // 使用最小阶数和初始地址初始化程序
29    allocator.init(12, ptr);
30    println!(
31        "MEMORY: {:#x}..{:#x}",
32        ptr.as_ptr() as usize,
33        ptr.as_ptr() as usize + len
34    );
35    // 计时
36    let t = Instant::now();
37    // 将地址空间放入分配器进行分配【此时生成的结果应该是默认分配情况下的】
38    unsafe { allocator.transfer(ptr, len) };
39    println!("transfer {:?}", t.elapsed());
40
41    assert_eq!(len, allocator.capacity());
42    assert_eq!(len, allocator.free());
43
44    println!(
45        "
46BEFORE
47{allocator:#x?}"
48    );
49
50    // 创建页面大小的指针?
51    let mut blocks = [null_mut::<Page>(); 65536];
52    let layout = Layout::new::<Page>();
53    let t = Instant::now();
54    for block in blocks.iter_mut() {
55        // 将指向对应page大小的地址指定给对应指针(将地址从buddyLine内删除)
56        let (ptr, size) = allocator.allocate_type::<Page>()?;
57        debug_assert_eq!(layout.size(), size);
58        *block = ptr.as_ptr();
59    }
60    // let (ptr, size) = allocator.allocate_type::<Page>()?;
61    // debug_assert_eq!(layout.size(), size);
62    // blocks[i] = ptr.as_ptr();
63    // for i in 0..DIVICE_PIECE {
64    //     // 对于所有的blocks我们便利四次,但是由于LinkedList 和 AVL 都在同等情况下进行测试,因此不会因为循环过多的次数影响到输出的结果
65    //     let mut cnt = 0;
66    //     for j in 0..50 {
67    //         if cnt == i {
68    //             let (ptr, size) = allocator.allocate_type::<Page>()?;
69    //             debug_assert_eq!(layout.size(), size);
70    //             blocks[j] = ptr.as_ptr();
71    //         }
72    //         cnt += 1;
73    //         if cnt == DIVICE_PIECE {
74    //             cnt = 0;
75    //         }
76    //     }
77    // }
78    let ta = t.elapsed();
79
80    // 呈现出全部都被收回的结果
81    println!(
82        "
83EMPTY
84{allocator:#x?}"
85    );
86
87    assert_eq!(len, allocator.capacity());
88    assert_eq!(len - blocks.len() * layout.size(), allocator.free());
89
90    println!("here");
91    let t = Instant::now();
92    // for block in blocks.iter_mut() {
93    //     // 释放指针所指向的空间给分配器进行调配
94    //     allocator.deallocate(NonNull::new(*block).unwrap(), layout.size());
95    //     *block = null_mut();
96    //     // println!("{allocator:#x?}");
97    // }
98    for i in 0..DIVICE_PIECE {
99        let mut cnt = 0;
100        for j in 0..blocks.len() {
101            if cnt == i {
102                allocator.deallocate(NonNull::new(blocks[j]).unwrap(), layout.size());
103                blocks[i] = null_mut();
104            }
105            // println!("{:#x?} , cnt: {cnt:?}, i: {i:?}", blocks[j]);
106            cnt += 1;
107            if cnt == DIVICE_PIECE {
108                cnt = 0;
109            }
110        }
111        println!("{allocator:#x?}");
112    }
113    let td = t.elapsed();
114
115    assert_eq!(len, allocator.capacity());
116    assert_eq!(len, allocator.free());
117
118    println!(
119        "
120AFTER
121{allocator:#x?}"
122    );
123
124    println!(
125        "allocate   {:?} ({} times)",
126        ta / blocks.len() as u32,
127        blocks.len()
128    );
129    println!(
130        "deallocate {:?} ({} times)",
131        td / blocks.len() as u32,
132        blocks.len()
133    );
134
135    Ok(())
136}
Source

pub unsafe fn transfer<T>(&mut self, ptr: NonNull<T>, size: usize)

将一个 ptr 指向的长度为 usize 的内存块转移给分配器。

§Safety

调用者需要保证:

  • 这个内存块没有被其他任何对象引用;
  • 这个内存块和已经托管的内存块不重叠。
Examples found in repository?
examples/bitmap.rs (line 20)
15fn main() {
16    let mut allocator = Allocator::<7>::new();
17    let ptr = NonNull::new(addr_of_mut!(MEMORY).cast::<u8>()).unwrap();
18    let len = size_of::<Page>();
19    allocator.init(3, ptr);
20    unsafe { allocator.transfer(ptr, len) };
21    println!("{allocator:?}");
22    let (_, size) = allocator.allocate_type::<usize>().unwrap();
23    assert_eq!(size, 8);
24    println!("{allocator:?}");
25}
More examples
Hide additional examples
examples/debug.rs (line 12)
6fn main() {
7    let mut allocator = BuddyAllocator::<16, BuddySet, LinkedListBuddy>::new();
8    allocator.init(12, non_null(0x1000));
9    println!();
10    assert!(allocator.allocate_type::<usize>().is_err());
11    println!();
12    unsafe { allocator.transfer(non_null(0x1000), 0x7fff_f000) };
13
14    println!();
15    println!("A {allocator:?}");
16    let (ptr0, size0) = allocator.allocate_type::<[u8; 2048]>().unwrap();
17    println!("B {allocator:?}");
18    let (ptr1, size1) = allocator.allocate_type::<[u8; 4096]>().unwrap();
19    println!("C {allocator:?}");
20    let (ptr2, size2) = allocator.allocate_type::<[u8; 4096 * 3 - 100]>().unwrap();
21    println!("D {allocator:?}");
22
23    assert_eq!(4096, size0);
24    assert_eq!(4096, size1);
25    assert_eq!(4096 * 3, size2);
26
27    println!();
28    println!("{allocator:?}");
29    allocator.deallocate(ptr0, size0);
30    println!("{allocator:?}");
31    allocator.deallocate(ptr1, size1);
32    println!("{allocator:?}");
33    allocator.deallocate(ptr2, size2);
34    println!("{allocator:?}");
35}
examples/bench.rs (line 36)
20fn main() -> Result<(), BuddyError> {
21    // 创建全局分配器
22    let mut allocator = Allocator::<12>::new();
23    // 从本机操作系统获取一块内存给程序
24    let ptr = NonNull::new(addr_of_mut!(MEMORY).cast::<u8>()).unwrap();
25    let len = size_of_val(unsafe { &*addr_of!(MEMORY) });
26    // 使用最小阶数和初始地址初始化程序
27    allocator.init(12, ptr);
28    println!(
29        "MEMORY: {:#x}..{:#x}",
30        ptr.as_ptr() as usize,
31        ptr.as_ptr() as usize + len
32    );
33    // 计时
34    let t = Instant::now();
35    // 将地址空间放入分配器进行分配
36    unsafe { allocator.transfer(ptr, len) };
37    println!("transfer {:?}", t.elapsed());
38
39    assert_eq!(len, allocator.capacity());
40    assert_eq!(len, allocator.free());
41
42    println!(
43        "
44BEFORE
45{allocator:#x?}"
46    );
47
48    // 创建页面大小的指针?
49    let mut blocks = [null_mut::<Page>(); 65536];
50    let layout = Layout::new::<Page>();
51    let t = Instant::now();
52    for block in blocks.iter_mut() {
53        // 将指向对应page大小的地址指定给对应指针(将地址从buddyLine内删除)
54        let (ptr, size) = allocator.allocate_type::<Page>()?;
55        debug_assert_eq!(layout.size(), size);
56        *block = ptr.as_ptr();
57    }
58    let ta = t.elapsed();
59
60    // 由于将等同于分配空间大小的页面全部收回
61    println!(
62        "
63EMPTY
64{allocator:#x?}"
65    );
66
67    // 感觉这个地方应该 有问题, 不应该总容量不变
68    assert_eq!(len, allocator.capacity());
69    assert_eq!(len - blocks.len() * layout.size(), allocator.free());
70
71    let t = Instant::now();
72    for block in blocks.iter_mut() {
73        // 释放指针所指向的空间给分配器进行调配
74        allocator.deallocate(NonNull::new(*block).unwrap(), layout.size());
75        *block = null_mut();
76        // println!("{allocator:#x?}");
77    }
78    let td = t.elapsed();
79
80    assert_eq!(len, allocator.capacity());
81    assert_eq!(len, allocator.free());
82
83    println!(
84        "
85AFTER
86{allocator:#x?}"
87    );
88
89    println!(
90        "allocate   {:?} ({} times)",
91        ta / blocks.len() as u32,
92        blocks.len()
93    );
94    println!(
95        "deallocate {:?} ({} times)",
96        td / blocks.len() as u32,
97        blocks.len()
98    );
99
100    Ok(())
101}
examples/avl.rs (line 38)
22fn main() -> Result<(), BuddyError> {
23    // 创建全局分配器
24    let mut allocator = Allocator::<12>::new();
25    // 从本机操作系统获取一块内存给程序
26    let ptr = NonNull::new(addr_of_mut!(MEMORY).cast::<u8>()).unwrap();
27    let len = size_of_val(unsafe { &*addr_of!(MEMORY) });
28    // 使用最小阶数和初始地址初始化程序
29    allocator.init(12, ptr);
30    println!(
31        "MEMORY: {:#x}..{:#x}",
32        ptr.as_ptr() as usize,
33        ptr.as_ptr() as usize + len
34    );
35    // 计时
36    let t = Instant::now();
37    // 将地址空间放入分配器进行分配【此时生成的结果应该是默认分配情况下的】
38    unsafe { allocator.transfer(ptr, len) };
39    println!("transfer {:?}", t.elapsed());
40
41    assert_eq!(len, allocator.capacity());
42    assert_eq!(len, allocator.free());
43
44    println!(
45        "
46BEFORE
47{allocator:#x?}"
48    );
49
50    // 创建页面大小的指针?
51    let mut blocks = [null_mut::<Page>(); 65536];
52    let layout = Layout::new::<Page>();
53    let t = Instant::now();
54    for block in blocks.iter_mut() {
55        // 将指向对应page大小的地址指定给对应指针(将地址从buddyLine内删除)
56        let (ptr, size) = allocator.allocate_type::<Page>()?;
57        debug_assert_eq!(layout.size(), size);
58        *block = ptr.as_ptr();
59    }
60    // let (ptr, size) = allocator.allocate_type::<Page>()?;
61    // debug_assert_eq!(layout.size(), size);
62    // blocks[i] = ptr.as_ptr();
63    // for i in 0..DIVICE_PIECE {
64    //     // 对于所有的blocks我们便利四次,但是由于LinkedList 和 AVL 都在同等情况下进行测试,因此不会因为循环过多的次数影响到输出的结果
65    //     let mut cnt = 0;
66    //     for j in 0..50 {
67    //         if cnt == i {
68    //             let (ptr, size) = allocator.allocate_type::<Page>()?;
69    //             debug_assert_eq!(layout.size(), size);
70    //             blocks[j] = ptr.as_ptr();
71    //         }
72    //         cnt += 1;
73    //         if cnt == DIVICE_PIECE {
74    //             cnt = 0;
75    //         }
76    //     }
77    // }
78    let ta = t.elapsed();
79
80    // 呈现出全部都被收回的结果
81    println!(
82        "
83EMPTY
84{allocator:#x?}"
85    );
86
87    assert_eq!(len, allocator.capacity());
88    assert_eq!(len - blocks.len() * layout.size(), allocator.free());
89
90    println!("here");
91    let t = Instant::now();
92    // for block in blocks.iter_mut() {
93    //     // 释放指针所指向的空间给分配器进行调配
94    //     allocator.deallocate(NonNull::new(*block).unwrap(), layout.size());
95    //     *block = null_mut();
96    //     // println!("{allocator:#x?}");
97    // }
98    for i in 0..DIVICE_PIECE {
99        let mut cnt = 0;
100        for j in 0..blocks.len() {
101            if cnt == i {
102                allocator.deallocate(NonNull::new(blocks[j]).unwrap(), layout.size());
103                blocks[i] = null_mut();
104            }
105            // println!("{:#x?} , cnt: {cnt:?}, i: {i:?}", blocks[j]);
106            cnt += 1;
107            if cnt == DIVICE_PIECE {
108                cnt = 0;
109            }
110        }
111        println!("{allocator:#x?}");
112    }
113    let td = t.elapsed();
114
115    assert_eq!(len, allocator.capacity());
116    assert_eq!(len, allocator.free());
117
118    println!(
119        "
120AFTER
121{allocator:#x?}"
122    );
123
124    println!(
125        "allocate   {:?} ({} times)",
126        ta / blocks.len() as u32,
127        blocks.len()
128    );
129    println!(
130        "deallocate {:?} ({} times)",
131        td / blocks.len() as u32,
132        blocks.len()
133    );
134
135    Ok(())
136}
Source

pub fn snatch<T>( &mut self, align_order: usize, size: NonZeroUsize, ) -> Result<(NonNull<T>, usize), BuddyError>

从分配器夺走一个对齐到 align_order 阶,长度为 size 的内存块。

Source

pub fn allocate_type<T>(&mut self) -> Result<(NonNull<T>, usize), BuddyError>

分配可容纳 T 对象的内存块。

Examples found in repository?
examples/bitmap.rs (line 22)
15fn main() {
16    let mut allocator = Allocator::<7>::new();
17    let ptr = NonNull::new(addr_of_mut!(MEMORY).cast::<u8>()).unwrap();
18    let len = size_of::<Page>();
19    allocator.init(3, ptr);
20    unsafe { allocator.transfer(ptr, len) };
21    println!("{allocator:?}");
22    let (_, size) = allocator.allocate_type::<usize>().unwrap();
23    assert_eq!(size, 8);
24    println!("{allocator:?}");
25}
More examples
Hide additional examples
examples/debug.rs (line 10)
6fn main() {
7    let mut allocator = BuddyAllocator::<16, BuddySet, LinkedListBuddy>::new();
8    allocator.init(12, non_null(0x1000));
9    println!();
10    assert!(allocator.allocate_type::<usize>().is_err());
11    println!();
12    unsafe { allocator.transfer(non_null(0x1000), 0x7fff_f000) };
13
14    println!();
15    println!("A {allocator:?}");
16    let (ptr0, size0) = allocator.allocate_type::<[u8; 2048]>().unwrap();
17    println!("B {allocator:?}");
18    let (ptr1, size1) = allocator.allocate_type::<[u8; 4096]>().unwrap();
19    println!("C {allocator:?}");
20    let (ptr2, size2) = allocator.allocate_type::<[u8; 4096 * 3 - 100]>().unwrap();
21    println!("D {allocator:?}");
22
23    assert_eq!(4096, size0);
24    assert_eq!(4096, size1);
25    assert_eq!(4096 * 3, size2);
26
27    println!();
28    println!("{allocator:?}");
29    allocator.deallocate(ptr0, size0);
30    println!("{allocator:?}");
31    allocator.deallocate(ptr1, size1);
32    println!("{allocator:?}");
33    allocator.deallocate(ptr2, size2);
34    println!("{allocator:?}");
35}
examples/bench.rs (line 54)
20fn main() -> Result<(), BuddyError> {
21    // 创建全局分配器
22    let mut allocator = Allocator::<12>::new();
23    // 从本机操作系统获取一块内存给程序
24    let ptr = NonNull::new(addr_of_mut!(MEMORY).cast::<u8>()).unwrap();
25    let len = size_of_val(unsafe { &*addr_of!(MEMORY) });
26    // 使用最小阶数和初始地址初始化程序
27    allocator.init(12, ptr);
28    println!(
29        "MEMORY: {:#x}..{:#x}",
30        ptr.as_ptr() as usize,
31        ptr.as_ptr() as usize + len
32    );
33    // 计时
34    let t = Instant::now();
35    // 将地址空间放入分配器进行分配
36    unsafe { allocator.transfer(ptr, len) };
37    println!("transfer {:?}", t.elapsed());
38
39    assert_eq!(len, allocator.capacity());
40    assert_eq!(len, allocator.free());
41
42    println!(
43        "
44BEFORE
45{allocator:#x?}"
46    );
47
48    // 创建页面大小的指针?
49    let mut blocks = [null_mut::<Page>(); 65536];
50    let layout = Layout::new::<Page>();
51    let t = Instant::now();
52    for block in blocks.iter_mut() {
53        // 将指向对应page大小的地址指定给对应指针(将地址从buddyLine内删除)
54        let (ptr, size) = allocator.allocate_type::<Page>()?;
55        debug_assert_eq!(layout.size(), size);
56        *block = ptr.as_ptr();
57    }
58    let ta = t.elapsed();
59
60    // 由于将等同于分配空间大小的页面全部收回
61    println!(
62        "
63EMPTY
64{allocator:#x?}"
65    );
66
67    // 感觉这个地方应该 有问题, 不应该总容量不变
68    assert_eq!(len, allocator.capacity());
69    assert_eq!(len - blocks.len() * layout.size(), allocator.free());
70
71    let t = Instant::now();
72    for block in blocks.iter_mut() {
73        // 释放指针所指向的空间给分配器进行调配
74        allocator.deallocate(NonNull::new(*block).unwrap(), layout.size());
75        *block = null_mut();
76        // println!("{allocator:#x?}");
77    }
78    let td = t.elapsed();
79
80    assert_eq!(len, allocator.capacity());
81    assert_eq!(len, allocator.free());
82
83    println!(
84        "
85AFTER
86{allocator:#x?}"
87    );
88
89    println!(
90        "allocate   {:?} ({} times)",
91        ta / blocks.len() as u32,
92        blocks.len()
93    );
94    println!(
95        "deallocate {:?} ({} times)",
96        td / blocks.len() as u32,
97        blocks.len()
98    );
99
100    Ok(())
101}
examples/avl.rs (line 56)
22fn main() -> Result<(), BuddyError> {
23    // 创建全局分配器
24    let mut allocator = Allocator::<12>::new();
25    // 从本机操作系统获取一块内存给程序
26    let ptr = NonNull::new(addr_of_mut!(MEMORY).cast::<u8>()).unwrap();
27    let len = size_of_val(unsafe { &*addr_of!(MEMORY) });
28    // 使用最小阶数和初始地址初始化程序
29    allocator.init(12, ptr);
30    println!(
31        "MEMORY: {:#x}..{:#x}",
32        ptr.as_ptr() as usize,
33        ptr.as_ptr() as usize + len
34    );
35    // 计时
36    let t = Instant::now();
37    // 将地址空间放入分配器进行分配【此时生成的结果应该是默认分配情况下的】
38    unsafe { allocator.transfer(ptr, len) };
39    println!("transfer {:?}", t.elapsed());
40
41    assert_eq!(len, allocator.capacity());
42    assert_eq!(len, allocator.free());
43
44    println!(
45        "
46BEFORE
47{allocator:#x?}"
48    );
49
50    // 创建页面大小的指针?
51    let mut blocks = [null_mut::<Page>(); 65536];
52    let layout = Layout::new::<Page>();
53    let t = Instant::now();
54    for block in blocks.iter_mut() {
55        // 将指向对应page大小的地址指定给对应指针(将地址从buddyLine内删除)
56        let (ptr, size) = allocator.allocate_type::<Page>()?;
57        debug_assert_eq!(layout.size(), size);
58        *block = ptr.as_ptr();
59    }
60    // let (ptr, size) = allocator.allocate_type::<Page>()?;
61    // debug_assert_eq!(layout.size(), size);
62    // blocks[i] = ptr.as_ptr();
63    // for i in 0..DIVICE_PIECE {
64    //     // 对于所有的blocks我们便利四次,但是由于LinkedList 和 AVL 都在同等情况下进行测试,因此不会因为循环过多的次数影响到输出的结果
65    //     let mut cnt = 0;
66    //     for j in 0..50 {
67    //         if cnt == i {
68    //             let (ptr, size) = allocator.allocate_type::<Page>()?;
69    //             debug_assert_eq!(layout.size(), size);
70    //             blocks[j] = ptr.as_ptr();
71    //         }
72    //         cnt += 1;
73    //         if cnt == DIVICE_PIECE {
74    //             cnt = 0;
75    //         }
76    //     }
77    // }
78    let ta = t.elapsed();
79
80    // 呈现出全部都被收回的结果
81    println!(
82        "
83EMPTY
84{allocator:#x?}"
85    );
86
87    assert_eq!(len, allocator.capacity());
88    assert_eq!(len - blocks.len() * layout.size(), allocator.free());
89
90    println!("here");
91    let t = Instant::now();
92    // for block in blocks.iter_mut() {
93    //     // 释放指针所指向的空间给分配器进行调配
94    //     allocator.deallocate(NonNull::new(*block).unwrap(), layout.size());
95    //     *block = null_mut();
96    //     // println!("{allocator:#x?}");
97    // }
98    for i in 0..DIVICE_PIECE {
99        let mut cnt = 0;
100        for j in 0..blocks.len() {
101            if cnt == i {
102                allocator.deallocate(NonNull::new(blocks[j]).unwrap(), layout.size());
103                blocks[i] = null_mut();
104            }
105            // println!("{:#x?} , cnt: {cnt:?}, i: {i:?}", blocks[j]);
106            cnt += 1;
107            if cnt == DIVICE_PIECE {
108                cnt = 0;
109            }
110        }
111        println!("{allocator:#x?}");
112    }
113    let td = t.elapsed();
114
115    assert_eq!(len, allocator.capacity());
116    assert_eq!(len, allocator.free());
117
118    println!(
119        "
120AFTER
121{allocator:#x?}"
122    );
123
124    println!(
125        "allocate   {:?} ({} times)",
126        ta / blocks.len() as u32,
127        blocks.len()
128    );
129    println!(
130        "deallocate {:?} ({} times)",
131        td / blocks.len() as u32,
132        blocks.len()
133    );
134
135    Ok(())
136}
Source

pub fn allocate_layout<T>( &mut self, layout: Layout, ) -> Result<(NonNull<T>, usize), BuddyError>

分配符合 layout 布局的内存块。

Source

pub fn allocate<T>( &mut self, align_order: usize, size: NonZeroUsize, ) -> Result<(NonNull<T>, usize), BuddyError>

分配。

如果分配成功,返回一个 (指针, 长度) 二元组。

Source

pub unsafe fn deallocate_layout<T>(&mut self, ptr: NonNull<T>, layout: Layout)

根据布局回收。

§Safety

这个方法认为 ptr 是根据 layout 分配出来的, 因此长度不小于 layout.size() 并且对齐到 self.min_order

Source

pub fn deallocate<T>(&mut self, ptr: NonNull<T>, size: usize)

回收。

§Notice

调用者需要保证 size 对齐了分配器的最小阶数。

Examples found in repository?
examples/debug.rs (line 29)
6fn main() {
7    let mut allocator = BuddyAllocator::<16, BuddySet, LinkedListBuddy>::new();
8    allocator.init(12, non_null(0x1000));
9    println!();
10    assert!(allocator.allocate_type::<usize>().is_err());
11    println!();
12    unsafe { allocator.transfer(non_null(0x1000), 0x7fff_f000) };
13
14    println!();
15    println!("A {allocator:?}");
16    let (ptr0, size0) = allocator.allocate_type::<[u8; 2048]>().unwrap();
17    println!("B {allocator:?}");
18    let (ptr1, size1) = allocator.allocate_type::<[u8; 4096]>().unwrap();
19    println!("C {allocator:?}");
20    let (ptr2, size2) = allocator.allocate_type::<[u8; 4096 * 3 - 100]>().unwrap();
21    println!("D {allocator:?}");
22
23    assert_eq!(4096, size0);
24    assert_eq!(4096, size1);
25    assert_eq!(4096 * 3, size2);
26
27    println!();
28    println!("{allocator:?}");
29    allocator.deallocate(ptr0, size0);
30    println!("{allocator:?}");
31    allocator.deallocate(ptr1, size1);
32    println!("{allocator:?}");
33    allocator.deallocate(ptr2, size2);
34    println!("{allocator:?}");
35}
More examples
Hide additional examples
examples/bench.rs (line 74)
20fn main() -> Result<(), BuddyError> {
21    // 创建全局分配器
22    let mut allocator = Allocator::<12>::new();
23    // 从本机操作系统获取一块内存给程序
24    let ptr = NonNull::new(addr_of_mut!(MEMORY).cast::<u8>()).unwrap();
25    let len = size_of_val(unsafe { &*addr_of!(MEMORY) });
26    // 使用最小阶数和初始地址初始化程序
27    allocator.init(12, ptr);
28    println!(
29        "MEMORY: {:#x}..{:#x}",
30        ptr.as_ptr() as usize,
31        ptr.as_ptr() as usize + len
32    );
33    // 计时
34    let t = Instant::now();
35    // 将地址空间放入分配器进行分配
36    unsafe { allocator.transfer(ptr, len) };
37    println!("transfer {:?}", t.elapsed());
38
39    assert_eq!(len, allocator.capacity());
40    assert_eq!(len, allocator.free());
41
42    println!(
43        "
44BEFORE
45{allocator:#x?}"
46    );
47
48    // 创建页面大小的指针?
49    let mut blocks = [null_mut::<Page>(); 65536];
50    let layout = Layout::new::<Page>();
51    let t = Instant::now();
52    for block in blocks.iter_mut() {
53        // 将指向对应page大小的地址指定给对应指针(将地址从buddyLine内删除)
54        let (ptr, size) = allocator.allocate_type::<Page>()?;
55        debug_assert_eq!(layout.size(), size);
56        *block = ptr.as_ptr();
57    }
58    let ta = t.elapsed();
59
60    // 由于将等同于分配空间大小的页面全部收回
61    println!(
62        "
63EMPTY
64{allocator:#x?}"
65    );
66
67    // 感觉这个地方应该 有问题, 不应该总容量不变
68    assert_eq!(len, allocator.capacity());
69    assert_eq!(len - blocks.len() * layout.size(), allocator.free());
70
71    let t = Instant::now();
72    for block in blocks.iter_mut() {
73        // 释放指针所指向的空间给分配器进行调配
74        allocator.deallocate(NonNull::new(*block).unwrap(), layout.size());
75        *block = null_mut();
76        // println!("{allocator:#x?}");
77    }
78    let td = t.elapsed();
79
80    assert_eq!(len, allocator.capacity());
81    assert_eq!(len, allocator.free());
82
83    println!(
84        "
85AFTER
86{allocator:#x?}"
87    );
88
89    println!(
90        "allocate   {:?} ({} times)",
91        ta / blocks.len() as u32,
92        blocks.len()
93    );
94    println!(
95        "deallocate {:?} ({} times)",
96        td / blocks.len() as u32,
97        blocks.len()
98    );
99
100    Ok(())
101}
examples/avl.rs (line 102)
22fn main() -> Result<(), BuddyError> {
23    // 创建全局分配器
24    let mut allocator = Allocator::<12>::new();
25    // 从本机操作系统获取一块内存给程序
26    let ptr = NonNull::new(addr_of_mut!(MEMORY).cast::<u8>()).unwrap();
27    let len = size_of_val(unsafe { &*addr_of!(MEMORY) });
28    // 使用最小阶数和初始地址初始化程序
29    allocator.init(12, ptr);
30    println!(
31        "MEMORY: {:#x}..{:#x}",
32        ptr.as_ptr() as usize,
33        ptr.as_ptr() as usize + len
34    );
35    // 计时
36    let t = Instant::now();
37    // 将地址空间放入分配器进行分配【此时生成的结果应该是默认分配情况下的】
38    unsafe { allocator.transfer(ptr, len) };
39    println!("transfer {:?}", t.elapsed());
40
41    assert_eq!(len, allocator.capacity());
42    assert_eq!(len, allocator.free());
43
44    println!(
45        "
46BEFORE
47{allocator:#x?}"
48    );
49
50    // 创建页面大小的指针?
51    let mut blocks = [null_mut::<Page>(); 65536];
52    let layout = Layout::new::<Page>();
53    let t = Instant::now();
54    for block in blocks.iter_mut() {
55        // 将指向对应page大小的地址指定给对应指针(将地址从buddyLine内删除)
56        let (ptr, size) = allocator.allocate_type::<Page>()?;
57        debug_assert_eq!(layout.size(), size);
58        *block = ptr.as_ptr();
59    }
60    // let (ptr, size) = allocator.allocate_type::<Page>()?;
61    // debug_assert_eq!(layout.size(), size);
62    // blocks[i] = ptr.as_ptr();
63    // for i in 0..DIVICE_PIECE {
64    //     // 对于所有的blocks我们便利四次,但是由于LinkedList 和 AVL 都在同等情况下进行测试,因此不会因为循环过多的次数影响到输出的结果
65    //     let mut cnt = 0;
66    //     for j in 0..50 {
67    //         if cnt == i {
68    //             let (ptr, size) = allocator.allocate_type::<Page>()?;
69    //             debug_assert_eq!(layout.size(), size);
70    //             blocks[j] = ptr.as_ptr();
71    //         }
72    //         cnt += 1;
73    //         if cnt == DIVICE_PIECE {
74    //             cnt = 0;
75    //         }
76    //     }
77    // }
78    let ta = t.elapsed();
79
80    // 呈现出全部都被收回的结果
81    println!(
82        "
83EMPTY
84{allocator:#x?}"
85    );
86
87    assert_eq!(len, allocator.capacity());
88    assert_eq!(len - blocks.len() * layout.size(), allocator.free());
89
90    println!("here");
91    let t = Instant::now();
92    // for block in blocks.iter_mut() {
93    //     // 释放指针所指向的空间给分配器进行调配
94    //     allocator.deallocate(NonNull::new(*block).unwrap(), layout.size());
95    //     *block = null_mut();
96    //     // println!("{allocator:#x?}");
97    // }
98    for i in 0..DIVICE_PIECE {
99        let mut cnt = 0;
100        for j in 0..blocks.len() {
101            if cnt == i {
102                allocator.deallocate(NonNull::new(blocks[j]).unwrap(), layout.size());
103                blocks[i] = null_mut();
104            }
105            // println!("{:#x?} , cnt: {cnt:?}, i: {i:?}", blocks[j]);
106            cnt += 1;
107            if cnt == DIVICE_PIECE {
108                cnt = 0;
109            }
110        }
111        println!("{allocator:#x?}");
112    }
113    let td = t.elapsed();
114
115    assert_eq!(len, allocator.capacity());
116    assert_eq!(len, allocator.free());
117
118    println!(
119        "
120AFTER
121{allocator:#x?}"
122    );
123
124    println!(
125        "allocate   {:?} ({} times)",
126        ta / blocks.len() as u32,
127        blocks.len()
128    );
129    println!(
130        "deallocate {:?} ({} times)",
131        td / blocks.len() as u32,
132        blocks.len()
133    );
134
135    Ok(())
136}

Trait Implementations§

Source§

impl<const N: usize, O: OligarchyCollection + Debug, B: BuddyCollection + Debug> Debug for BuddyAllocator<N, O, B>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<const N: usize, O: OligarchyCollection, B: BuddyCollection> Default for BuddyAllocator<N, O, B>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<const N: usize, O, B> Freeze for BuddyAllocator<N, O, B>
where O: Freeze, B: Freeze,

§

impl<const N: usize, O, B> RefUnwindSafe for BuddyAllocator<N, O, B>

§

impl<const N: usize, O, B> Send for BuddyAllocator<N, O, B>
where O: Send, B: Send,

§

impl<const N: usize, O, B> Sync for BuddyAllocator<N, O, B>
where O: Sync, B: Sync,

§

impl<const N: usize, O, B> Unpin for BuddyAllocator<N, O, B>
where O: Unpin, B: Unpin,

§

impl<const N: usize, O, B> UnsafeUnpin for BuddyAllocator<N, O, B>
where O: UnsafeUnpin, B: UnsafeUnpin,

§

impl<const N: usize, O, B> UnwindSafe for BuddyAllocator<N, O, B>
where O: UnwindSafe, B: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.