]> rtime.felk.cvut.cz Git - frescor/fosa.git/blobdiff - src_aquosa/fosa_threads_and_signals.c
Updated for compilation on older systems without PTHREAD_PRIO_INHERIT
[frescor/fosa.git] / src_aquosa / fosa_threads_and_signals.c
index 1cb47959fffe0fa3322250bc5460e10fef904faa..a5910719576f8858a49e764acc8c30422cdb8035 100644 (file)
 #include "fosa_configuration_parameters.h"
 #include "fosa_threads_and_signals.h"
 
+#ifdef OMK_FOR_USER            /* If compiled by OMK, use the config */
+#include "fosa_config.h"
+#endif
+
 /*************************
  * Storage of thread-specific keys
  *************************/
@@ -73,20 +77,22 @@ static pthread_mutex_t key_lock;
 /* Initialize the keys data structure */
 int init_keys()
 {
-       int i, error;
+       int i, ret;
        pthread_mutexattr_t attr;
 
        for(i = 0; i < FOSA_MAX_KEYS; i++)
                key_in_use[i] = false;
 
-       if ((error = pthread_mutexattr_init(&attr)) != 0)
-               return error;
+       ret = pthread_mutexattr_init(&attr);
+       if (ret) return errno;
 
-       if ((error = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT)) != 0)
-               return error;
+#ifndef CONFIG_NO_PRIO_INHERIT /* Not supported on older systems */
+       ret = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
+       if (ret) return errno;
+#endif
 
-       if ((error = pthread_mutex_init(&key_lock,&attr)) != 0)
-               return error;
+       ret = pthread_mutex_init(&key_lock,&attr);
+       if (ret) return errno;
 
        return 0;
 }
@@ -135,6 +141,14 @@ fosa_thread_id_t fosa_thread_self()
  * Thread attributes
  *************************/
 
+static inline int __fosa_check_thread(const fosa_thread_id_t *tid)
+{
+       if (tid->linux_pid == tid->linux_tid)
+               return 0;
+
+       return 1;
+}
+
 /**
  * fosa_thread_attr_init()
  *
@@ -149,13 +163,6 @@ fosa_thread_id_t fosa_thread_self()
  **/
 int fosa_thread_attr_init(fosa_thread_attr_t *attr)
 {
-       fosa_thread_id_t self;
-
-       /* only POSIX threads have attributes */
-       self = fosa_thread_self();
-       if (self.linux_pid == self.linux_tid)
-               return EINVAL;
-
        return pthread_attr_init(attr);
 }
 
@@ -171,13 +178,6 @@ int fosa_thread_attr_init(fosa_thread_attr_t *attr)
  **/
 int fosa_thread_attr_destroy(fosa_thread_attr_t *attr)
 {
-       fosa_thread_id_t self;
-
-       /* only POSIX threads can have attributes */
-       self = fosa_thread_self();
-       if (self.linux_pid == self.linux_tid)
-               return EINVAL;
-
        return pthread_attr_destroy(attr);
 }
 
@@ -199,13 +199,6 @@ int fosa_thread_attr_destroy(fosa_thread_attr_t *attr)
 int fosa_thread_attr_set_stacksize(fosa_thread_attr_t *attr,
                                   size_t stacksize)
 {
-       fosa_thread_id_t self;
-
-       /* only POSIX threads can set the size of the stack */
-       self = fosa_thread_self();
-       if (self.linux_pid == self.linux_tid)
-               return EINVAL;
-
        return pthread_attr_setstacksize(attr, stacksize);
 }
 
@@ -222,13 +215,6 @@ int fosa_thread_attr_set_stacksize(fosa_thread_attr_t *attr,
 int fosa_thread_attr_get_stacksize(const fosa_thread_attr_t *attr,
                                   size_t *stacksize)
 {
-       fosa_thread_id_t self;
-
-       /* only POSIX threads can set the size of the stack */
-       self = fosa_thread_self();
-       if (self.linux_pid == self.linux_tid)
-               return EINVAL;
-
        return pthread_attr_getstacksize(attr, stacksize);
 }
 
@@ -299,33 +285,30 @@ int fosa_thread_create(fosa_thread_id_t *tid,
  **/
 int fosa_key_create(int *key)
 {
-       int i, error = 0;
+       int i, ret;
        bool found = false;
-       fosa_thread_id_t self;
 
-       /* only POSIX threads can have specific data */
-       self = fosa_thread_self();
-       if (self.linux_pid == self.linux_tid)
-               return EINVAL;
-
-       if ((error = pthread_mutex_lock(&key_lock)) != 0)
-               return error;
+       ret = pthread_mutex_lock(&key_lock);
+       if (ret) return ret;
 
        /* find an unused key */
        for (i = 0; i < FOSA_MAX_KEYS; i++) {
                if (!key_in_use[i]) {
+                       ret = pthread_key_create(&(key_list[i]), NULL);
+                       if (ret) return ret;
+
                        *key = i;
                        key_in_use[i] = true;
-                       error = pthread_key_create(&(key_list[i]), NULL);
                        found = true;
+
                        break;
                }
        }
 
-       if ((error = pthread_mutex_unlock(&key_lock))!= 0)
-               return error;
+       ret = pthread_mutex_unlock(&key_lock);
+       if (ret) return ret;
 
-       return (!found ? FOSA_EINVAL : error);
+       return (!found ? FOSA_EINVAL : ret);
 }
 
 /**
@@ -340,22 +323,18 @@ int fosa_key_create(int *key)
  **/
 int fosa_key_destroy(int key)
 {
-       int error;
-       fosa_thread_id_t self;
+       int ret;
 
-       /* only POSIX threads can have specific data */
-       self = fosa_thread_self();
-       if (self.linux_pid == self.linux_tid)
-               return EINVAL;
+       ret = pthread_mutex_lock(&key_lock);
+       if (ret) return ret;
 
-       if ((error = pthread_mutex_lock(&key_lock)) != 0)
-               return error;
+       ret = pthread_key_delete(key_list[key]);
+       if (ret) return ret;
 
-       if ((error = pthread_key_delete(key_list[key])) != 0)
-               key_in_use[key]=false;
+       key_in_use[key]=false;
 
-       if ((error = pthread_mutex_unlock(&key_lock)) != 0)
-               return error;
+       ret = pthread_mutex_unlock(&key_lock);
+       if (ret) return ret;
 
        return 0;
 }
@@ -379,14 +358,15 @@ int fosa_key_destroy(int key)
                                   fosa_thread_id_t tid,
                                   const void * value)
 {
-       fosa_thread_id_t self;
+       int ret;
 
        /* only POSIX threads can have specific data */
-       self = fosa_thread_self();
-       if (self.linux_pid == self.linux_tid)
-               return EINVAL;
+       if (!__fosa_check_thread(&tid))
+               return FOSA_EINVAL;
+
+       ret = pthread_setspecific(key_list[key], value);
 
-       return pthread_setspecific(key_list[key], value);
+       return ret ? ret : 0;
 }
 
 /**
@@ -407,17 +387,13 @@ int fosa_thread_get_specific_data(int key,
                                  fosa_thread_id_t tid,
                                  void ** value)
 {
-       fosa_thread_id_t self;
-
        /* only POSIX threads can have specific data */
-       self = fosa_thread_self();
-       if (self.linux_pid == self.linux_tid)
+       if (!__fosa_check_thread(&tid))
                return EINVAL;
 
-       if ((value = pthread_getspecific(key_list[key])) != NULL)
-               return EINVAL;
-       else
-               return 0;
+       value = pthread_getspecific(key_list[key]);
+
+       return !value ? FOSA_EINVAL : 0;
 }
 
 /******************************************************************
@@ -438,7 +414,11 @@ int fosa_thread_get_specific_data(int key,
  **/
 int fosa_get_priority_max()
 {
-       return sched_get_priority_max(SCHED_RR);
+       int ret;
+
+       ret = sched_get_priority_max(SCHED_RR);
+
+       return ret ? errno : 0;
 }
 
 /**
@@ -448,7 +428,11 @@ int fosa_get_priority_max()
  **/
 int fosa_get_priority_min()
 {
-       return sched_get_priority_min(SCHED_RR);
+       int ret;
+
+       ret = sched_get_priority_min(SCHED_RR);
+
+       return ret ? errno : 0;
 }
 
 /**
@@ -469,18 +453,12 @@ int fosa_get_priority_min()
  **/
 int fosa_thread_attr_set_prio(fosa_thread_attr_t *attr, int prio)
 {
-       int error;
-       fosa_thread_id_t self;
+       int ret;
        struct sched_param param;
 
-       /* normal UNIX processes have no attributes */
-       self = fosa_thread_self();
-       if (self.linux_pid == self.linux_tid)
-               return EINVAL;
-       
        param.sched_priority = prio;
-       if ((error = pthread_attr_setschedpolicy(attr, SCHED_RR)) == 0)
-               return error;
+       ret = pthread_attr_setschedpolicy(attr, SCHED_RR);
+       if (ret) return ret;
 
        return pthread_attr_setschedparam(attr, &param);
 }
@@ -497,19 +475,15 @@ int fosa_thread_attr_set_prio(fosa_thread_attr_t *attr, int prio)
  **/
 int fosa_thread_attr_get_prio(const fosa_thread_attr_t *attr, int *prio)
 {
-       int error;
-       fosa_thread_id_t self;
+       int ret;
        struct sched_param param;
 
-       /* normal UNIX processes have no attributes */
-       self = fosa_thread_self();
-       if (self.linux_pid == self.linux_tid)
-               return EINVAL;
+       ret = pthread_attr_getschedparam(attr, &param);
+       if (ret) return ret;
 
-       if ((error = pthread_attr_getschedparam(attr, &param)) == 0)
-               *prio = param.sched_priority;
+       *prio = param.sched_priority;
 
-       return error;
+       return 0;
 }
 
 /**
@@ -527,11 +501,14 @@ int fosa_thread_attr_get_prio(const fosa_thread_attr_t *attr, int *prio)
  **/
 int fosa_thread_set_prio(fosa_thread_id_t tid, int prio)
 {
+       int ret;
        struct sched_param param;
 
-       param.sched_priority=prio;
+       param.sched_priority = prio;
+
+       ret = sched_setscheduler(0, SCHED_RR, &param);
 
-       return sched_setscheduler(0, SCHED_RR, &param);
+       return ret ? errno : 0;
 }
 
 /**
@@ -547,12 +524,12 @@ int fosa_thread_set_prio(fosa_thread_id_t tid, int prio)
 int fosa_thread_get_prio(fosa_thread_id_t tid, int *prio)
 {
        struct sched_param param;
-       int error;
+       int ret;
 
-       error = sched_getparam(0, &param);
+       ret = sched_getparam(0, &param);
        *prio = param.sched_priority;
 
-       return error;
+       return ret ? errno : 0;
 }
 
 /*******************************************************************
@@ -588,13 +565,13 @@ int fosa_thread_get_prio(fosa_thread_id_t tid, int *prio)
  **/
 int fosa_set_accepted_signals(fosa_signal_t set[], int size)
 {
-       int i, error;
+       int i, ret;
        fosa_thread_id_t self;
        sigset_t sigset;
        struct sigaction action;
 
-       if ((error = sigemptyset(&sigset)) != 0)
-               return error;
+       ret = sigemptyset(&sigset);
+       if (ret) goto err;
 
        action.sa_handler = SIG_DFL;
        action.sa_mask = sigset;
@@ -602,17 +579,24 @@ int fosa_set_accepted_signals(fosa_signal_t set[], int size)
        action.sa_sigaction = NULL;
 
        for (i = 0; i < size; i++) {
-               if ((error = sigaddset(&sigset, set[i])) != 0)
-                       return error;
-               if ((error = sigaction(set[i], &action, NULL)) != 0)
-                       return error;
+               ret = sigaddset(&sigset, set[i]);
+               if (ret) goto err;
+               ret = sigaction(set[i], &action, NULL);
+               if (ret) goto err;
        }
 
        self = fosa_thread_self();
-       if (self.linux_pid == self.linux_tid)
-               return pthread_sigmask(SIG_BLOCK, &sigset, NULL);
-       else
-               return sigprocmask(SIG_BLOCK, &sigset, NULL);
+       if (__fosa_check_thread(&self)) {
+               ret = pthread_sigmask(SIG_BLOCK, &sigset, NULL);
+               if (ret) return ret;
+       } else {
+               ret = sigprocmask(SIG_BLOCK, &sigset, NULL);
+               if (ret) goto err;
+       }
+
+       return 0;
+err:
+       return errno;
 }
 
 /**
@@ -652,12 +636,13 @@ int fosa_signal_queue(fosa_signal_t signal,
                      fosa_signal_info_t info,
                      fosa_thread_id_t receiver)
 {
-       int error;
+       int ret;
        timer_t fake_timer;
        struct itimerspec fake_time;
        struct sigevent fake_event;
 
-       timer_create(CLOCK_MONOTONIC, &fake_event, &fake_timer);
+       ret = timer_create(FOSA_CLOCK_REALTIME, &fake_event, &fake_timer);
+       if (ret) goto err;
 
         fake_time.it_value.tv_sec = fake_time.it_value.tv_nsec = 0;
         fake_time.it_interval.tv_sec = fake_time.it_interval.tv_nsec = 0;
@@ -666,10 +651,18 @@ int fosa_signal_queue(fosa_signal_t signal,
        fake_event.sigev_value.sival_int = info.sival_int;
         fake_event._sigev_un._tid = receiver.linux_tid;
 
-        error = timer_settime(fake_timer, TIMER_ABSTIME, &fake_time, NULL);
-       timer_delete(fake_timer);
+        ret = timer_settime(fake_timer, TIMER_ABSTIME, &fake_time, NULL);
+       if (ret) {
+               timer_delete(fake_timer);
+               goto err;
+       }
+
+       ret = timer_delete(fake_timer);
+       if (ret) goto err;
 
-       return error;
+       return 0;
+err:
+       return errno;
 }
 
 /**
@@ -700,19 +693,20 @@ int fosa_signal_wait(fosa_signal_t set[], int size,
                     fosa_signal_t *signal_received,
                     fosa_signal_info_t *info)
 {
-       int i, error;
+       int i, ret;
        sigset_t sigset;
        siginfo_t siginfo;
 
-       if ((error = sigemptyset(&sigset)) != 0)
-               return error;
+       ret = sigemptyset(&sigset);
+       if (ret) goto err;
 
-       for (i = 0; i < size; i++)
-               if ((error = sigaddset(&sigset,set[i])) != 0)
-                       return error;
+       for (i = 0; i < size; i++) {
+               ret = sigaddset(&sigset,set[i]);
+               if (ret) goto err;
+       }
 
-       if ((error = sigwaitinfo(&sigset, &siginfo)) != 0)
-               return error;
+       ret = sigwaitinfo(&sigset, &siginfo);
+       if (ret) goto err;
 
        if (info != NULL && signal_received != NULL)
                *signal_received = siginfo.si_signo;
@@ -720,6 +714,8 @@ int fosa_signal_wait(fosa_signal_t set[], int size,
                *info = (fosa_signal_info_t) siginfo.si_value.sival_int;
 
        return 0;
+err:
+       return errno;
 }
 
 /**
@@ -746,19 +742,20 @@ int fosa_signal_timedwait(fosa_signal_t set[], int size,
                          fosa_signal_info_t *info,
                          const struct timespec *timeout)
 {
-       int i, error;
+       int i, ret;
        sigset_t signalset;
        siginfo_t siginfo;
 
-       if ((error = sigemptyset(&signalset)) != 0)
-               return error;
+       ret = sigemptyset(&signalset);
+       if (ret) goto err;
 
-       for (i = 0; i < size; i++)
-               if ((error = sigaddset(&signalset,set[i])) != 0)
-                       return error;
+       for (i = 0; i < size; i++) {
+               ret = sigaddset(&signalset,set[i]);
+               if (ret) goto err;
+       }
 
-       if ((error = sigtimedwait(&signalset,&siginfo,timeout)) != 0)
-               return error;
+       ret = sigtimedwait(&signalset,&siginfo,timeout);
+       if (ret) goto err;
 
        if (signal_received != NULL)
                *signal_received = siginfo.si_signo;
@@ -766,5 +763,7 @@ int fosa_signal_timedwait(fosa_signal_t set[], int size,
                *info = (fosa_signal_info_t) siginfo.si_value.sival_int;
 
        return 0;
+err:
+       return errno;
 }