diff --git a/.vscode/settings.json b/.vscode/settings.json index 25cd09f0..a1bc6241 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,6 +19,8 @@ "immintrin.h": "c", "stdint.h": "c", "electrosphere_server_fluid_manager_serverfluidchunk.h": "c", - "stdio.h": "c" + "stdio.h": "c", + "cstdlib": "c", + "pool.h": "c" } } \ No newline at end of file diff --git a/buildNumber.properties b/buildNumber.properties index ddb10881..17ea0259 100644 --- a/buildNumber.properties +++ b/buildNumber.properties @@ -1,3 +1,3 @@ #maven.buildNumber.plugin properties file -#Sun Dec 01 15:59:03 EST 2024 -buildNumber=475 +#Sun Dec 01 16:31:44 EST 2024 +buildNumber=477 diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 8a347d88..b6f9c385 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1210,6 +1210,7 @@ Fix GriddedDataCellManager memory leak caused by physics and ConcurrentHashMap Fix fluid sim null pointer bug with unallocated chunks Fix fluid sim NP bug with skipped chunks Fix fluid chunk indexing from java side +Memory pooling for chunk buffer allocations diff --git a/src/fluid/compile.sh b/src/fluid/compile.sh index a4bbb593..f6b906c9 100644 --- a/src/fluid/compile.sh +++ b/src/fluid/compile.sh @@ -78,12 +78,17 @@ INPUT_FILES="./src/mem/fluidmem.c" OUTPUT_FILE="./fluidmem.o" gcc $COMPILE_FLAGS -I"$BASE_INCLUDE_DIR" -I"$OS_INCLUDE_DIR" $INPUT_FILES -o $OUTPUT_FILE +COMPILE_FLAGS="-c -fPIC -m64 -mavx -mavx2 -march=native -Ofast -DSAVE_STEPS=$SAVE_STEPS" +INPUT_FILES="./src/mem/pool.c" +OUTPUT_FILE="./pool.o" +gcc $COMPILE_FLAGS -I"$BASE_INCLUDE_DIR" -I"$OS_INCLUDE_DIR" $INPUT_FILES -o $OUTPUT_FILE + #compile shared object file OUTPUT_FILE="libfluidsim$LIB_ENDING" COMPILE_FLAGS="-shared" -INPUT_FILES="fluidsim.o javainterface.o metadatacalc.o fluidmem.o" +INPUT_FILES="fluidsim.o javainterface.o metadatacalc.o fluidmem.o pool.o" gcc $COMPILE_FLAGS $INPUT_FILES -o $OUTPUT_FILE #move to resources diff --git a/src/fluid/includes/mem/pool.h b/src/fluid/includes/mem/pool.h new file mode 100644 index 00000000..c0d3b2f3 --- /dev/null +++ b/src/fluid/includes/mem/pool.h @@ -0,0 +1,58 @@ +#ifndef POOL_H +#define POOL_H + +/** + * A pool of memory blocks + */ +typedef struct pool { + /** + * The current number of utilized blocks within the pool + */ + int posCurr; + + /** + * The maximum number of blocks currently stored in the pool + */ + int posMax; + + /** + * The size of a block within the pool + */ + int blockSize; + + /** + * The table of blocks itself + */ + void ** table; + + +} POOL; + +/** + * Creates a memory pool + * @param blockSize The size of a block within the pool + * @return The pool + */ +POOL * pool_create(int blockSize); + +/** + * Gets a block from the pool + * @param pool The pool to pull from + * @return The block of memory + */ +void * pool_get(POOL * pool); + +/** + * Destroys the pool + * @param p The pool to destroy + */ +void pool_destroy(POOL * p); + +/** + * Returns the block at index + * @param pool The pool to return memory to + * @param block The block to return + */ +void pool_return(POOL * pool, void * block); + +#endif \ No newline at end of file diff --git a/src/fluid/src/mem/fluidmem.c b/src/fluid/src/mem/fluidmem.c index 3285f12b..2099d92c 100644 --- a/src/fluid/src/mem/fluidmem.c +++ b/src/fluid/src/mem/fluidmem.c @@ -4,6 +4,8 @@ #include "../../../main/c/includes/electrosphere_server_fluid_manager_ServerFluidChunk.h" #include "../../../main/c/includes/electrosphere_client_fluid_cache_FluidChunkData.h" +#include "../../includes/mem/pool.h" + /** * Size of a single buffer */ @@ -14,6 +16,15 @@ */ #define CENTER_POS 13 +/** + * Pool for the center array blocks + */ +POOL * centerArrPool = NULL; + +/** + * Pool for the field blocks + */ +POOL * fieldPool = NULL; /** * Allocates the center buffer of a buffer array @@ -82,8 +93,11 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_manager_ServerFluidChunk_ * @param arrFieldId The specific field to allocate */ void allocateCenterField(JNIEnv * env, jobject fluidObj, jfieldID arrFieldId){ + if(centerArrPool == NULL){ + centerArrPool = pool_create(BUFF_SIZE); + } //actually allocate - void *buffer = calloc(1,BUFF_SIZE); + void * buffer = pool_get(centerArrPool); if (buffer == NULL) { // Handle allocation failure return; @@ -92,7 +106,7 @@ void allocateCenterField(JNIEnv * env, jobject fluidObj, jfieldID arrFieldId){ jobject byteBuffer = (*env)->NewDirectByteBuffer(env, buffer, BUFF_SIZE); if (byteBuffer == NULL) { // Handle ByteBuffer creation failure - free(buffer); + pool_return(centerArrPool, buffer); return; } @@ -144,7 +158,7 @@ void freeCenterField(JNIEnv * env, jobject fluidObj, jfieldID arrFieldId){ void *buffer = (*env)->GetDirectBufferAddress(env, buff); if (buffer != NULL) { // Free the allocated memory - free(buffer); + pool_return(centerArrPool, buffer); } //null the array element @@ -176,8 +190,11 @@ JNIEXPORT void JNICALL Java_electrosphere_client_fluid_cache_FluidChunkData_allo * @param arrFieldId The specific field to allocate */ void allocateField(JNIEnv * env, jobject fluidObj, jfieldID arrFieldId){ + if(fieldPool == NULL){ + fieldPool = pool_create(BUFF_SIZE); + } //actually allocate - void *buffer = calloc(1,BUFF_SIZE); + void *buffer = pool_get(fieldPool); if (buffer == NULL) { // Handle allocation failure return; @@ -186,7 +203,7 @@ void allocateField(JNIEnv * env, jobject fluidObj, jfieldID arrFieldId){ jobject byteBuffer = (*env)->NewDirectByteBuffer(env, buffer, BUFF_SIZE); if (byteBuffer == NULL) { // Handle ByteBuffer creation failure - free(buffer); + pool_return(fieldPool,buffer); return; } @@ -226,7 +243,7 @@ void freeField(JNIEnv * env, jobject fluidObj, jfieldID arrFieldId){ void *buffer = (*env)->GetDirectBufferAddress(env, buff); if (buffer != NULL) { // Free the allocated memory - free(buffer); + pool_return(fieldPool,buffer); } //null the array element diff --git a/src/fluid/src/mem/pool.c b/src/fluid/src/mem/pool.c new file mode 100644 index 00000000..e6565f3b --- /dev/null +++ b/src/fluid/src/mem/pool.c @@ -0,0 +1,68 @@ +#include + +//Libraries +#include "../../lib/stb/stb_ds.h" + +#include "../../includes/mem/pool.h" + + +/** + * Creates a memory pool + * @param blockSize The size of a block within the pool + * @return The pool + */ +POOL * pool_create(int blockSize){ + POOL * p = (POOL*)malloc(sizeof(POOL) ); + p->table = NULL; + p->blockSize = blockSize; + p->posCurr = 0; + p->posMax = 0; + return p; +} + +/** + * Gets a block from the pool + * @param pool The pool to pull from + * @return The block of memory + */ +void * pool_get(POOL * pool){ + pool->posCurr++; + if(pool->posCurr >= pool->posMax){ + //allocate a new block + void * newBlock = (void *)calloc(1,pool->blockSize); + stbds_arrput(pool->table,newBlock); + pool->posMax++; + } + return pool->table[pool->posCurr - 1]; +} + +/** + * Destroys the pool + * @param p The pool to destroy + */ +void pool_destroy(POOL * p){ + for(int i = 0; i < p->posMax; i++){ + free(p->table[i]); + } + free(p->table); + free(p); +} + +/** + * Returns the block at index + * @param pool The pool to return memory to + * @param block The block to return + */ +void pool_return(POOL * pool, void * block){ + int returnedIndex = 0; + for(int i = 0; i < pool->posCurr; i++){ + if(block == pool->table[i]){ + returnedIndex = i; + break; + } + } + void * returnedBlock = pool->table[returnedIndex]; + pool->table[returnedIndex] = pool->table[pool->posCurr - 1]; + pool->table[pool->posCurr] = returnedBlock; + pool->posCurr--; +} \ No newline at end of file