Skip to main content

Crate buddy_pool

Crate buddy_pool 

Source
Expand description

BuddyPool implements a simple buddy-system allocator. It does not assume that the memory (or resource) being allocated is accessible, and uses only its own data structures for metadata. It thus can be used, for example to allocate I/O memory that is not directly accessible to the CPU. As part of this approach, BuddyPool does not contain any unsafe code, using Vec structures with integers for linking lists. This approach does consume more memory than some other approaches.

§Types

  • BuddyPool
    • This struct is the type for a memory pool.
  • BuddyConfig
    • This struct is used to pass configuration parameters to the pool constructor.
  • BuddyStats
    • The pool implementation keeps some statistics on operations. This struct is used to return them to the user.
  • BuddyError
    • Pool functions use this type to return information on errors.
  • Index
    • The allocator uses this type for indices. Types u8, u16, u32, and usize have been tested. Smaller types will limit the maximum pool size, but save on overhead.

§Example

        use buddy_pool::BuddyPool;
        use buddy_pool::BuddyConfig;
        use buddy_pool::BuddyErrorType;
        use std::alloc::alloc;
        use std::alloc::Layout;

        // Allocate some memory for testing.

        let bytes: usize = 2 * 1024 * 1024;

        let alloc_mem =
            unsafe {
                alloc(Layout::array::<u8>(bytes).unwrap())
            } as usize;

        // Get the configuration parameters ready.

        let config =
            BuddyConfig {
                base:       alloc_mem  ,        // the base address from libc::malloc
                size:       bytes,              // the size of the memory region in bytes
                min_alloc:  1,                  // the minimum allocation size allowed
                max_alloc:  17 * 1024,          // the largest allocation that will be allowed
                min_buddy:  8192,               // the minimum size buddy block that will be created
            };

        // Construct the pool and try an alloc/free pair.

        let mut pool    = BuddyPool::new(config).unwrap();
        let     address = pool.alloc(config.max_alloc).unwrap();

        assert!(address >= config.base && address < config.base + config.size);

        pool.free(address).unwrap();

        // Try a double free.

        let result = pool.free(address);

        assert!(result.is_err());
        assert!(result.unwrap_err().error_type() == BuddyErrorType::FreeingFreeMemory);

        // Try an undersized allocation.

        let result = pool.alloc(config.min_alloc - 1);

        assert!(result.is_err());
        assert!(result.unwrap_err().error_type() == BuddyErrorType::UndersizeAlloc);

        // Try an oversized allocation.

        let result = pool.alloc(config.max_alloc + 1);

        assert!(result.is_err());
        assert!(result.unwrap_err().error_type() == BuddyErrorType::OversizeAlloc);

        // Now allocate until the pool is empty.  Keep track
        // of the allocation count to see that it matches
        // the configuration.

        let mut allocs = 0;

        loop {
            let result = pool.alloc(config.min_alloc);

            if result.is_err() {
                let error = result.unwrap_err();

                assert!(error.error_type() == BuddyErrorType::OutOfMemory);
                break;
            }

            allocs += 1;
        }

        assert!(allocs == config.size / config.min_buddy);

Structs§

BuddyConfig
Specifies the configuration parameters for a pool.
BuddyError
Contains the error information for failed requests.
BuddyPool
Defines the pool type itself.
BuddyStats
Contains the results of a query for statistics on the pool.
ListStats
Contains the statistics returned by a single list. Currently, the only lists are the free lists.

Enums§

BuddyErrorType
Defines the error codes for all operations.

Functions§

compute_buddy_size
Converts a byte count into a buddy size, if possibe, obeying the limits on buddy sizes given as parameters.

Type Aliases§

Index
This type can be set to u8, u16, u32, or usize, as needed to match the pool size. The size limit of a pool in bytes is usize::MAX / 2 or (Index::MAX + 1) * min_size, whichever is smaller. For example, a min_size parameter of 1024 bytes using u32 indices sets a limit of 4 terabytes per memory pool.