]> rtime.felk.cvut.cz Git - frescor/fosa.git/commitdiff
Transition to phase II API completed.
authorfaggioli <faggioli@35b4ef3e-fd22-0410-ab77-dab3279adceb>
Tue, 3 Feb 2009 13:51:23 +0000 (13:51 +0000)
committerfaggioli <faggioli@35b4ef3e-fd22-0410-ab77-dab3279adceb>
Tue, 3 Feb 2009 13:51:23 +0000 (13:51 +0000)
The Linux/AQuoSA FOSA sources are now fully phase II API-compliant.
All the prescribed functionalities of the FOSA software layer have been
implemented and their semantic complies with the specifications.

Signal delivery also adheres to FOSA/FRSH design documents, thus it is now
possible to send a FOSA_SIGNAL directly to a specific thread. In fact,
altough not available in POSIX, we achieved this by means of a Linux
specific feature when dealing with timer notification events (see comments
in source files for details).

The only not-implemented module is FOSA ADS, since we are not interested in
implementing Application Defined Scheduling in Linux. However, source file
for it is present in src_aquosa folder, and all the functions returns
-EINVAL as error code.

git-svn-id: http://www.frescor.org/private/svn/frescor/fosa/trunk@1530 35b4ef3e-fd22-0410-ab77-dab3279adceb

src_aquosa/fosa_threads_and_signals.c

index 7cb0378437e6c204b2f329c73e999caa57bb2f85..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;
 }
 
@@ -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);
 }
@@ -581,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)
 {
@@ -592,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;
@@ -622,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
@@ -636,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;
 }
 
 /**
@@ -664,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,
@@ -683,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;
@@ -705,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,