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. Furthermore, the C library functions may return values
that are not aligned pointers, something which many functions of the foreign
language interface require.
The following functions provide the same services via SICStus Prolog's memory manager. All pointers returned are aligned.
void * SP_malloc(unsigned int size)
size
bytes.
void * SP_calloc(unsigned int nmemb, unsigned 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, unsigned int 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: ... }