1#[cfg(not(feature = "no_std"))]
16mod imp {
17 use std::cell::Cell;
18
19 thread_local! {
20 static USED: Cell<usize> = const { Cell::new(0) };
21 static LIMIT: Cell<usize> = const { Cell::new(usize::MAX) };
22 }
23
24 pub fn init(limit: usize) {
25 USED.set(0);
26 LIMIT.set(limit);
27 }
28
29 pub fn alloc(bytes: usize) {
30 USED.with(|u| u.set(u.get().saturating_add(bytes)));
31 }
32
33 pub fn dealloc(bytes: usize) {
34 USED.with(|u| u.set(u.get().saturating_sub(bytes)));
35 }
36
37 pub fn exceeded() -> bool {
38 USED.with(|u| LIMIT.with(|l| u.get() > l.get()))
39 }
40
41 pub fn would_exceed(bytes: usize) -> bool {
42 USED.with(|u| LIMIT.with(|l| u.get().saturating_add(bytes) > l.get()))
43 }
44}
45
46#[cfg(feature = "no_std")]
49mod imp {
50 use core::cell::Cell;
51
52 struct SyncCell(Cell<usize>);
55 unsafe impl Sync for SyncCell {}
56
57 static USED: SyncCell = SyncCell(Cell::new(0));
58 static LIMIT: SyncCell = SyncCell(Cell::new(usize::MAX));
59
60 pub fn init(limit: usize) {
61 USED.0.set(0);
62 LIMIT.0.set(limit);
63 }
64
65 pub fn alloc(bytes: usize) {
66 USED.0.set(USED.0.get().saturating_add(bytes));
67 }
68
69 pub fn dealloc(bytes: usize) {
70 USED.0.set(USED.0.get().saturating_sub(bytes));
71 }
72
73 pub fn exceeded() -> bool {
74 USED.0.get() > LIMIT.0.get()
75 }
76
77 pub fn would_exceed(bytes: usize) -> bool {
78 USED.0.get().saturating_add(bytes) > LIMIT.0.get()
79 }
80}
81
82pub fn bop_memory_init(limit: usize) {
86 imp::init(limit);
87}
88
89pub fn bop_alloc(bytes: usize) {
92 imp::alloc(bytes);
93}
94
95pub fn bop_dealloc(bytes: usize) {
97 imp::dealloc(bytes);
98}
99
100pub fn bop_memory_exceeded() -> bool {
103 imp::exceeded()
104}
105
106pub fn bop_would_exceed(bytes: usize) -> bool {
110 imp::would_exceed(bytes)
111}