Pool
This commit is contained in:
parent
4056473705
commit
86ffa5ef9d
4 changed files with 213 additions and 0 deletions
7
poolsclosed/.clang-format
Normal file
7
poolsclosed/.clang-format
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Language: C
|
||||
BasedOnStyle: LLVM
|
||||
IndentWidth: 4 # Use 4 spaces for indentation
|
||||
TabWidth: 4 # Tab width is also 4 spaces
|
||||
UseTab: Never # Always use spaces instead of tabs
|
||||
ColumnLimit: 80 # Wrap lines after 80 characters
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
126
poolsclosed/pool.c
Normal file
126
poolsclosed/pool.c
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
#include <malloc.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
/* See: https://8dcc.github.io/programming/pool-allocator.html */
|
||||
/* See: https://github.com/8dcc/libpool */
|
||||
|
||||
#define CHUNK_SIZE 64
|
||||
|
||||
typedef union Chunk Chunk;
|
||||
union Chunk {
|
||||
Chunk *next; // When not null, it is used
|
||||
char arr[CHUNK_SIZE];
|
||||
};
|
||||
|
||||
typedef struct LinkedPtr LinkedPtr;
|
||||
struct LinkedPtr {
|
||||
Chunk *ptr;
|
||||
LinkedPtr *next;
|
||||
};
|
||||
|
||||
typedef struct Pool Pool;
|
||||
struct Pool {
|
||||
Chunk *free_chunk; // Pointer to a linked list of free chunks
|
||||
LinkedPtr *array_starts;
|
||||
};
|
||||
|
||||
Pool *pool_new(size_t pool_size) {
|
||||
Pool *pool = malloc(sizeof(Pool));
|
||||
|
||||
if (pool == NULL)
|
||||
return NULL;
|
||||
|
||||
Chunk *arr = pool->free_chunk = malloc(pool_size * sizeof(Chunk));
|
||||
if (arr == NULL) {
|
||||
free(pool);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < pool_size - 1; i++) arr[i].next = &arr[i + 1];
|
||||
arr[pool_size - 1].next = NULL;
|
||||
|
||||
pool->array_starts = malloc(sizeof(LinkedPtr));
|
||||
if (pool->array_starts == NULL) {
|
||||
/* Allocation failed */
|
||||
free(arr);
|
||||
free(pool);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pool->array_starts->next = NULL;
|
||||
pool->array_starts->ptr = arr;
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
void *pool_alloc(Pool *pool) {
|
||||
if (pool == NULL || pool->free_chunk == NULL)
|
||||
return NULL;
|
||||
|
||||
// Pop a new one from the free list
|
||||
Chunk *result = pool->free_chunk;
|
||||
pool->free_chunk = pool->free_chunk->next;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void pool_free(Pool *pool, void *ptr) {
|
||||
if (pool == NULL || ptr == NULL)
|
||||
return;
|
||||
|
||||
// This can be done withuot an intermediate ptr
|
||||
Chunk *freed = ptr;
|
||||
freed->next = pool->free_chunk;
|
||||
pool->free_chunk = freed;
|
||||
}
|
||||
|
||||
void pool_close(Pool *pool) {
|
||||
if (pool == NULL)
|
||||
return;
|
||||
|
||||
LinkedPtr *lptr = pool->array_starts;
|
||||
while (lptr != NULL) {
|
||||
LinkedPtr *next = lptr->next;
|
||||
free(lptr->ptr);
|
||||
free(lptr);
|
||||
lptr = next;
|
||||
}
|
||||
|
||||
free(pool);
|
||||
}
|
||||
|
||||
bool pool_resize(Pool *pool, size_t extra_chunk_num) {
|
||||
if (pool == NULL || extra_chunk_num == 0)
|
||||
return false;
|
||||
|
||||
// Allocate the array of extra chunks that we are trying to add to the pool.
|
||||
Chunk *extra_chunk_arr = malloc(extra_chunk_num * sizeof(Chunk));
|
||||
if (extra_chunk_arr == NULL)
|
||||
return false;
|
||||
|
||||
// Link the new chunks together, just like we did when creating the pool.
|
||||
for (size_t i = 0; i < extra_chunk_num - 1; i++)
|
||||
extra_chunk_arr[i].next = &extra_chunk_arr[i + 1];
|
||||
|
||||
// Prepend the array of extra chunks to the “free chunks” list, just like we
|
||||
// did when freeing chunks.
|
||||
extra_chunk_arr[extra_chunk_num - 1].next = pool->free_chunk;
|
||||
pool->free_chunk = extra_chunk_arr;
|
||||
|
||||
// Allocate a new LinkedPtr structure, and store the start of the new chunk
|
||||
// array in it.
|
||||
LinkedPtr *array_start = malloc(sizeof(LinkedPtr));
|
||||
if (array_start == NULL) {
|
||||
free(extra_chunk_arr);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prepend this new LinkedPtr structure to the linked list of “array
|
||||
// starts”, stored inside the Pool structure.
|
||||
array_start->ptr = extra_chunk_arr;
|
||||
array_start->next = pool->array_starts;
|
||||
pool->array_starts = array_start;
|
||||
|
||||
return true;
|
||||
}
|
||||
47
poolsclosed/simpe_pool.c
Normal file
47
poolsclosed/simpe_pool.c
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
/* See: https://8dcc.github.io/programming/pool-allocator.html */
|
||||
|
||||
#define CHUNK_SIZE 64
|
||||
|
||||
typedef union Chunk Chunk;
|
||||
union Chunk {
|
||||
Chunk *next; // When not null, it is used
|
||||
char arr[CHUNK_SIZE];
|
||||
};
|
||||
|
||||
typedef struct Pool Pool;
|
||||
struct Pool {
|
||||
Chunk *free_chunk; // Pointer to a linked list of free chunks
|
||||
Chunk *chunk_arr;
|
||||
};
|
||||
|
||||
void *pool_alloc(Pool *pool) {
|
||||
if (pool == NULL || pool->free_chunk == NULL)
|
||||
return NULL;
|
||||
|
||||
// Pop a new one from the free list
|
||||
Chunk *result = pool->free_chunk;
|
||||
pool->free_chunk = pool->free_chunk->next;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void pool_free(Pool *pool, void *ptr) {
|
||||
if (pool == NULL || ptr == NULL)
|
||||
return;
|
||||
|
||||
// This can be done withuot an intermediate ptr
|
||||
Chunk *freed = ptr;
|
||||
freed->next = pool->free_chunk;
|
||||
pool->free_chunk = freed;
|
||||
}
|
||||
|
||||
void pool_close(Pool *pool) {
|
||||
if (pool == NULL)
|
||||
return;
|
||||
|
||||
free(pool->chunk_arr);
|
||||
free(pool);
|
||||
}
|
||||
33
poolsclosed/test.lua
Executable file
33
poolsclosed/test.lua
Executable file
|
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/env lua
|
||||
|
||||
local m = {}
|
||||
|
||||
print("Hello")
|
||||
os.execute("echo $SHELL")
|
||||
|
||||
m.abc = {
|
||||
kek = 10,
|
||||
}
|
||||
|
||||
function m:print()
|
||||
print(m.abc.kek)
|
||||
end
|
||||
|
||||
function os.getName()
|
||||
local osname
|
||||
-- ask LuaJIT first
|
||||
if jit then
|
||||
return jit.os
|
||||
end
|
||||
|
||||
-- Unix, Linux variants
|
||||
local fh, _ = assert(io.popen("uname -o 2>/dev/null", "r"))
|
||||
if fh then
|
||||
osname = fh:read()
|
||||
end
|
||||
|
||||
return osname or "Windows"
|
||||
end
|
||||
|
||||
m:print()
|
||||
print(os.getName())
|
||||
Loading…
Add table
Add a link
Reference in a new issue