The Embedding Functions for Memory Management

Release 3 of Quintus Prolog makes it possible to run Prolog as an embedded system. In terms of memory management this means that Prolog does not assume full control of the address space or that all its memory is going to be contiguous. This makes it possible to share the same address space between Prolog and other applications. The memory used by Prolog can be interspersed with the memory used by the application into which Prolog is embedded.

With Release 3 all of Prolog's sophisticated memory management can be built on top of a primitive layer, which users can replace with their own functions. Such replacement is only required when the application in which the Prolog code is embedded demands full control of the address space and memory allocation. In general it is not necessary or even advantageous to do this.

The embedding layer of memory management comprises three primitive functions: QU_alloc_init_mem(), QU_alloc_mem() and QU_free_mem(). The system has a default implementation of these functions based on sbrk(2) for UNIX and VirtualAlloc() for Windows. If Prolog is to become part of an embedded package that would like to provide its own memory management routines then the user can redefine these functions and statically link it with the Prolog system. (Static linking is discussed in sap-srs.) If the user does not provide these functions, the API functions (in e.g. libqp.a or libqps.lib) will be used by default.

This layer is responsible for allocating memory to Prolog and freeing memory back to the Operating System. Prolog calls the functions QU_alloc_mem() and QU_free_mem() for these purposes. QU_init_mem() is called the first time Prolog makes a call to allocate memory. If the user redefines these functions the redefinition should meet the specifications for these functions mentioned in the reference pages. An example of defining your own memory management routines is given in the reference page for QU_alloc_mem().

This layer is also responsible for the environment variables PROLOGINCSIZE and PROLOGMAXSIZE, which are available for customizing the default memory management routines. The user can set PROLOGINCSIZE to set the least amount by which Prolog should expand each time. The user can set PROLOGMAXSIZE to limit the maximum memory used by Prolog. See ref-mgc-osi.

The Prolog system top level supplied by Quintus automatically cleans up Prolog memory each time it returns to top level. However, when Prolog is called directly from a foreign function the Quintus top level (or a user-defined equivalent) need not be used. If nothing else is done (such as calling trimcore/0 in the Prolog code), when a Prolog query returns, the memory allocated to Prolog will stay expanded to whatever was required to compute the previous solutions.

In the case where it is more convenient to call a C function than a Prolog built-in, QP_trimcore() is provided to explicitly clean up Prolog memory. It has the same effect as trimcore/0. Like trimcore/0 it should be used judiciously, as overuse can result in unnecessary time being spent in memory expansion and contraction. However, when Prolog is to be dormant for a period, or as much free memory as possible is desired, QP_trimcore() can be quite useful.