QU_alloc_mem(), QU_alloc_init_mem(), QU_free_mem()

Synopsis

     char *QU_alloc_mem(size, alignment, actualsize)
     unsigned int  size;
     unsigned int  alignment;
     unsigned int *actualsize;
     

The primitive function that Prolog calls to get memory

     char *QU_alloc_init_mem(size, alignment, actualsize)
     unsigned int  size;
     unsigned int  alignment;
     unsigned int *actualsize;
     

Called when Prolog needs memory for the first time

     int QU_free_mem(mem, size)
     char          *mem;
     unsigned int  size;
     

The primitive function called when Prolog wants to free memory.

Description

These are the primitive functions on which the all of Prolog's sophisticated memory management is built. If Prolog is to be embedded into an application that would like to provide its own memory management routines then the user can redefine these functions and link it with the Prolog system.

QU_alloc_mem() must allocate a piece of memory that has at least size bytes aligned at alignment in it and return a pointer to it. The memory returned itself need not be aligned at alignment. The alignment argument is guaranteed to be a power of 2. The actual size of the piece of memory returned should be stored in *actualsize. Prolog uses all the memory given to it; there is no memory wasted when actualsize is greater than size. QU_alloc_mem() should return 0 if it cannot allocate any more memory.

QU_alloc_init_mem() is a special case of QU_alloc_mem(). It can do whatever initialization that this layer of memory management wants to do.

QU_free_mem() is called with a pointer to the memory that is to be freed and the size of the memory to be freed. If QU_free_mem() was not able to free this piece of memory then this function should return 0. In this case Prolog will continue using the memory as if it was not freed.

The default definitions for these functions look at the environment variables PROLOGINITSIZE, PROLOGINCSIZE, PROLOGKEEPSIZE and PROLOGMAXSIZE. These environment variables are useful to customize the default memory manager. If users redefine this layer of memory management they can choose to ignore these environment variables.

Examples

Here is a simple example of the embeddable layer of memory management based on malloc(3) and free(3). This example is far from ideal because you might be over-allocating memory to ensure the required size of aligned memory, but demonstrates the capability. The C file mem.c defines QU_alloc_mem(), QU_alloc_init_mem() and QU_free_mem().

                                      
mem.c
unsigned int IncSize = 0x100000; /* 1M */ unsigned int InitSize = 0x100000; /* 1M */ unsigned int MaxSize = 0x1000000; /* 16 M */ unsigned int KeepSize = 0x100000; /* 1M */ unsigned int MemTotal; char * QU_alloc_mem(size, align, actualsize) unsigned int size; /* in bytes */ unsigned int align; /* power of 2 */ unsigned int *actualsize; { char *mem, *malloc(); size = size + align; if (size <= IncSize) size = IncSize; if ((size + MemTotal) > MaxSize) return 0; mem = malloc(size); *actualsize = size; MemTotal += (mem == 0 ? 0 : size); return mem; } char * QU_alloc_init_mem(size, align, actualsize) unsigned int size; /* in bytes */ unsigned int align; /* power of 2 */ unsigned int *actualsize; { char *mem, *str, *malloc(), *getenv(); str = getenv("PROLOGINCSIZE"); if (str) sscanf(str, "%u", &IncSize); str = getenv("PROLOGINITSIZE"); if (str) sscanf(str, "%u", &InitSize); str = getenv("PROLOGMAXSIZE"); if (str) sscanf(str, "%u", &MaxSize); str = getenv("PROLOGKEEPSIZE"); if (str) sscanf(str, "%u", &KeepSize); MemTotal = 0; return QU_alloc_mem(size, align, actualsize); } int QU_free_mem(mem, size) char * mem; unsigned int size; { if ((MemTotal - size) < KeepSize) return 0; free(mem); MemTotal = MemTotal - size; return 1; }

To build a Prolog development system based on the functions defined in mem.c:

     % cc -c mem.c
     % qld -D mem.o -o prolog_on_my_mm_fns
     

See Also

fli-emb