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.