Node:Operating System Services, Next:, Previous:Unifying and Comparing Terms, Up:Support



Operating System Services

Memory Allocation

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)
Returns a pointer to a block of at least 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)
Changes the size of the block referenced by 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)
Releases the block referenced by 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().

File System

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)
Cause a directory pointed to by 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.

Threads

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:
       ...
     }