9.4.6.3 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, and 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.

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