pub struct PidAllocator<const ORDER: usize> { /* private fields */ }
Expand description
A thread-safe PID allocator that can allocate and recycle PIDs efficiently.
It encapsulates the allocator’s state within an Arc<SpinMutex<...>>
to allow safe shared access across threads.
This design ensures that PIDs can be allocated and recycled from multiple threads without data races or consistency issues.
The ORDER
generic parameter determines the capacity of the allocator,
with the total number of allocatable PIDs being ORDER * usize::BITS
. This makes
the allocator flexible for various use cases, whether you need a few dozen PIDs or thousands.
§Examples
Creating a new PID Allocator:
use pid_allocator::PidAllocator;
let allocator = PidAllocator::<8>::new(); // Creates an allocator that can manage up to 8 * usize::BITS PIDs.
//Allocating a PID:
if let Some(pid) = allocator.allocate() {
println!("Successfully allocated PID: {}", *pid);
// When the `pid` goes out of scope, it will be automatically recycled.
} else {
println!("Failed to allocate a PID. The allocator might be full.");
}
//Checking if a PID is allocated (using `contains` method):
let pid = allocator.allocate().expect("Failed to allocate PID");
assert!(allocator.contains(*pid), "The PID should be marked as allocated.");
//Recycle a PID by simply dropping it:
{
let pid = allocator.allocate().expect("Failed to allocate PID");
// PID is in use within this scope
}
// PID is automatically recycled here when `pid` goes out of scope
§Note
This allocator is designed to be used in environments where PID recycling is frequent, and thread safety is a concern. Its performance characteristics are optimized for scenarios where both allocation and deallocation (recycling) of PIDs are common operations.
Implementations§
Source§impl<const ORDER: usize> PidAllocator<ORDER>
impl<const ORDER: usize> PidAllocator<ORDER>
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new instance of the PID allocator.
This constructor initializes the PID allocator, setting up its internal
structure to keep track of allocated and available PIDs. The allocator
supports up to ORDER * usize::BITS
unique PIDs, where ORDER
is a
compile-time constant defining the number of layers in the allocator.
§Examples
use pid_allocator::PidAllocator;
let allocator = PidAllocator::<8>::new();
This creates a PID allocator with 8 layers, capable of managing
a total of 8 * usize::BITS
PIDs, which depends on the architecture
(e.g., 256 PIDs for a 32-bit architecture or 512 PIDs for a 64-bit architecture).
Sourcepub fn allocate(&self) -> Option<Pid<ORDER>>
pub fn allocate(&self) -> Option<Pid<ORDER>>
Attempts to allocate a new PID. Returns Some(Pid)
if successful, or None
if all PIDs are currently allocated.
The allocated PID is wrapped in a Pid
object, which will automatically recycle the PID when dropped.
This method locks the internal state, searches for a free PID, marks it as used,
and returns a Pid
instance representing the allocated PID. If no PIDs are available,
it returns None
.
§Returns
Some(Pid<ORDER>)
containing the allocated PID if allocation is successful.None
if all PIDs are already allocated.
§Examples
Successful allocation:
use pid_allocator::PidAllocator;
let allocator = PidAllocator::<8>::new();
if let Some(pid) = allocator.allocate() {
println!("Allocated PID: {}", *pid);
}
Handling failure to allocate a PID:
use pid_allocator::PidAllocator;
let allocator = PidAllocator::<8>::new();
let mut pids = Vec::new();
while let Some(pid) = allocator.allocate() {
pids.push(pid);
}
// At this point, no more PIDs can be allocated.
assert!(allocator.allocate().is_none());
In this example, PIDs are continuously allocated until no more are available,
at which point allocate()
returns None
.
Sourcepub fn contains(&self, number: usize) -> bool
pub fn contains(&self, number: usize) -> bool
Checks whether a given PID is currently allocated.
§Parameters
number
: The PID number to check for allocation.
§Returns
true
if the PID is currently allocated.false
otherwise.
§Example
use pid_allocator::PidAllocator;
let allocator = PidAllocator::<32>::new();
let pid = allocator.allocate().expect("Failed to allocate PID");
assert!(allocator.contains(*pid), "The PID should be marked as allocated.");
§Note
This method performs a read-only operation on the allocator’s state and is thread-safe,
thanks to the internal use of Arc<SpinMutex<...>>
. However, because the state of the allocator
can change in concurrent environments, the returned allocation state might not remain valid
immediately after this method is called.