]> rtime.felk.cvut.cz Git - frescor/fosa.git/blobdiff - src_aquosa/fosa_threads_and_signals.c
Transition to phase II API completed.
[frescor/fosa.git] / src_aquosa / fosa_threads_and_signals.c
index 8b62f294375ae9136e2dfe4059283b902f4fe40a..1cb47959fffe0fa3322250bc5460e10fef904faa 100644 (file)
@@ -88,9 +88,6 @@ int init_keys()
        if ((error = pthread_mutex_init(&key_lock,&attr)) != 0)
                return error;
 
-       //if ((error = pthread_mutexattr_destroy(&attr)) != 0)
-       //      return error;
-
        return 0;
 }
 
@@ -171,7 +168,7 @@ int fosa_thread_attr_init(fosa_thread_attr_t *attr)
  * pointed to by attr, and deallocate any system resources allocated for it
  * 
  * Returns 0
- */
+ **/
 int fosa_thread_attr_destroy(fosa_thread_attr_t *attr)
 {
        fosa_thread_id_t self;
@@ -198,7 +195,7 @@ int fosa_thread_attr_destroy(fosa_thread_attr_t *attr)
  * return 0 if successful, or the following error code:
  *    FOSA_EINVAL: the specified stacksize  value is not supported in
  *            this implementation
- */
+ **/
 int fosa_thread_attr_set_stacksize(fosa_thread_attr_t *attr,
                                   size_t stacksize)
 {
@@ -221,7 +218,7 @@ int fosa_thread_attr_set_stacksize(fosa_thread_attr_t *attr,
  * minimum stack size stored in the thread attributes object attr.
  * 
  * return 0
- */
+ **/
 int fosa_thread_attr_get_stacksize(const fosa_thread_attr_t *attr,
                                   size_t *stacksize)
 {
@@ -441,7 +438,7 @@ int fosa_thread_get_specific_data(int key,
  **/
 int fosa_get_priority_max()
 {
-       return sched_get_priority_max(SCHED_FIFO);
+       return sched_get_priority_max(SCHED_RR);
 }
 
 /**
@@ -451,7 +448,7 @@ int fosa_get_priority_max()
  **/
 int fosa_get_priority_min()
 {
-       return sched_get_priority_min(SCHED_FIFO);
+       return sched_get_priority_min(SCHED_RR);
 }
 
 /**
@@ -472,6 +469,7 @@ 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;
        struct sched_param param;
 
@@ -481,6 +479,8 @@ int fosa_thread_attr_set_prio(fosa_thread_attr_t *attr, int prio)
                return EINVAL;
        
        param.sched_priority = prio;
+       if ((error = pthread_attr_setschedpolicy(attr, SCHED_RR)) == 0)
+               return error;
 
        return pthread_attr_setschedparam(attr, &param);
 }
@@ -528,19 +528,10 @@ 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)
 {
        struct sched_param param;
-       int error;
 
        param.sched_priority=prio;
-       if (tid.linux_pid == tid.linux_tid)
-               error = sched_setscheduler(tid.linux_pid,
-                                          SCHED_RR,
-                                          &param);
-       else
-               error = pthread_setschedparam(tid.pthread_id,
-                                              SCHED_RR,
-                                              &param);
 
-       return error;
+       return sched_setscheduler(0, SCHED_RR, &param);
 }
 
 /**
@@ -553,18 +544,12 @@ int fosa_thread_set_prio(fosa_thread_id_t tid, int prio)
  * 
  * Returns 0
  **/
-int fosa_thread_get_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 policy, error;
-
-       if (tid.linux_pid == tid.linux_tid)
-               error = sched_getparam(tid.linux_pid, &param);
-       else
-               error = pthread_getschedparam(tid.pthread_id,
-                                             &policy,
-                                             &param);
+       int error;
 
+       error = sched_getparam(0, &param);
        *prio = param.sched_priority;
 
        return error;
@@ -596,6 +581,10 @@ int fosa_thread_get_prio (fosa_thread_id_t tid, int *prio)
  *     EINVAL: the array contains one or more values which are not
  *             between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size
  *             is less than 0
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
  **/
 int fosa_set_accepted_signals(fosa_signal_t set[], int size)
 {
@@ -607,7 +596,6 @@ int fosa_set_accepted_signals(fosa_signal_t set[], int size)
        if ((error = sigemptyset(&sigset)) != 0)
                return error;
 
-       /* real-time signal (can be queued) */
        action.sa_handler = SIG_DFL;
        action.sa_mask = sigset;
        action.sa_flags = SA_SIGINFO;
@@ -637,12 +625,16 @@ int fosa_set_accepted_signals(fosa_signal_t set[], int size)
  * 
  * The signal number specified by signal is sent together with the
  * information specified by info, to the thread identified by
- * receiver.
- * 
- * Note that, in this implementation, the signal is sent to any thread
- * waiting for it (maybe via fosa_signal_wait()).
- * If needed ensure the receiver is the only one who is waiting for the
- * signal (e.g., by using different signal numbers for each thread). 
+ * receiver. In those implementations that do not support queueing a
+ * signal with information to a thread (such as POSIX), the signal may
+ * be sent to any thread that is waiting for this signal via
+ * fosa_signal_wait(). Portability can be ensured by having the receiver
+ * thread be the one who is waiting for the signal. 
+ *
+ * In this implementation, this limitation has been overcome by means
+ * of the Linux specific capability of sending a timer event directly
+ * to a specific thread. Thus, we program a fake timer to fire immediately
+ * and notify such event to the requested receiver thread.
  *
  * Returns 0 if successful; otherwise it returns an error code:
  *     EINVAL: the signal specified by signal is not
@@ -651,13 +643,33 @@ int fosa_set_accepted_signals(fosa_signal_t set[], int size)
  *     EAGAIN: no resources are available to queue the signal; the
  *             maximum number of queued signals has been reached, or a
  *             systemwide resource limit has been exceeded
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
  **/
 int fosa_signal_queue(fosa_signal_t signal,
                      fosa_signal_info_t info,
                      fosa_thread_id_t receiver)
 {
-       /* Note: signal sent to a "whole" process */
-       return sigqueue(receiver.linux_pid, signal, *((union sigval*) &info));
+       int error;
+       timer_t fake_timer;
+       struct itimerspec fake_time;
+       struct sigevent fake_event;
+
+       timer_create(CLOCK_MONOTONIC, &fake_event, &fake_timer);
+
+        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;
+        fake_event.sigev_notify = SIGEV_THREAD_ID | SIGEV_SIGNAL;
+        fake_event.sigev_signo  = SIGRTMIN;
+       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);
+
+       return error;
 }
 
 /**
@@ -679,6 +691,10 @@ int fosa_signal_queue(fosa_signal_t signal,
  *     EINVAL: the array contains one or more values which are not
  *             between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size
  *             is less than 0
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
  **/
 int fosa_signal_wait(fosa_signal_t set[], int size,
                     fosa_signal_t *signal_received,
@@ -698,7 +714,7 @@ int fosa_signal_wait(fosa_signal_t set[], int size,
        if ((error = sigwaitinfo(&sigset, &siginfo)) != 0)
                return error;
 
-       if (signal_received != NULL)
+       if (info != NULL && signal_received != NULL)
                *signal_received = siginfo.si_signo;
        if (info != NULL)
                *info = (fosa_signal_info_t) siginfo.si_value.sival_int;
@@ -720,6 +736,10 @@ int fosa_signal_wait(fosa_signal_t set[], int size,
  *             between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size
  *             is less than 0, or timeout is invalid
  *     EAGAIN: The timeout expired
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
  **/
 int fosa_signal_timedwait(fosa_signal_t set[], int size,
                          fosa_signal_t *signal_received,
@@ -747,3 +767,4 @@ int fosa_signal_timedwait(fosa_signal_t set[], int size,
 
        return 0;
 }
+