Node:Operating System Services, Next:Miscellaneous C API Functions, Previous:Unifying and Comparing Terms, Up:Support
The standard C library memory allocation functions (malloc,
calloc, realloc, and free) are available in
foreign code, but cannot reuse any free memory that SICStus Prolog's
memory manager may have available, and so may contribute to memory
fragmentation.
The following functions provide the same services via SICStus Prolog's memory manager.
void * SP_malloc(size_t size)
size
bytes.
void * SP_calloc(size_t nmemb, size_t size)
Returns a pointer to a block of at least size *
nemb. The first size * nmemb bytes are set to zero.
void * SP_realloc(void *ptr, size_t size)
ptr to size
bytes and returns a pointer to the (possibly moved) block. The contents
will be unchanged up to the lesser of the new and old sizes. The block
referenced by ptr must have been obtained by a call to
SP_malloc or SP_realloc, and must not have been released
by a call to SP_free or SP_realloc.
void SP_free(void *ptr)
ptr, which must have been
obtained by a call to SP_malloc or SP_realloc, and must
not have been released by a call to SP_free or SP_realloc.
char * SP_strdup(const char *str)
Returns a pointer to a new string which is a duplicate of the string
pointer to by str. The memory for the new string is allocated
using SP_malloc().
SICStus Prolog caches the name of the current working directory. To
take advantage of the cache and to keep it consistent, foreign code
should call the following interface functions instead of calling
chdir() and getcwd() directly:
int SP_chdir(const char *path)
path to become the current
working directory. Returns 0 upon successful completion. Otherwise, a
value of -1 is returned and errno is set to indicate the error.
char *SP_getcwd(char *buf, unsigned int size);
Returns a pointer to the current directory pathname. If buf is
not NULL, the pathname will be stored in the space pointed to by
buf. If buf is a NULL pointer, size bytes
of space will be obtained using SP_malloc(). In this case, the
pointer returned may be used as the argument in a subsequent call to
SP_free(). Returns NULL with errno set if
size is not large enough to store the pathname.
When running more that one SICStus run-time in the same process it is often necessary to protect data with mutual exclusion locks. The following functions implement recursive mutual exclusion locks which only need static initialization.
Note that the SICStus run-time is not thread safe in general.
typedef ... SP_mutex;
#define SP_MUTEX_INITIALIZER ...
int SP_mutex_lock(SP_mutex *pmx);
int SP_mutex_unlock(SP_mutex *pmx);
A (recursive) mutual exclusion lock is declared as type
SP_mutex. It should be initialized to (the static initializer)
SP_MUTEX_INITIALIZER before use.
SP_mutex_lock locks the mutex. SP_mutex_lock returns zero
on error, non-zero on success.
SP_mutex_unlock unlocks the mutex. It returns zero on error,
non-zero on success. The number of unlocks must match the number of
locks and only the thread that performed the lock can unlock the
mutex. SP_mutex_unlock returns zero on error, non-zero on
success.
...
static SP_mutex volatile my_mutex = SP_MUTEX_INITIALIZER;
/* only access this counter with my_mutex locked */
int volatile protected_counter = 0;
/* returns the new value of protected_counter */
int increment_the_counter(void)
{
int new_value;
if(SP_mutex_lock(&my_mutex) == 0) goto error_handling;
/* No other thread can update protected_counter here */
new_value = protected_counter+1;
protected_counter = new_value;
if (SP_mutex_unlock(&my_mutex) == 0) goto error_handling;
return new_value;
error_handling:
...
}