]> rtime.felk.cvut.cz Git - frescor/fosa.git/commitdiff
Adding a FOSA test to find a bug manifested in Thales demo
authortelleriam <telleriam@35b4ef3e-fd22-0410-ab77-dab3279adceb>
Wed, 11 Mar 2009 18:33:14 +0000 (18:33 +0000)
committertelleriam <telleriam@35b4ef3e-fd22-0410-ab77-dab3279adceb>
Wed, 11 Mar 2009 18:33:14 +0000 (18:33 +0000)
git-svn-id: http://www.frescor.org/private/svn/frescor/fosa/trunk@1566 35b4ef3e-fd22-0410-ab77-dab3279adceb

src_marte_os/tests/test_monotonic_cpuclock_consumption/Makefile [new file with mode: 0644]
src_marte_os/tests/test_monotonic_cpuclock_consumption/Makefile.omk [new file with mode: 0644]
src_marte_os/tests/test_monotonic_cpuclock_consumption/test_monotonic_cpuclock_consumption.c [new file with mode: 0644]

diff --git a/src_marte_os/tests/test_monotonic_cpuclock_consumption/Makefile b/src_marte_os/tests/test_monotonic_cpuclock_consumption/Makefile
new file mode 100644 (file)
index 0000000..1e776f9
--- /dev/null
@@ -0,0 +1,6 @@
+include ../../../config.mk
+include ../../../rules.mk
+
+
+
+
diff --git a/src_marte_os/tests/test_monotonic_cpuclock_consumption/Makefile.omk b/src_marte_os/tests/test_monotonic_cpuclock_consumption/Makefile.omk
new file mode 100644 (file)
index 0000000..a02e70f
--- /dev/null
@@ -0,0 +1,8 @@
+test_PROGRAMS:=$(basename $(notdir $(wildcard $(SOURCES_DIR)/*.c)))
+
+$(foreach t,$(test_PROGRAMS),\
+$(eval $(t)_SOURCES = $(t).c)\
+$(eval $(t)_LIBS = fosa m)\
+)
+
+
diff --git a/src_marte_os/tests/test_monotonic_cpuclock_consumption/test_monotonic_cpuclock_consumption.c b/src_marte_os/tests/test_monotonic_cpuclock_consumption/test_monotonic_cpuclock_consumption.c
new file mode 100644 (file)
index 0000000..b6dada9
--- /dev/null
@@ -0,0 +1,263 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2008 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FOSA (Frsh Operating System Adaption)
+//
+//  FOSA is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FOSA is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FOSA; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FOSA header files in a file,
+//  instantiating FOSA generics or templates, or linking other files
+//  with FOSA objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+/*
+    Idea of the test:
+
+    This test verifies that the remaining budget of an execution-time
+    clock decreases in a monotonic way with execution time.
+
+    Some traces in a FRSH demo with Thales made us believe that
+    sometimes this does not happen.
+
+    The test consists in creating a monitored thread that execute very
+    small time slots and remain blocked for most of the time.  In each
+    block-unblock period the cpu clock is read, the timer is disarmed
+    and armed again. 
+
+    We verify that the remaining time obtained when disarming the
+    timer is equal or less than the time used to arm the timer
+    initially.
+
+*/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <time.h> // for nanosleep
+
+#include <assert.h>
+#include <stdlib.h> // for exit in assert
+#include <string.h> // for memset
+
+#include "fosa.h"
+#include <misc/error_checks.h>
+#include <drivers/console_switcher.h>
+
+/*****************************/
+/*   D E F I N I T I O N S   */
+/*****************************/
+#define NUMBER_OF_TRIES 25
+#define SLEEP_TIME_MSECS 5
+#define ARMED_BUDGET_MSECS 2000
+
+#define MAIN_PRIO 5
+#define MUTEX_CEILING 5
+#define MONITORED_THREAD_PRIO 5
+
+#define TIMER_SIGNAL (FOSA_SIGNAL_MAX - 1)
+
+
+typedef struct _thread_arg_t
+{
+    fosa_cond_t *conditional_variable;
+    fosa_mutex_t *sync_mutex;
+    int *slave_can_run;
+} thread_arg_t;
+
+
+/***************************/
+/*   P R O T O T Y P E S   */
+/***************************/
+static void *monitored_thread_body(void *arg);
+
+
+int main ()
+{
+    SERIAL_CONSOLE_INIT();
+
+
+    fosa_thread_attr_t monitored_attr;
+    fosa_thread_id_t monitored_tid;
+
+    fosa_cond_t conditional_variable;
+    fosa_mutex_t sync_mutex;
+    int slave_can_run;
+
+    fosa_clock_id_t monitored_clock;
+    fosa_timer_id_t monitored_timer;
+
+    fosa_signal_t signal_set[1];
+    fosa_signal_info_t signal_info_to_send;
+
+    fosa_rel_time_t remaining_time = fosa_msec_to_rel_time(ARMED_BUDGET_MSECS);
+    fosa_rel_time_t interval_to_sleep = fosa_msec_to_rel_time(SLEEP_TIME_MSECS);
+    int i;
+
+
+    thread_arg_t thread_arg;
+
+    /* Set the process-wide signal mask */
+    /************************************/
+    signal_set[0] = TIMER_SIGNAL;
+    CHK(  fosa_set_accepted_signals(signal_set, 1) );
+    CHK(  fosa_thread_set_prio(fosa_thread_self(), fosa_get_priority_min() + MAIN_PRIO) );
+
+
+    /* We initializa the condvar the mutex and */
+    /* set the predicate to false              */
+    /*******************************************/
+    CHK(  fosa_cond_init(&conditional_variable) );
+    CHK(  fosa_mutex_init(&sync_mutex, fosa_get_priority_min() + MUTEX_CEILING) );
+    slave_can_run = 0;
+
+    
+    thread_arg.conditional_variable = &conditional_variable;
+    thread_arg.sync_mutex = &sync_mutex;
+    thread_arg.slave_can_run = &slave_can_run;
+
+    /* We create the monitored thread that will stop in the */
+    /* conditional variable wait.                           */
+    /********************************************************/
+    thread_arg.conditional_variable = &conditional_variable;
+    thread_arg.sync_mutex = &sync_mutex;
+   
+    CHK(  fosa_thread_attr_init(&monitored_attr) );
+    CHK(  fosa_thread_attr_set_prio(&monitored_attr, fosa_get_priority_min() + MONITORED_THREAD_PRIO) );
+    
+    CHK(  fosa_thread_create(&monitored_tid, &monitored_attr, monitored_thread_body, &thread_arg) );
+
+    /* We create the CPU timer for the monitored thread */
+    /* and program it for a long expiration period.     */
+    /****************************************************/
+    signal_info_to_send.sival_int = 42;
+    CHK(  fosa_thread_get_cputime_clock(monitored_tid, &monitored_clock) );
+    CHK(  fosa_timer_create(monitored_clock, TIMER_SIGNAL, signal_info_to_send, &monitored_timer) );
+
+
+    for (i = 0; i < NUMBER_OF_TRIES; i++)
+    {
+        long int msecs_armed_after_activation;
+        long int msecs_disarmed_after_blocking;
+        fosa_abs_time_t current_time;
+        fosa_abs_time_t awakening_time;
+        struct timespec awakening_time_tspec;
+
+        /* We first unblock the thread by signalling the condition var */
+        CHK(  fosa_mutex_lock(&sync_mutex) );
+        assert(slave_can_run == 0);
+        slave_can_run = 1;
+        CHK(  fosa_cond_signal(&conditional_variable) );
+        CHK(  fosa_mutex_unlock(&sync_mutex) );
+
+        printf("MAIN:  Slave activation # %d\n", i);
+        /* Since we have the lock, we have a higher priority */
+        /* due to the priority ceiling of the mutex.        */
+        /****************************************************/
+
+        // We arm the timer
+        msecs_armed_after_activation = fosa_rel_time_to_msec(remaining_time);
+        printf("MAIN:  Timer armed with: %ld msec\n", msecs_armed_after_activation);
+        CHK(  fosa_rel_timer_arm(monitored_timer, &remaining_time) );
+
+        
+        // We let the thread execute something (short) and then block
+        // itself again
+        CHK(  fosa_clock_get_time(FOSA_CLOCK_REALTIME, &current_time) );
+        printf("MAIN:  SLEEPING\n");
+        awakening_time = fosa_abs_time_incr(current_time, interval_to_sleep);
+        awakening_time_tspec = fosa_abs_time_to_timespec(awakening_time);
+
+
+        CHK(  clock_nanosleep(FOSA_CLOCK_REALTIME, TIMER_ABSTIME, &awakening_time_tspec, NULL) );
+
+
+        // We disarm the timer and release the mutex
+        CHK(  fosa_timer_disarm(monitored_timer, &remaining_time) );
+        msecs_disarmed_after_blocking = fosa_rel_time_to_msec(remaining_time);
+
+        printf("MAIN:  Timer disarmed with %ld msec\n", msecs_disarmed_after_blocking);
+
+        if (msecs_disarmed_after_blocking > msecs_armed_after_activation)
+        {
+            printf("MAIN: BINGOO  Bug reproduced!!!\n");
+            exit(1);
+        }
+
+    }
+        
+    return 0;
+}
+
+// -----------------------------------------------------------
+
+static void *monitored_thread_body(void *arg)
+{
+    thread_arg_t *thread_args = (thread_arg_t *) arg;
+
+    int nr_activation = 0;
+
+    while(1)
+    {
+        printf("SLAVE about to block\n");
+        CHK(  fosa_mutex_lock(thread_args->sync_mutex) );
+
+        while (!*(thread_args->slave_can_run))
+        {
+            CHK(  fosa_cond_wait(thread_args->conditional_variable,
+                                 thread_args->sync_mutex) );
+        }
+
+        printf("This comes second\n");
+
+        printf("SLAVE: Activation nr: %d\n", nr_activation);
+        nr_activation++;
+
+        *(thread_args->slave_can_run) = 0;
+        CHK(  fosa_mutex_unlock(thread_args->sync_mutex) );
+
+    }
+}
+
+