1use std::{iter, mem::ManuallyDrop, ops::Deref, sync::Mutex};
2
3use crate::Allocator;
4
5pub struct AllocatorPool {
9 allocators: Mutex<Vec<Allocator>>,
10}
11
12impl AllocatorPool {
13 pub fn new(thread_count: usize) -> AllocatorPool {
15 let allocators = iter::repeat_with(Allocator::new).take(thread_count).collect();
16 AllocatorPool { allocators: Mutex::new(allocators) }
17 }
18
19 pub fn get(&self) -> AllocatorGuard<'_> {
27 let allocator = {
28 let mut allocators = self.allocators.lock().unwrap();
29 allocators.pop()
30 };
31 let allocator = allocator.unwrap_or_else(Allocator::new);
32
33 AllocatorGuard { allocator: ManuallyDrop::new(allocator), pool: self }
34 }
35
36 fn add(&self, allocator: Allocator) {
44 let mut allocators = self.allocators.lock().unwrap();
45 allocators.push(allocator);
46 }
47}
48
49pub struct AllocatorGuard<'alloc_pool> {
53 allocator: ManuallyDrop<Allocator>,
54 pool: &'alloc_pool AllocatorPool,
55}
56
57impl Deref for AllocatorGuard<'_> {
58 type Target = Allocator;
59
60 fn deref(&self) -> &Self::Target {
61 &self.allocator
62 }
63}
64
65impl Drop for AllocatorGuard<'_> {
66 fn drop(&mut self) {
68 let mut allocator = unsafe { ManuallyDrop::take(&mut self.allocator) };
70 allocator.reset();
71 self.pool.add(allocator);
72 }
73}