page_alloc.rs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. use super::RawPage;
  2. /// A trait for allocating and deallocating pages of memory.
  3. ///
  4. /// Note that the instances of this trait should provide pointer-like or reference-like
  5. /// behavior, meaning that the allocators are to be passed around by value and stored in
  6. /// managed data structures. This is because the allocator may be used to deallocate the
  7. /// pages it allocates.
  8. pub trait PageAlloc: Clone {
  9. type RawPage: RawPage;
  10. /// Allocate a page of the given *order*.
  11. fn alloc_order(&self, order: u32) -> Option<Self::RawPage>;
  12. /// Allocate exactly one page.
  13. fn alloc(&self) -> Option<Self::RawPage> {
  14. self.alloc_order(0)
  15. }
  16. /// Allocate a contiguous block of pages that can contain at least `count` pages.
  17. fn alloc_at_least(&self, count: usize) -> Option<Self::RawPage> {
  18. let order = count.next_power_of_two().trailing_zeros();
  19. self.alloc_order(order)
  20. }
  21. /// Deallocate a page.
  22. ///
  23. /// # Safety
  24. /// This function is unsafe because it assumes that the caller MUST ensure that
  25. /// `raw_page` is allocated in this allocator and never used after this call.
  26. unsafe fn dealloc(&self, raw_page: Self::RawPage);
  27. /// Check whether the page is allocated and managed by the allocator.
  28. fn has_management_over(&self, page_ptr: Self::RawPage) -> bool;
  29. }
  30. /// A trait for global page allocators.
  31. ///
  32. /// Global means that we can get an instance of the allocator from anywhere in the kernel.
  33. pub trait GlobalPageAlloc: PageAlloc + 'static {
  34. /// Get the global page allocator.
  35. fn global() -> Self;
  36. }
  37. impl<'a, A> PageAlloc for &'a A
  38. where
  39. A: PageAlloc,
  40. {
  41. type RawPage = A::RawPage;
  42. fn alloc_order(&self, order: u32) -> Option<Self::RawPage> {
  43. (*self).alloc_order(order)
  44. }
  45. unsafe fn dealloc(&self, raw_page: Self::RawPage) {
  46. unsafe { (*self).dealloc(raw_page) }
  47. }
  48. fn has_management_over(&self, raw_page: Self::RawPage) -> bool {
  49. (*self).has_management_over(raw_page)
  50. }
  51. }