From cf9c3554bbc9c191c1bfea338abca621f65ad891 Mon Sep 17 00:00:00 2001 From: faggioli Date: Tue, 3 Feb 2009 13:51:23 +0000 Subject: [PATCH] Transition to phase II API completed. 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 | 65 ++++++++++++++++++++------- 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/src_aquosa/fosa_threads_and_signals.c b/src_aquosa/fosa_threads_and_signals.c index 7cb0378..1cb4795 100644 --- a/src_aquosa/fosa_threads_and_signals.c +++ b/src_aquosa/fosa_threads_and_signals.c @@ -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, ¶m); } @@ -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, -- 2.39.2