diff options
author | vitalyisaev <vitalyisaev@ydb.tech> | 2023-11-30 13:26:22 +0300 |
---|---|---|
committer | vitalyisaev <vitalyisaev@ydb.tech> | 2023-11-30 15:44:45 +0300 |
commit | 0a98fece5a9b54f16afeb3a94b3eb3105e9c3962 (patch) | |
tree | 291d72dbd7e9865399f668c84d11ed86fb190bbf /contrib/tools/swig/Source/DOH/memory.c | |
parent | cb2c8d75065e5b3c47094067cb4aa407d4813298 (diff) | |
download | ydb-0a98fece5a9b54f16afeb3a94b3eb3105e9c3962.tar.gz |
YQ Connector:Use docker-compose in integrational tests
Diffstat (limited to 'contrib/tools/swig/Source/DOH/memory.c')
-rw-r--r-- | contrib/tools/swig/Source/DOH/memory.c | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/contrib/tools/swig/Source/DOH/memory.c b/contrib/tools/swig/Source/DOH/memory.c new file mode 100644 index 0000000000..f8081d3aee --- /dev/null +++ b/contrib/tools/swig/Source/DOH/memory.c @@ -0,0 +1,292 @@ +/* ----------------------------------------------------------------------------- + * This file is part of SWIG, which is licensed as a whole under version 3 + * (or any later version) of the GNU General Public License. Some additional + * terms also apply to certain portions of SWIG. The full details of the SWIG + * license and copyrights can be found in the LICENSE and COPYRIGHT files + * included with the SWIG source code as distributed by the SWIG developers + * and at https://www.swig.org/legal.html. + * + * memory.c + * + * This file implements all of DOH's memory management including allocation + * of objects and checking of objects. + * ----------------------------------------------------------------------------- */ + +#include "dohint.h" + +#include <stdio.h> +#include <stdlib.h> + +#ifndef DOH_POOL_SIZE +#define DOH_POOL_SIZE 4194304 +#endif + +/* Checks stale DOH object use - will use a lot more memory as pool memory is not re-used. */ +/* +#define DOH_DEBUG_MEMORY_POOLS +*/ + +static int PoolSize = DOH_POOL_SIZE; + +DOH *DohNone = 0; /* The DOH None object */ + +typedef struct pool { + DohBase *ptr; /* Start of pool */ + int len; /* Length of pool */ + int blen; /* Byte length of pool */ + int current; /* Current position for next allocation */ + char *pbeg; /* Beg of pool */ + char *pend; /* End of pool */ + struct pool *next; /* Next pool */ +} Pool; + +static DohBase *FreeList = 0; /* List of free objects */ +static Pool *Pools = 0; +static int pools_initialized = 0; + +/* ---------------------------------------------------------------------- + * CreatePool() - Create a new memory pool + * ---------------------------------------------------------------------- */ + +static void CreatePool(void) { + Pool *p = 0; + p = (Pool *) DohMalloc(sizeof(Pool)); + p->ptr = (DohBase *) DohCalloc(PoolSize, sizeof(DohBase)); + p->len = PoolSize; + p->blen = PoolSize * sizeof(DohBase); + p->current = 0; + p->pbeg = ((char *) p->ptr); + p->pend = p->pbeg + p->blen; + p->next = Pools; + Pools = p; +} + +/* ---------------------------------------------------------------------- + * InitPools() - Initialize the memory allocator + * ---------------------------------------------------------------------- */ + +static void InitPools(void) { + if (pools_initialized) + return; + CreatePool(); /* Create initial pool */ + pools_initialized = 1; + DohNone = NewVoid(0, 0); /* Create the None object */ + DohIntern(DohNone); +} + +/* ---------------------------------------------------------------------- + * DohCheck() + * + * Returns 1 if an arbitrary pointer is a DOH object. + * ---------------------------------------------------------------------- */ + +int DohCheck(const DOH *ptr) { + Pool *p = Pools; + char *cptr = (char *) ptr; + while (p) { + if ((cptr >= p->pbeg) && (cptr < p->pend)) { +#ifdef DOH_DEBUG_MEMORY_POOLS + DohBase *b = (DohBase *) ptr; + int DOH_object_already_deleted = b->type == 0; + assert(!DOH_object_already_deleted); +#endif + return 1; + } + /* + pptr = (char *) p->ptr; + if ((cptr >= pptr) && (cptr < (pptr+(p->current*sizeof(DohBase))))) return 1; */ + p = p->next; + } + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohIntern() + * ----------------------------------------------------------------------------- */ + +void DohIntern(DOH *obj) { + DohBase *b = (DohBase *) obj; + b->flag_intern = 1; +} + +/* ---------------------------------------------------------------------- + * DohObjMalloc() + * + * Allocate memory for a new object. + * ---------------------------------------------------------------------- */ + +DOH *DohObjMalloc(DohObjInfo *type, void *data) { + DohBase *obj; + if (!pools_initialized) + InitPools(); +#ifndef DOH_DEBUG_MEMORY_POOLS + if (FreeList) { + obj = FreeList; + FreeList = (DohBase *) obj->data; + } else { +#endif + while (Pools->current == Pools->len) { + CreatePool(); + } + obj = Pools->ptr + Pools->current; + ++Pools->current; +#ifndef DOH_DEBUG_MEMORY_POOLS + } +#endif + obj->type = type; + obj->data = data; + obj->meta = 0; + obj->refcount = 1; + obj->flag_intern = 0; + obj->flag_marked = 0; + obj->flag_user = 0; + obj->flag_usermark = 0; + return (DOH *) obj; +} + +/* ---------------------------------------------------------------------- + * DohObjFree() - Free a DOH object + * ---------------------------------------------------------------------- */ + +void DohObjFree(DOH *ptr) { + DohBase *b, *meta; + b = (DohBase *) ptr; + if (b->flag_intern) + return; + meta = (DohBase *) b->meta; + b->data = (void *) FreeList; + b->meta = 0; + b->type = 0; + b->refcount = 0; + FreeList = b; + if (meta) { + Delete(meta); + } +} + +/* ---------------------------------------------------------------------- + * DohMemoryDebug() + * + * Display memory usage statistics + * ---------------------------------------------------------------------- */ + +void DohMemoryDebug(void) { + extern DohObjInfo DohStringType; + extern DohObjInfo DohListType; + extern DohObjInfo DohHashType; + + Pool *p; + int totsize = 0; + int totused = 0; + int totfree = 0; + + int numstring = 0; + int numlist = 0; + int numhash = 0; + + printf("Memory statistics:\n\n"); + printf("Pools:\n"); + + p = Pools; + while (p) { + /* Calculate number of used, free items */ + int i; + int nused = 0, nfree = 0; + for (i = 0; i < p->len; i++) { + if (p->ptr[i].refcount <= 0) + nfree++; + else { + nused++; + if (p->ptr[i].type == &DohStringType) + numstring++; + else if (p->ptr[i].type == &DohListType) + numlist++; + else if (p->ptr[i].type == &DohHashType) + numhash++; + } + } + printf(" Pool %8p: size = %10d. used = %10d. free = %10d\n", (void *) p, p->len, nused, nfree); + totsize += p->len; + totused += nused; + totfree += nfree; + p = p->next; + } + printf("\n Total: size = %10d, used = %10d, free = %10d\n", totsize, totused, totfree); + + printf("\nObject types\n"); + printf(" Strings : %d\n", numstring); + printf(" Lists : %d\n", numlist); + printf(" Hashes : %d\n", numhash); + +#if 0 + p = Pools; + while (p) { + int i; + for (i = 0; i < p->len; i++) { + if (p->ptr[i].refcount > 0) { + if (p->ptr[i].type == &DohStringType) { + Printf(stdout, "%s\n", p->ptr + i); + } + } + } + p = p->next; + } +#endif + +} + +/* Function to call instead of exit(). */ +static void (*doh_exit_handler)(int) = NULL; + +void DohSetExitHandler(void (*new_handler)(int)) { + doh_exit_handler = new_handler; +} + +void DohExit(int status) { + if (doh_exit_handler) { + void (*handler)(int) = doh_exit_handler; + /* Unset the handler to avoid infinite loops if it tries to do something + * which calls DohExit() (e.g. calling Malloc() and that failing). + */ + doh_exit_handler = NULL; + handler(status); + } + doh_internal_exit(status); +} + +static void allocation_failed(size_t n, size_t size) { + /* Report and exit as directly as possible to try to avoid further issues due + * to lack of memory. */ + if (n == 1) { +#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 19901L + fprintf(stderr, "Failed to allocate %zu bytes\n", size); +#else + fprintf(stderr, "Failed to allocate %lu bytes\n", (unsigned long)size); +#endif + } else { +#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 19901L + fprintf(stderr, "Failed to allocate %zu*%zu bytes\n", n, size); +#else + fprintf(stderr, "Failed to allocate %lu*%lu bytes\n", (unsigned long)n, (unsigned long)size); +#endif + } + DohExit(EXIT_FAILURE); +} + +void *DohMalloc(size_t size) { + void *p = doh_internal_malloc(size); + if (!p) allocation_failed(1, size); + return p; +} + +void *DohRealloc(void *ptr, size_t size) { + void *p = doh_internal_realloc(ptr, size); + if (!p) allocation_failed(1, size); + return p; +} + +void *DohCalloc(size_t n, size_t size) { + void *p = doh_internal_calloc(n, size); + if (!p) allocation_failed(n, size); + return p; +} |