Updated raylib memory pool (markdown)

master
Kevin Yonan 3 years ago
parent
commit
8821b40241
1 changed files with 82 additions and 2 deletions
  1. +82
    -2
      raylib-memory-pool.md

+ 82
- 2
raylib-memory-pool.md

@ -67,7 +67,7 @@ When we finish using the pool's memory, we clean it up by using `MemPool_Destroy
```c
MemPool_Destroy(&pool);
```
Alternatively, if you're not in a position to use any kind of dynamic allocation from the operating system, you have the option to utilize an existing buffer as memory for the mempool:
```c
char mem[64000];
@ -79,7 +79,7 @@ To allocate from the pool, we have two functions:
void *MemPool_Alloc(MemPool *mempool, size_t bytes);
void *MemPool_Realloc(MemPool *mempool, void *ptr, size_t bytes);
```
`MemPool_Alloc` returns a (zeroed) pointer to a memory block.
```c
// allocate an int pointer.
@ -242,3 +242,83 @@ Which of course is equivalent to:
```c
ObjPool_Free(&vector_pool, origin), origin = NULL;
```
# Double-Ended aka Bi(furcated) Stack
By Kevin 'Assyrianic' Yonan @ https://github.com/assyrianic
**About**:
The raylib BiStack is a fast & efficient bifurcated stack "bi-stack" allocator.
**Purpose**:
raylib BiStack's purpose is the following list:
* A quick, efficient way of allocating temporary, dynamically-sizeable memory during various operations.
* Bifurcated to allow certain temporary data to have a different lifetime from other, temporary data.
**Data Implementation**:
The bifurcated stack encapsulates one public struct:
* `mem` which is an unsigned integer large enough to represent a pointer; the pointer value it holds is the memory address of the backing buffer.
* `front` holds a pointer value representing the first aka _front_ portion of the bifurcated stack.
* `back` holds a pointer value representing the second aka _back_ portion of the bifurcated stack.
* and a `size` that holds the amount of bytes of the backing buffer.
```c
typedef struct BiStack {
uintptr_t mem, front, back;
size_t size;
} BiStack;
```
**Usage**:
The bi-stack is designed to be used as a direct object.
There are two constructor functions:
```c
BiStack CreateBiStack(size_t len);
BiStack CreateBiStackFromBuffer(void *buf, size_t len);
```
To which you create a `BiStack` instance and give the function a max amount of memory you wish or require for your data.
Remember not to exceed that memory amount or the allocation functions of the allocator will give you a NULL pointer.
So we create a bistack that will malloc an internal buffer of 10K bytes.
```c
BiStack bistack = CreateBiStack(10000);
```
When the bi-stack is no longer needed, we clean it up by using `DestroyBiStack`.
```c
DestroyBiStack(&bistack);
```
Alternatively, if you're not in a position to use any kind of dynamic allocation from the operating system, you have the option to utilize an existing buffer as memory for the bistack:
```c
char mem[64000];
BiStack pool = CreateBiStackFromBuffer(mem, sizeof mem);
```
To allocate from the bistack, we have two functions:
```c
void *BiStackAllocFront(BiStack *destack, size_t len);
void *BiStackAllocBack(BiStack *destack, size_t len);
```
**NOTE**: _The two allocator functions do **NOT** zero memory._
```c
// allocate an int pointer from the front.
int *i = BiStackAllocFront(&bistack, sizeof *i);
// allocate a float pointer from the back.
float *f = BiStackAllocBack(&bistack, sizeof *f);
```
Unlike the other allocators, the Bi-stack does not require you free given pointers back to the allocator. However, you will need to reset the bi-stack in order to "free" the data back to the bi-stack. Here are three functions that resets the bi-stack:
```c
void BiStackResetFront(BiStack *destack);
void BiStackResetBack(BiStack *destack);
void BiStackResetAll(BiStack *destack);
```
`BiStackResetFront` will reset allocation data for the front portion of the bi-stack. So ALL pointers given from the front portion can be overwritten if any new pointers allocated also point to those parts. Same deal for `BiStackResetBack` and the back portion of the bi-stack.
If both portions need to be reset, `BiStackResetAll` will do the job.
An important caveat with the bi-stack is that if the back portion or the front portion collide with one another, you will be given a `NULL` pointer. To check if they will collide, `intptr_t BiStackMargins(BiStack destack);` is used to get the difference between how far, in bytes, the back portion is from the front.
The way this works is that, when allocating from the front portion, the `front` member is increased. When allocating the back portion, the `back` member is decreased. If the front portion reaches the back, that means the front portion of the bi-stack is out of memory, same deal for the back portion if it reaches the front. Thus, `BiStackMargins` provides you the difference between these two portions; a number of 0 or less means that one of the portions has reached the other and a reset is necessary.

Loading…
Cancel
Save