8.2.2 Using More than One SICStus Runtime

Using more than one SICStus runtime in a process is only supported when the dynamic library version of the SICStus runtime is used (e.g. sprt4-3-3.dll, libsprt4-3-3.so).

An application that wants to use more than one SICStus runtime needs to be built using the --multi-sp-aware option to spld. C-code compiled by spld --multi-sp-aware will have the C preprocessor macro MULTI_SP_AWARE defined and non-zero.

Unlike the single runtime case described above, an application built with --multi-sp-aware will not have a global variable that holds the dispatch vector. Instead, your code will have to take steps to ensure that the appropriate dispatch vector is used when switching between SICStus runtimes.

There are several steps needed to access a SICStus runtime from an application built with --multi-sp-aware.

  1. You must obtain the dispatch vector of the initial SICStus runtime using SP_get_dispatch(). Note that this function is special in that it is not accessed through the dispatch vector; instead, it is exported in the ordinary manner from the SICStus runtime dynamic library (sprt4-3-3.dll under Windows and, typically, libsprt4-3-3.so under UNIX).
  2. You must ensure that SICStusDISPATCHVAR expands to something that references the dispatch vector obtained in step 1.

    The C preprocessor macro SICStusDISPATCHVAR should expand to a SICSTUS_API_STRUCT_TYPE *, that is, a pointer to the dispatch vector that should be used. When --multi-sp-aware is not used SICStusDISPATCHVAR expands to sp_GlobalSICStus as described above. When using --multi-sp-aware it is probably best to let SICStusDISPATCHVAR expand to a local variable.

  3. Once you have access to the SICStus API of the initial SICStus runtime you can call the SICStus API function SP_load_sicstus_run_time() to load additional runtimes.
SICSTUS_API_STRUCT_TYPE *SP_get_dispatch(void *reserved);

SP_get_dispatch() returns the dispatch vector of the SICStus runtime. The argument reserved should be NULL. This function can be called from any thread.

typedef SICSTUS_API_STRUCT_TYPE *SP_get_dispatch_type(void *);

int SP_load_sicstus_run_time(SP_get_dispatch_type **ppfunc, void *reserved);

SP_load_sicstus_run_time() loads a new SICStus runtime. If a new runtime could be loaded a positive value is returned and the address of the SP_get_dispatch() function of the newly loaded SICStus runtime is stored at the address ppfunc. The second argument, phandle, is reserved and should be NULL.

As a special case, if SP_load_sicstus_run_time() is called from a SICStus runtime that has not been initialized (with SP_initialize()) and that has not previously been loaded as the result of calling SP_load_sicstus_run_time(), no new runtime is loaded. Instead, the SP_get_dispatch() of the runtime itself is returned. In particular, the first time SP_load_sicstus_run_time() is called on the initial SICStus runtime, and if this happens before the initial SICStus runtime is initialized, no new runtime is loaded.

Calling SP_load_sicstus_run_time() from a particular runtime can be done from any thread.

An application that links statically with the SICStus runtime should not call SP_load_sicstus_run_time().

You should not use prelinked foreign resources when using multiple SICStus runtimes in the same process.

For an example of loading and using multiple SICStus runtimes, see library/jasper/spnative.c that implements this functionality for the Java interface Jasper.

Send feedback on this subject.