Node:Initializing the Prolog Engine, Next:Loading Prolog Code, Previous:User-defined Main Programs, Up:User-defined Main Programs
The Prolog Engine is initialized by calling SP_initialize()
. This
must be done before any interface functions are called, except
SP_force_interactive
,
SP_set_memalloc_hooks
,
SP_set_wcx_hooks
,
SP_set_user_stream_post_hook
and
SP_set_user_stream_hook
. The function will allocate data areas
used by Prolog, initialize command line arguments so that they can be
accessed by the argv
Prolog flag, and load the Runtime
Library. It is called like this:
int SP_initialize(int argc, char **argv, char *boot_path)
boot_path
should be the name of a directory, equivalent to
$SP_PATH/bin
. If boot_path
is NULL
,
SP_initialize()
will look up the value of the environment
variable SP_PATH
and look for the file
$SP_PATH/bin/sprt.sav
($SP_PATH/bin/spre.sav
)
which contains the (Extended) Runtime Library.
It returns SP_SUCCESS
if initialization was successful, and
SP_ERROR
otherwise. If initialization was successful, further
calls to SP_initialize()
will be no-ops (and return
SP_SUCCESS
).
To unload the SICStus emulator, SP_deinitalize()
can be called.
void SP_deinitialize(void)
SP_deinitialize()
will make a best effort to restore the system
to the state it was in at the time of calling
SP_initialize()
. This involves unloading foreign resources,
shutting down the emulator by
calling halt/0
,
and deallocate
memory used by Prolog. SP_deinitialize()
is idempotent as well,
i.e. it is a no-op unless SICStus has actually been initialized.
You may also call SP_force_interactive()
before calling
SP_initialize()
. This will force the I/O built-in predicates to
treat the standard input stream as a terminal, even if it does not
appear to be a terminal. Same as the -i
option in development
systems. (see Start).
void SP_force_interactive(void)
You may also call SP_set_memalloc_hooks()
before calling
SP_initialize()
. This will define one layer of Prolog's
memory manager, in case your application has special requirements.
The SICStus Prolog memory manager has a two-layer structure. The top
layer has roughly the same functionality as the standard UNIX functions
malloc
and free
, whereas the bottom layer is an interface
to the operating system. It's the bottom layer that can be customized
according to the API described below.
SICStus Prolog can generally use the whole virtual address space, but certain memory blocks are address-constrained--they must fit within a given memory range, the size of which is 256Mb (2^28 bytes) on 32-bit platforms, and 1Eb (2^60 bytes) on 64-bit platforms. Memory blocks are also subject to certain alignment constraints.
The API is as follows:
typedef int SP_InitAllocHook(size_t alignment, void *earliest_start, void *latest_end, void *cookie); typedef void SP_DeinitAllocHook(void *cookie); typedef void *SP_AllocHook(size_t size, size_t *actual_sizep, int constrained, void *cookie); typedef int SP_FreeHook(void *ptr, size_t size, int constrained, int force, void *cookie); int SP_set_memalloc_hooks(int hint, SP_InitAllocHook *init_alloc_hook, SP_DeinitAllocHook *deinit_alloc_hook, SP_AllocHook *alloc_hook, SP_FreeHook *free_hook, void *cookie);
SP_set_memalloc_hooks
SP_initialize
.
hint
cookie
SP_set_memalloc_hooks
is passed to each hook
function. One possible use is to keep track of multiple SICStus
run-times within the same process.
init_alloc_hook
alignment
is guaranteed to be a power of 2,
and is used by alloc_hook
. earliest_start
(inclusive) and
latest_end
(exclusive) are the bounds within which
address-constrained memory blocks must fit. Both are aligned according
to alignment
and non-zero. The function can do whatever
initialization that this layer of memory management wants to do. It
should return non-zero if it succeeds, zero if the memory manager bottom
layer could not be initialized, in which case initialization of the
SICStus run-time will fail.
deinit_alloc_hook
SP_deinitialize
when the Prolog engine shuts down.
The function can do any necessary cleaning up.
alloc_hook
size
bytes aligned at a multiple of alignment
. The
actual size of the piece of memory should be returned in
*actual_sizep
. If constrained
is non-zero, the piece of
memory must be address-constrained. Should return NULL
if it
cannot allocate a suitable piece of memory. Note that the memory
returned need not be aligned as long as there is room for an aligned
block of at least size
bytes.
free_hook
alloc_hook
. constrained
is the same as
when alloc_hook
was called to allocate the memory block. If
force
is non-zero, free_hook
must accept the piece of
memory; otherwise, it only accepts it if it is able to return it to the
operating system. free_hook
should return non-zero iff it
accepts the piece of memory. Otherwise, the upper layer will keep using
the memory as if it were not freed.
The default bottom layers look at the environment variables
PROLOGINITSIZE
, PROLOGINCSIZE
, PROLOGKEEPSIZE
and
PROLOGMAXSIZE
. They are useful for customizing the default
memory manager. If you redefine the bottom layer, you can choose to
ignore these environment variables. See Environment Variables.