Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
The goal of this Memory Pool is to provide the ability to allocate big chunks of
memory that can fit many Block
s. Some memory allocators out there have a fairly large
minimal size requirement, which would be wasteful if many chunks of small size (eg. 32
bytes) are needed at once. Memory pool will allocate one page at a time as more blocks
is needed.
Currently there is no functionality for releasing unused pages. So, once a page is
allocated, it will be re-used when more Block
s is needed, but it will not be GCed
until the whole Pool
is GCed.
Synopsis
- data Pool n s
- initPool ∷ ∀ n s. KnownNat n ⇒ Int → (∀ a. Int → ST s (ForeignPtr a)) → (Ptr (Block n) → IO ()) → ST s (Pool n s)
- data Block (n ∷ Nat) = Block
- blockByteCount ∷ KnownNat n ⇒ Block n → Int
- grabNextBlock ∷ KnownNat n ⇒ Pool n s → ST s (ForeignPtr (Block n))
- countPages ∷ Pool n s → ST s Int
- findNextZeroIndex ∷ ∀ b. FiniteBits b ⇒ b → Maybe Int
Pool
Thread-safe lock-free memory pool for managing large memory pages that contain of
many small Block
s.
∷ ∀ n s. KnownNat n | |
⇒ Int | Number of groups per page. Must be a posititve number, otherwise error. One group
contains as many blocks as the operating system has bits. A 64bit architecture will
have 64 blocks per group. For example, if program is compiled on a 64 bit OS and you
know ahead of time the maximum number of blocks that will be allocated through out
the program, then the optimal value for this argument will |
→ (∀ a. Int → ST s (ForeignPtr a)) | Mempool page allocator. Some allocated pages might be immediately discarded, therefore number of pages utilized will not necessesarely match the number of times this action will be called. |
→ (Ptr (Block n) → IO ()) | Finalizer to use for each block. It is an IO action because it will be executed by
the Garbage Collector in a separate thread once the |
→ ST s (Pool n s) |
Initilizes the Pool
that can be used for further allocation of
with ForeignPtr
Block
ngrabNextBlock
.
Block
This is just a proxy type that carries information at the type level about the size
of the block in bytes supported by a particular instance of a Pool
. Use
blockByteCount
to get the byte size at the value level.
grabNextBlock ∷ KnownNat n ⇒ Pool n s → ST s (ForeignPtr (Block n)) Source #
Reserve a ForeignPtr
of the blockByteCount
size in the Pool
. There is a default
finalizer attached to the ForeignPtr
that will run Block
pointer finalizer and
release that memory for re-use by other blocks allocated in the future. It is safe to
add more Haskell finalizers with addForeignPtrConcFinalizer
if necessary.
Helpers
countPages ∷ Pool n s → ST s Int Source #
Useful function for testing. Check how many pages have been allocated thus far.
findNextZeroIndex ∷ ∀ b. FiniteBits b ⇒ b → Maybe Int Source #
Helper function that finds an index of the left-most bit that is not set.