To make it simpler to convert old foreign resources, there is an intermediate level of support for multiple SICStus run-times. This level of support makes it possible for several SICStus run-times to call the foreign resource, but a mutual exclusion lock ensures that only one SICStus run-time at a time can execute code in the foreign resource. That is, the mutex is locked upon entry to any function in the foreign resource and unlocked when the function returns. This makes it possible to use a global variable to hold the SICStus dispatch vector, in much the same way as is done when only a single SICStus run-time is supported. In addition, a special hook function in the foreign resource will be called every time the foreign resource is entered. This hook function can then make arrangements to ensure that any global variables are set up as appropriate.
To build a foreign resource in this way, use splfr --exclusive-access
. In addition to including the generated header
file, your code needs to define the context switch function. If the
resource is named resname, the context switch hook
should look like:
void sp_context_switch_hook_resname(int entering)
The context switch hook will be called with the SICStus API
dispatch vector already set up, so calling any SICStus API function from
the context switch hook will work as expected. The argument
entering
will be non-zero when a SICStus run-time is about to
call a function in the foreign resource. The hook will be
called with entering
zero when the foreign function is about to
return to SICStus.
It is possible to specify a name for the context switch hook with the splfr option --context-hook=name. If you do not require a context switch hook you can specify the splfr option --no-context-hook.
Due to the use of mutual exclusion lock to protect the foreign resource, there is a remote possibility of dead-lock. This would happen if the foreign resource calls back to SICStus and then passes control to a different SICStus run-time in the same thread, which then calls the foreign resource. For this reason it is best to avoid --exclusive-access for foreign resources that makes call-backs into Prolog.
The new SICStus API function SP_foreign_stash()
provides access
to a location where the foreign resource can store anything that
is specific to the calling SICStus run-time. The location is specific to
each foreign resource and each SICStus
run-time. See OS Threads.
C code compiled by splfr --exclusive-access
will have the C
pre-processor macro SP_SINGLE_THREADED
defined to a non-zero
value.
Some of the foreign resources in the SICStus library use this
technique; see for instance library(system)
.