Initializing the Prolog Engine

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)

It is recommended that NULL be passed for the boot_path argument; SP_initialize() will then use the location of the SICStus run-time system or the executable to locate the any supporting files.

If, for some reason, boot_path must be passed explicitly it should be the name of a directory, equivalent to $SP_PATH/bin. If the boot path can not be determined by any other means 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. See WCX Foreign Interface, for implications of using non-ASCII characters in any of the arguments to SP_initialize().

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);
returns non-zero on success. Zero on error, e.g. if called after SP_initialize().
is reserved for future extensions. It should be zero.
can be used for any state needed by the memory hook functions. The value passed to 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.
is called initially. 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.
is called by SP_deinitialize() when the Prolog engine shuts down. The function can do any necessary cleaning up.
must allocate and return a pointer to a piece of memory that contains at least 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.
is called with a pointer to a piece of memory to be freed and its size as returned by 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.