solana-allocator 0.1.0

A global allocator for Solana programs supporting ≥32 KiB heap sizes and mutable global state.
Documentation
# solana-allocator

A custom Solana allocator with the following features:

- Supports heaps of arbitrary size.  Default Solana allocator assumes 32 KiB of
  available space regardless of heap size configured via the
  `ComputeBudgetInstruction`.  This allocator will use all the allotted space.

- Supports opportunistic freeing and resizing.  The default Solana allocator
  never frees memory and calling `msg!` in a loop will eventually exhaust all
  memory.  This allocator frees at least the last allocated object addressing
  simple case of temporary buffers.

- Allows declaring mutable global variables which is something Solana Virtual
  Machine doesn’t normally support.  (Any program with mutable static variable
  will fail to deploy).  This allocator offers a way to define such state.

## Usage

The crate provides `custom_heap` and `custom_global` macros which make use of
the allocator relatively straightforward.  Note however, that
`solana_program::entrypoint` and `anchor::program` macros define global
allocator of their own unless `custom-heap` Cargo feature is enabled.

### Simple usage

For a simple usage (without support for mutable static variables), add the
dependency and use `custom_heap` macro.  First in `Cargo.toml`:

```toml
[dependencies.solana-allocator]
name = "solana-allocator"
version = "0.1"
optional = true

[features]
default = ["custom-heap"]
custom-heap = ["dep:solana-allocator"]
```

And than in `lib.rs`:

```rust
#[cfg(feature = "custom-heap")]
solana_allocator::custom_heap();
```

### Usage with mutable global variables

For usage with the mutable global variables, additional `bytemuck` dependency
must be added and `custom_global` macro used instead.  First in `Cargo.toml`:

```toml
[dependencies.bytemuck]
version = "*"
optional = true

[dependencies.solana-allocator]
name = "solana-allocator"
version = "0.1"
optional = true

[features]
default = ["custom-heap"]
custom-heap = ["dep:bytemuck", "dep:solana-allocator"]
```

And then in `lib.rs`, for example:

```rust
solana_allocator::custom_global!(struct GlobalData {
    counter: Cell<usize>,
});

#[cfg(target_os = "solana")]
pub fn unique() -> usize {
    let counter = &global().counter;
    let value = counter.get();
    counter.set(value + 1);
    value
}

#[cfg(not(target_os = "solana"))]
pub fn unique() -> usize {
    use std::sync::atomic::{AtomicUsize, Ordering};
    static COUNTER: AtomicUsize = AtomicUsize::new(0);
    COUNTER.fetch_add(1, Ordering::SeqCst)
}
```

See documentation or [Mutable global state in
Solana](https://mina86.com/2025/solana-mutable-global-state/) article for more
detailed description.