#[cfg(not(feature = "no_std"))]
mod imp {
use std::cell::Cell;
thread_local! {
static USED: Cell<usize> = const { Cell::new(0) };
static LIMIT: Cell<usize> = const { Cell::new(usize::MAX) };
}
pub fn init(limit: usize) {
USED.set(0);
LIMIT.set(limit);
}
pub fn alloc(bytes: usize) {
USED.with(|u| u.set(u.get().saturating_add(bytes)));
}
pub fn dealloc(bytes: usize) {
USED.with(|u| u.set(u.get().saturating_sub(bytes)));
}
pub fn exceeded() -> bool {
USED.with(|u| LIMIT.with(|l| u.get() > l.get()))
}
pub fn would_exceed(bytes: usize) -> bool {
USED.with(|u| LIMIT.with(|l| u.get().saturating_add(bytes) > l.get()))
}
}
#[cfg(feature = "no_std")]
mod imp {
use core::cell::Cell;
struct SyncCell(Cell<usize>);
unsafe impl Sync for SyncCell {}
static USED: SyncCell = SyncCell(Cell::new(0));
static LIMIT: SyncCell = SyncCell(Cell::new(usize::MAX));
pub fn init(limit: usize) {
USED.0.set(0);
LIMIT.0.set(limit);
}
pub fn alloc(bytes: usize) {
USED.0.set(USED.0.get().saturating_add(bytes));
}
pub fn dealloc(bytes: usize) {
USED.0.set(USED.0.get().saturating_sub(bytes));
}
pub fn exceeded() -> bool {
USED.0.get() > LIMIT.0.get()
}
pub fn would_exceed(bytes: usize) -> bool {
USED.0.get().saturating_add(bytes) > LIMIT.0.get()
}
}
pub fn bop_memory_init(limit: usize) {
imp::init(limit);
}
pub fn bop_alloc(bytes: usize) {
imp::alloc(bytes);
}
pub fn bop_dealloc(bytes: usize) {
imp::dealloc(bytes);
}
pub fn bop_memory_exceeded() -> bool {
imp::exceeded()
}
pub fn bop_would_exceed(bytes: usize) -> bool {
imp::would_exceed(bytes)
}