tema 4dccia.ua.es/dccia/inf/asignaturas/str/temario/tema4.pdfcontenido accediendo a posiciones de...

33
1 1 Maria Isabel Alfonso Galipienso. 2006 Tema 4 Sistemas operativos y Soportes de Ejecución Introducción Soporte de ejecución: POSIX RTLinux 2 Maria Isabel Alfonso Galipienso. 2006 Indice Introducción Soporte de ejecución: POSIX Extensiones de tiempo real Threads RTLinux

Upload: others

Post on 13-Feb-2021

9 views

Category:

Documents


0 download

TRANSCRIPT

  • 1

    1Maria Isabel Alfonso Galipienso. 2006

    Tema 4Sistemas operativos y Soportes de Ejecución

    IntroducciónSoporte de ejecución: POSIX

    RTLinux

    2Maria Isabel Alfonso Galipienso. 2006

    Indice

    Introducción

    Soporte de ejecución: POSIXExtensiones de tiempo real

    Threads

    RTLinux

  • 2

    3Maria Isabel Alfonso Galipienso. 2006

    Introducción

    Requerimientos de los S.O.T.R.Planificación de procesos de tiempo realPlanificación expulsivaGarantía de respuesta a interrupcionesPrioridades dinámicasComunicación síncrona y asíncrona entre procesosAdquisición de datos a altas velocidadesE/S de altas prestacionesAcceso a redes con protocolos deterministas

    SOTR= Sistema Operativo de Tiempo RealRTOS= Real Time Operating System

    4Maria Isabel Alfonso Galipienso. 2006

    Ejemplos de RTOS

    iRMX86: para sistemas empotrados (familia del 80x86)QNX: para aplicaciones basadas en el IBM-PC distribuidasVRTX: famila de sw para microproesadores orientados sistemas de control industrialAllegro Real-Time Operating SystemChimera Real-Time Operating System (Carnegie MellonUniversity) Chorus Operating SystemLynx Real-Time SystemsRT-Linux (Real-Time Linux Operating Systems)RTMX: Real Time IEEE POSIX Operating Systems and ToolsRTX (Real-time Executive) The Spring System (Sun Microsystems)VenturCom Real-Time Support (para Unix y Windows/NT) VRTX (Microtec Research)

  • 3

    5Maria Isabel Alfonso Galipienso. 2006

    Soporte de ejecución

    Run-time operating systemCapacidad del sistema operativo para proporcionar:

    Una serie de funcionalidades necesarias para soportar aplicaciones de tiempo realPermite la ejecución de sistemas de tiempo real cuando dichos sistemas se desarrollan en una máquina diferente (host machine vs. targetmachine)

    6Maria Isabel Alfonso Galipienso. 2006

    Indice

    Introducción

    Soporte de ejecución: POSIXExtensiones de tiempo realThreads

    RTLinux

    QNX

  • 4

    7Maria Isabel Alfonso Galipienso. 2006

    POSIX y Tiempo Real

    Portable Operating System Interface basado en UniXEl objetivo es conseguir la portabilidad de las aplicaciones a nivel de código fuenteDesarrollado por el IEEE Computer SocietyPOSIX es el estándar IEEE 1003Estándar definido empleando como base el lenguaje “C”

    Partes en las que se divide POSIX:POSIX.1 Unix básico (nada que ver con tiempo real) (1003.1)POSIX.4 Extensiones de tiempo real (1003.1b)POSIX.4a Más extensiones de tiempo real (1003.1c)POSIX.4b Extensiones de threads (1003.1d)

    8Maria Isabel Alfonso Galipienso. 2006

    POSIX

    1003.1 Servicios básicos del sistema operativo 1003.1a Extensiones a los servicios básicos 1003.1b Extensiones de tiempo real 1003.1c Extensión de threads 1003.1d Extensiones adicionales de tiempo real 1003.1e Seguridad 1003.1f Sistema de ficheros en red (NFS) 1003.1g Comunicaciones por red 1003.1h Tolerancia a fallos 1003.1j Extensiones de tiempo real avanzadas 1003.1m Puntos de chequeo y reintento 1003.2 Shell y utilidades 1003.2b Utilidades adicionales 1003.2d Ejecución por lotes (batch) 1003.3 Métodos para probar la conformidad con POSIX1003.21 Comunicaciones para sistemas distribuidos de tiempo real

  • 5

    9Maria Isabel Alfonso Galipienso. 2006

    Indice

    Introducción

    Soporte de ejecución: POSIXExtensiones de tiempo real

    Threads

    RTLinux

    10Maria Isabel Alfonso Galipienso. 2006

    POSIX.41003.1b- extensiones de tiempo realServicios para programación concurrente:

    Sincronización mediante semáforos contadoresObjetos de memoria compartida, colas de mensajes

    Servicios para conseguir un comportamiento temporal predecible:Entrada/salida asíncrona, entrada/salida sincronizada Incluyen la planificación expulsiva de procesos mediante políticas basadas en prioridades fijas Inhibición de memoria virtual para el espacio de direcciones de un procesoSeñales de tiempo real; y Relojes y temporizadores.

  • 6

    11Maria Isabel Alfonso Galipienso. 2006

    Sincronización entre procesos

    Se pueden utilizar semáforos, que pueden tener nombres, o ser anónimos si están en memoria compartida.Los semáforos no están libres de inversión de prioridad no limitada.sem_id sem_open (name, oflags,modo, valor_ini)sem_close (sem_id)sem_unlik (nombre)sem_wait (sem_id)sem_post (sem_id)sem_trywait (sem_id)int sem_get_value (sem_id)

    12Maria Isabel Alfonso Galipienso. 2006

    Semáforos

    Ejemplo:#include #include #include struct sched_param param;main()

    sem_t *mutex; int x;mutex = sem_open (“SEMAF”,O_CREAT,0 1);if (fork () == 0) {

    for (x=1; x

  • 7

    13Maria Isabel Alfonso Galipienso. 2006

    Comunicación de procesos

    Varios procesos pueden tener acceso a una zona de memoria común. Cada proceso la “verá” como si fuera memoria propia

    Se puede “mapear” un fichero en memoria física, y acceder a su contenido accediendo a posiciones de memoria.

    Se puede compartir la zona de memoria con otros procesos hijos.

    void *mmap (start,len,prot,flags,fd,offset)«”Mapea” len bytes desde offset del fichero fd en la posición de

    memoria start con los permisos de protección prot y los atributos flags»munmap (start,len)«Suprime la proyección de memoria de un archivo»

    MEMORIA COMPARTIDA

    14Maria Isabel Alfonso Galipienso. 2006

    Comunicación de procesosMEMORIA COMPARTIDA.

    Ejemplo:#include #include #include struct sched_param param;main() {

    int *ptr, fd;fd = open (“prueba.ps”, O_RDWR);ptr = mmap(NULL, 100*sizeof(int), PROT_READ ⏐PROT_WRITE,

    MAP_SHARED,fd,0L);ptr[0] = 0;if (fork () == 0) {

    while (ptr[0] == 0 );} else { ptr[0] = 1 );}

    }

  • 8

    15Maria Isabel Alfonso Galipienso. 2006

    Comunicación de procesos

    Método de comunicación asíncrono.Cuando un proceso recibe una señal, se interrumpe la ejecución en curso y se ejecuta la función manejador.Al finalizar la cual, se reanuda la ejecución interrumpida.

    SEÑALES

    Nombre de señal DescripciónSIGILL Instrucción ilegal (matar al proceso)SIGSEGV Acceso a memoria ilegal (matar al proceso)SIGTERM Finalizar el proceso de forma controlada (matar al proceso)SIGALRM Enviada cuando vence la alarma anteriormente pedida (m.p.)SIGKILL Finalizar incondicionalmente el proceso (no se puede ignorar ni

    capturar)SIGFPE Error en operación en coma flotante (matar al proceso)SIGSTOP, SIGCONT Detiene el proceso (no se puede capturar), continúa la ejecuciónSIGUSR1, SIGUSR2 Utilizables por el usuario (matar el proceso)SIGRTMIN...SIGRTMAX Utilizables por el usuario (matar el proceso). Ampliación para

    tiempo real

    16Maria Isabel Alfonso Galipienso. 2006

    Comunicación de procesos

    Hay más señales disponibles. Al menos 8 señales más: SIGRTMIN .. SIGRTMAX

    El envío de señales se realiza con sigqueue en lugar de kill

    Las señales se “entregan” en orden cronológico en el que fueron enviadas

    Podemos realizar una espera rápida de señales: no se tiene que ejecutar ningún manejador

    sigwaitinfo: espera la llegada de una señal pero no llama a ningún manejador, devuelve el número de la señal

    sigtimedwait: igual que la anterior, pero tiene un parámetro “timeout” que especifica un tiempo máximo de llegada de la señal

    SEÑALES PARA TIEMPO REAL

  • 9

    17Maria Isabel Alfonso Galipienso. 2006

    Comunicación de procesos

    Las opciones para tratar las señales son:Bloquear temporalmente la señalIgnorar la señalManejar la señal mediante una funciónDejar que el sistema realice la función por defecto

    sigaction (señal, control, control_anterior)«Asocia la función en control a la señal»kill (pid, señal)«Envía la señal al proceso pid»sigprocmask (oper, conj_señ, conj_señ_ant)«Bloquea temporalmente las señales»sigsuspend (conj_mascara)«Espera a que se produzca alguna de las señales que NO están en conj_mascara»

    MANEJO DE SEÑALES

    struct sigaction {void (*sa_handler) ();sigset_t sa_mask;int sa_flags;void (*sa_sigaction) (...);

    };

    18Maria Isabel Alfonso Galipienso. 2006

    Comunicación de procesosMANEJO DE SEÑALES. EJEMPLO

    #include void manejador (int señal) {

    printf (“Ojo! , se ha producido una excepción aritmética \n”);}

    main() {struct sigaction man; float a,b; int x;man.sa_flags = 0;man.sa_handler = manejador;sigemptyset(&man.sa_mask);

    sigaction(SIGFPE, &man, NULL);for (x=0; x

  • 10

    19Maria Isabel Alfonso Galipienso. 2006

    Comunicación de procesos

    Las colas de mensajes se identifican por nombre. No son ficheros. Tienen un tamaño máximo, que se establece al crearlas.Los mensajes se reciben en orden de prioridadEl envío y recepción es asíncrono, y puede ser bloqueante o no (cuando el buffer de mensajes esté lleno o vacío)cola mq_open (nombre,oflags, modo, atributos) → «crea/abre la cola»mq_close (cola) → «Informa al S.O. de que no se va a utilizar la cola»mq_unlink (cola) → «Se destruye la cola»mq_send (cola, mensaje, tam_msg, prio) → «Se envía un mensaje»mq_receive (cola, mensaje, tam_msg, prio) → «Recoge un mensaje»mq_setattr (cola, attr_new, attr_old) → «Modifica los atributos de la cola »

    MENSAJES

    20Maria Isabel Alfonso Galipienso. 2006

    Scheduling

    Posix define 3 políticas de planificaciónSCHED_FIFO

    «Orden fifo entre tareas de igual prioridad»SCHED_RR

    «Turno rotatorio entre tareas de igual prioridad»SCHED_OTHER

    «No especificado»

    Deben existir al menos 32 niveles de prioridad

  • 11

    21Maria Isabel Alfonso Galipienso. 2006

    Scheduling

    Se pueden utilizar las siguientes funciones:

    sched_setscheduler(pid, policy, param)

    sched_setparam(pid,param)

    int sched_get_priority_min (policy)

    int sched_get_priority_max (policy)

    sched_yield (void)

    22Maria Isabel Alfonso Galipienso. 2006

    Scheduling. Ejemplo

    #include struct sched_param param;main()

    printf(“RR min: % ld\n” ,sched_get_priority_min(SCHED_RR));printf(“RR max: % ld\n” ,sched_get_priority_max(SCHED_RR));printf(“FIFO min: % ld\n” ,sched_get_priority_min(SCHED_FIFO));printf(“FIFO max: % ld\n” ,sched_get_priority_max(SCHED_FIFO))param.sched_priority = 10;fork();sched_setscheduler(0,SCHED_FIFO, &param);haz_trabajo();

    }

  • 12

    23Maria Isabel Alfonso Galipienso. 2006

    Gestión de memoria

    Funciones que bloquean en memoria física RAM:mlock(address, length)→ «bloquea desde address con longitud length»munlock(address,length)→ «permite el intercambio a disco»mlockall (flags) → «bloquea todo el proceso»munlockall (void) → «deshace cualquier bloqueo anterior»

    #include main () {

    mlock(MCL_CURRENT⏐MCL_FUTURE);/*Ahora ni este proceso ni su descendencia

    podrán ser copiados en memoria secundaria */haz_trabajo();

    }

    EJEMPLO:

    24Maria Isabel Alfonso Galipienso. 2006

    Manejo del tiempoSe puede trabajar con una buena resolución de tiempo (entre 20 msegundos y 1 nanosegundo)clock_gettime (clock_id, tiempo_actual) → «valor del reloj del sistema»clock_getres (clock_id, resolución) → «granularidad de la implementación»nanosleep (duracion, tiempo_restante) → «suspende al proceso que la invoca»

    RELOJES

    #include main()

    struct timespec B, A;clock_gettime (CLOCK_REALTIME, &A);clock_gettime (CLOCK_REALTIME, &b);printf(“Dos llamadas consecutivas: %ld nseg\n”,

    1000000000L *(B.tv_sec–A.tv_sec) + (B.tv_nsec–A.tv_nsec)); }

    EJEMPLO

  • 13

    25Maria Isabel Alfonso Galipienso. 2006

    Manejo del tiempo

    Se utilizan para generar señales en momentos determinados, o de forma periódica.

    timer_create (clock_id, sig_spec, timer_new)

    timer_settime (timer_id, flags, new_interval, old_interval)

    timer_gettimer (timer_id, current_interval)

    timer_delete (timer_id)

    TEMPORIZADORES

    struct itimerspec {struct timerspec it_value;struct timespec it_interval;

    };

    26Maria Isabel Alfonso Galipienso. 2006

    Manejo del tiempoTEMPORIZADORES. EJEMPLO

    #include #include void manejador ( ) {

    struct timespec ahora;signal (SIGRTMIN,manejador);clock_gettime (CLOCK_REALTIME, &ahora);printf (“Instante ⇒ seg: %ld, nseg:

    %ld\n, B.tv_sec, B.tv_nsec);}main() {

    struct timespec B;struct itimerspec tempor_spec;timer_t tempor;struct sigevent evento;signal (SIGRTMIN,manejador);evento.sigev_signo = SIGRTMIN;evento.sigev_notify = SIGEV_SIGNAL;

    timer_create(CLOCK_REALTIME, &evento, &tempor));tempor_spec.it_value.tv_sec =5;tempor_spec.it_value.tv_nsec =0;tempor_spec.it_interval.tv_sec =1;tempor_spec.it_interval.tv_nsec =0;timer_settime(tempor,0,&tempor_spec,NULL);clock_gettime(CLOCK_REALTIME, &B);printf(“Instante ⇒ seg: %ld, nseg:

    %ld\n, B.tv_sec, B.tv_nsec);while (1) {

    sleep(100);}

    }

  • 14

    27Maria Isabel Alfonso Galipienso. 2006

    Indice

    Introducción

    Soporte de ejecución: POSIXExtensiones de tiempo real

    Threads

    RTLinux

    28Maria Isabel Alfonso Galipienso. 2006

    Threads

    Procesos “pesados”Cambio de contexto con coste excesivoElevado coste de creación y destrucción de procesosUso de multiprocesadores

    Procesos “ligeros” : hilos de ejecución (threads)Cada proceso POSIX puede definir varios hilos de ejecuciónLos hilos comparten un único espacio de direcciones del proceso

    POSIX 4.a (1003.1c)

  • 15

    29Maria Isabel Alfonso Galipienso. 2006

    Diferencias fork() - thread

    Reg

    istro

    s

    Identidad

    Recursos

    Pila

    Texto

    Datos

    Heap

    •••

    •••

    hacer_cosa ( )

    Registros

    main ( )

    hacer_otra_cosa ( )

    hacer_cosa ( )

    main ( )

    i, j, k

    i, j, khacer_otra_cosa ( )SP

    PC

    SPPC

    PIDUIDGID...

    r1r2

    Pila

    Trhead 2

    Trhe

    ad1

    Registros

    Identidad

    Recursos

    Pila

    Texto

    Datos

    Heap

    •••

    •••

    fork ( )

    Pila

    Texto

    Datos

    Heap

    Registros

    Identidad

    Recursos

    •••

    •••

    fork ( )

    Pila

    Texto

    Datos

    Heap

    Registros

    Identidad

    Recursos

    •••

    •••

    fork ( )

    PROCESO

    Proceso PADRE Proceso HIJO

    PROCESO con MULTIPLES HILOS

    30Maria Isabel Alfonso Galipienso. 2006

    Estructura pthread (I)typedef struct pthread {

    SYS_SIGJMP_BUF context; /* save area for context switch */SYS_SIGJMP_BUF body; /* save area for pthread_body */volatile int errno; /* thread-specific errno */char *stack_base; /* bottom of run-time stack */int state; /* thread state, -> pthread_asm.h */struct pthread *next[NUM_QUEUES]; /* links for queues */int num_timers; /* number of timers for thread */struct timeval interval; /* time left for SCHED_RR */struct p_siginfo sig_info[NNSIG]; /* info for user handlers */int sig; /* latest received signal */int code; /* latest received signal code */int osp, opc, obp; /* save area for old context sw */struct context_t *nscp; /* UNIX signal context (new sig) */struct context_t *scp; /* UNIX signal context (current) */struct pthread_queue joinq; /* queue to await termination */pthread_cond_t *cond; /* cond var. if in cond_wait */pthread_queue_t queue;/* primary queue thread is contained in */sigset_t mask; /* set of signals thread has masked out */sigset_t pending; /* set of signals pending on thread */

  • 16

    31Maria Isabel Alfonso Galipienso. 2006

    sigset_t sigwaitset; /* set of signals thread is waiting for */pthread_func_t func; /* actual function to call upon activation */any_t arg; /* argument list to above function */any_t result; /* return value of above function */any_t key[_POSIX_DATAKEYS_MAX]; /* thread specific data */cleanup_t cleanup_top; /* stack of cleanup handlers */pthread_attr_t attr; /* attributes */int base_prio; /* Base priority of thread */int max_ceiling_prio; /* Max of ceiling prio among locked mutexes */int new_prio; /* New Priority */int wait_on_select; /* more information in fds */int width; /* pertinent file desc. set width */int how_many; /* how many amoung 0 .. width -1 */fd_set readfds; /* read file descriptor set */fd_set writefds; /* write file descriptor set */fd_set exceptfds; /* except. file descriptor set */pthread_func_t timer_func; /* function to be called on timeout*/any_t timer_arg; /* arg of above function */struct timespec tp; /* wake-up time */int dummy; /* filler for stack alignment */

    } *pthread_t;

    Estructura pthread (II)

    32Maria Isabel Alfonso Galipienso. 2006

    Gestión de threads

    int pthread_attr_init (pthread_attr_t * attr); int pthread_attr_destroy (pthread_attr_t * attr); int pthread_attr_setstacksize (pthread_attr_t * attr, size_t stacksize); int pthread_attr_getstacksize (pthread_attr_t * attr, size_t * stacksize); int pthread_attr_setdetachstate (pthread_attr_t * attr, int * detachstate); int pthread_attr_getdetachstate (pthread_attr_t * attr);

    int pthread_create (pthread_t * thread, pthread_attr_t * attr, pthread_func_t func, any_t arg);

    int pthread_join (pthread_t thread, any_t * status);int pthread_detach (pthread_t * thread); int pthread_cancel (pthread_t * thread);void pthread_exit (any_t status); pthread_t pthread_self (void); int pthread_equal (pthread_t t1, pthread_t t2); int pthread_once (pthread_once_t * once_c, ....

  • 17

    33Maria Isabel Alfonso Galipienso. 2006

    #include /* Thread que escribe periódicamente en la pantalla */ void * periodic (void *arg) { int period; /*en segundos*/

    period = *((int *)arg); while (1) { printf("En el thread con periodo %d\n",period);

    sleep (period); }

    } /* Programa principal, que crea dos threads periódicos */ main () { pthread_t th1,th2; pthread_attr_t attr; int period1=2; int period2=3; /* Crear el objeto de atributos y poner el estado de devolución de recursos*/ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); pthread_create(&th1,&attr,periodic,&period1); pthread_create(&th2,&attr,periodic,&period2); ... }

    Ejemplo

    34Maria Isabel Alfonso Galipienso. 2006

    Sincronización

    mutex: acceso mutuo exclusivo a recursos compartidos

    int pthread_mutexattr_init (pthread_mutexattr_t * attr); int pthread_mutexattr_destroy (pthread_mutexattr_t * attr); int pthread_mutexattr_getpshared (pthread_mutexattr_t * attr, int * pshared); int pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, int pshared);

    int pthread_mutex_init (pthread_mutex_t * mutex, pthread_mutexattr_t * attr); int pthread_mutex_destroy (pthread_mutex_t * mutex); int pthread_mutex_lock (pthread_mutex_t * mutex); int pthread_mutex_trylock (pthread_mutex_t * mutex); int pthread_mutex_unlock (pthread_mutex_t * mutex);

    int pthread_mutexattr_setprio_ceiling (pthread_mutexattr_t * attr, int prio_ceiling); int pthread_mutexattr_getprio_ceiling (pthread_mutexattr_t attr);

    MUTEX

  • 18

    35Maria Isabel Alfonso Galipienso. 2006

    /* Fichero shared_object.c: Implementación del objeto */ #include #include #include "shared_object.h" shared_t object; pthread_mutex_t the_mutex; void sh_create (int prio_ceiling, const shared_t *initial_value) { pthread_mutexattr_t attr;

    pthread_mutexattr_init(&attr); pthread_mutexattr_setprotocol (&attr,PTHREAD_PRIO_PROTECT); pthread_mutexattr_setprioceiling (&attr,prio_ceiling); pthread_mutex_init(&the_mutex,&attr); object=*initial_value; pthread_mutexattr_destroy(&attr);

    }

    /* Fichero shared_object.h: Prototipo del objeto*/ typedef struct { ... } shared_t;

    void sh_create (int prio_ceiling, const shared_t *initial_value); /* sh_create debe terminar antes de que el objeto sea usado */ void sh_modify (const shared_t *new_value); void sh_read (shared_t *current_value);

    void sh_modify (const shared_t *new_value{ pthread_mutex_lock(&the_mutex); object=*new_value; pthread_mutex_unlock(&the_mutex);

    } void sh_read (shared_t *current_value) { pthread_mutex_lock(&the_mutex); *current_value=object; pthread_mutex_unlock(&the_mutex);

    }

    SincronizaciónMUTEX: EJEMPLO

    36Maria Isabel Alfonso Galipienso. 2006

    Sincronización

    int pthread_cond_init (pthread_cond_t * cond, pthread_condattr_t * attr); int pthread_cond_wait (pthread_cond_t * cond, pthread_mutex_t * mutex); int pthread_cond_signal (pthread_cond_t * cond);int pthread_cond_broadcast (pthread_cond_t * cond);int pthread_cond_destroy (pthread_cond_t * cond);int pthread_cond_timedwait (pthread_cond_t * cond,

    pthread_mutex_t * mutex, struct timespec * timeout);

    int pthread_condattr_init (pthread_condattr_t * attr); int pthread_condattr_destroy (pthread_condattr_t *attr); int pthread_condattr_getpshared (pthread_condattr_t *attr, int *pshared); int pthread_condattr_setpshared (pthread_condattr_t *attr, int pshared);

    VARIABLES CONDICIONALES

    Son objetos de sincronización que se usan para que un thread pueda suspenderse en espera de que otro thread lo reactiveSe usan siempre conjuntamente con un “mutex”

  • 19

    37Maria Isabel Alfonso Galipienso. 2006

    /* Fichero one_way_buffer.h: Prototipo del objeto*/ typedef struct { ... } buf_data_t;

    #define BUFFER_OK 0 #define BUFFER_FULL -1

    void buf_create (int prio_ceiling); /* buf_create debe completarse antes de que el objeto sea usado */

    int buf_insert (const buf_data_t *message); /* buf_insert retorna BUFFER_OK o BUFFER_FULL, y nunca se bloquea */

    void buf_extract (buf_data_t *message); /* buf_extract se bloquea si el buffer está vacío */

    EJEMPLOSincronización

    38Maria Isabel Alfonso Galipienso. 2006

    /* Fichero one_way_buffer.c: Implementación del objeto */ #include #include #include "buffer_queue.h" pthread_mutex_t the_mutex; pthread_cond_t the_condition; void buf_create (int prio_ceiling) {

    pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_setprotocol (&attr,PTHREAD_PRIO_PROTECT); pthread_mutexattr_setprioceiling (&attr,prio_ceiling); pthread_mutex_init(&the_mutex,&attr); pthread_mutexattr_destroy(&attr);

    /* Initialize the condition variable with default attributes */ pthread_cond_init(&the_condition,NULL);

    }

    /* Fichero buffer_queue.h: Prototipo del objeto*/ #include "one_way_buffer.h" #define MAX_DATA 100 void queue_insert (const buf_data_t *message);void queue_extract (buf_data_t *message); int queue_isfull (void); int queue_isempty (void);

    EJEMPLOSincronización

  • 20

    39Maria Isabel Alfonso Galipienso. 2006

    int buf_insert (const buf_data_t *message) { int ret_value;

    pthread_mutex_lock(&the_mutex); if (queue_isfull())

    ret_value=BUFFER_FULL; else {

    ret_value=BUFFER_OK; queue_insert(message); pthread_cond_signal(&the_condition);

    } pthread_mutex_unlock(&the_mutex); return (ret_value);

    }

    void buf_extract (buf_data_t *message) {

    pthread_mutex_lock(&the_mutex); while (queue_isempty())pthread_cond_wait(&the_condition,

    &the_mutex); queue_extract(message); pthread_mutex_unlock(&the_mutex);

    }

    EJEMPLOSincronización

    Maria Isabel Alfonso Galipienso. 2006

    Cada thread tiene su propia máscara de señales.Los manejadores de señales son compartidos por procesos y threads.

    int sigwait (sigset_t * set); int sigprocmask (int how, ...); int sigpending (sigset_t * set); int sigsuspend (const sigset_t * set); int pause (void); int sigaction (int sig.....);

    unsigned int alarm (unsigned int seconds); emite la SIGALARMunsigned int sleep (unsigned int seconds); suspende al thread un tiempoint raise (int sig); envia la señal sig al proceso en ejecuciónint pthread_kill (pthread_t thread, int sig); envia la señal sig al thread referenciado

    Señales

  • 21

    41Maria Isabel Alfonso Galipienso. 2006

    Scheduling

    SCHED_FIFO: Priority scheduling, FIFO for same priority, 32 prio. levelsSCHED_RR: Priority scheduling, RR for same priority, 32 prio. levelsSCHED_OTHER: Implementation definition

    SCHED_FIFO: Priority scheduling, FIFO for same priority, 32 prio. levelsSCHED_RR: Priority scheduling, RR for same priority, 32 prio. levelsSCHED_OTHER: Implementation definition

    void pthread__yield (any_t arg); int setprio (pid_t pid, int prio); int getprio (pid_t pid); int setscheduler (pid_t pid, int sched, int prio); int getscheduler (pid_t pid);

    42Maria Isabel Alfonso Galipienso. 2006

    #include #include /* Programa principal que crea dos threads periódicos */ main () { pthread_t th1,th2; pthread_attr_t attr; int period1=2; int period2=3; struct sched_param my_params; /* Crear el objeto de atributos y colocar cada atributo */

    pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED); pthread_attr_setschedpolicy(&attr,SCHED_FIFO); my_params.sched_priority= sched_get_priority_min(SCHED_FIFO); pthread_attr_setschedparams(&attr,&my_params);

    /* Crear los threads */ pthread_create(&th1,&attr,periodic,&period1); my_params.sched_priority= (sched_get_priority_min(SCHED_FIFO)+1); pthread_attr_setschedparams(&attr,&my_params); pthread_create(&th2,&attr,periodic,&period2);

    ... }

    Ejemplo

  • 22

    43Maria Isabel Alfonso Galipienso. 2006

    Indice

    Introducción

    Soporte de ejecución: POSIXExtensiones de tiempo real

    Threads

    RTLinux

    44Maria Isabel Alfonso Galipienso. 2006

    RT-Linux (I)

    RT-Linux es una extensión de Linux para la gestión de tareas de tiempo real.Fue desarrollado en el Institute of Technologyde la universidad de New Mexico por VictorYodaiken y Michael Barabanov.Solo disponible para la arquitectura IBM-PC.Permite tratar con:

    Tareas de tiempo real blandas (soft): Tareas de tiempo real estricto (hard):

  • 23

    45Maria Isabel Alfonso Galipienso. 2006

    RT-Linux (II)

    El propósito de RT-Linux es integrar dos propiedades incompatibles:

    Prestar un servicio "hard real-time": predecible, rápido, con una latencia de interrupción baja, con un planificador versátil,

    Todos los servicios del estándar de Posix: GUI, TCP/IP, NFS, compiladores, servidores-web,...

    En el mismo sistema operativo!

    46Maria Isabel Alfonso Galipienso. 2006

    Linux y las tareas de tiempo real

    Falta de predecibilidad del sistema motivada por:Planificación (scheduling) basada en asignación de "quántum" y prioridadesUso de memoria virtual con paginaciónResolución del reloj de tiempo bajaEl kernel del S.O. es no interrumpible

    El estándar POSIX.1b permite utilizar linux para tiempo real pero su uso queda limitado a las tareas de tiempo real blandas (soft)

    El kernel continua siendo no interrumpible

  • 24

    47Maria Isabel Alfonso Galipienso. 2006

    Estructura de RT-Linux (I)

    Implementa un núcleo reducido que solo ofrece los servicios básicos para tiempo realSobre el kernel de RT-Linux se ejecutan las tareas de tiempo real y el núcleo de LinuxEl núcleo de Linux tiene la prioridad más baja

    Linux ejecuta cuando no hay tareas de tiempo real que requieran la CPU

    El núcleo de RT-Linux es no interrumpibleEs fácil calcular el peor caso para un retardo producido por esta causa (núcleo reducido)

    48Maria Isabel Alfonso Galipienso. 2006

    Estructura de RT-Linux (II)

    Hardware

    RT-Linuxrt_sched

    Accesodirecto

    al hardware

    Linux se ejecuta en background.

    Hard intr

    RTTask

    RTTask

    RTTask

    Soft intr

    Planif basado en prioridades.

    Linux S.O.Llamadas al S.O.

    Scheduler

  • 25

    49Maria Isabel Alfonso Galipienso. 2006

    Codificación de RT-Linux

    Los componentes de tiempo real se codifican en módulos que se cargan en el núcleoLos módulos son programas “normales” que tienen las funciones: init_module, cleanup_moduleSólo el superusuario (root) puede cargar o descargar módulos# modprobe modulo# rmmod modulo# lsmodTienen acceso a todos los recursos del sistema, tanto hardware como software

    Un módulo NO es un fichero ejecutable, sino un fichero

    objeto “.o”,

    50Maria Isabel Alfonso Galipienso. 2006

    Servicios de RT-Linux

    Gestión de RT-tareas según un esquema de prioridades fijas:

    rtl_task_init rt_task_suspendrt_task_delete rt_task_waitrt_task_make_periodic rt_task_wakeup

    Asignación de manejadores de interrupción:rquest_RTint free_RTint

    Comunicación con aplicaciones Linux de usuario:rtf_create rtf_getrtf_destroy rtf_putrtf_create_handler rtf_resize

    Alta resolución de medida de tiempos: rt_get_time

  • 26

    51Maria Isabel Alfonso Galipienso. 2006

    Emulación de interrupciones (I)

    Ahora es el kernel de RT-Linux el que recibe las interrupciones hardware Instrucciones hardware para el acceso a las interrupciones en la familia Intel:

    cli ⇒ Inhabilita interrupcionessti ⇒ Habilita interrupcionesiret ⇒ retorno de una interrupción

    En el código del núcleo de Linux se sustituyen las llamadas a cli, sti e iret por las macros de emulación S_CLI, S_STI y S_IRET

    52Maria Isabel Alfonso Galipienso. 2006

    Emulación de interrupciones (II)

    Todas las interupciones pasan primero por el emulador.Cuando Linux inhabilita las interrupciones el emulador activa un flag.Cuando se presenta una interrupción dirigida a Linux:

    Si Linux las tiene habilitadas se invoca al manejador.Caso contrario, la interrupción se encola y es emulada cuando Linux vuelva a habilitarlasSi mientras se emulan interrupciones se presentan nuevas, su tratamiento deberá esperar hasta la próxima llamada a S_STI o S_IRET.

  • 27

    53Maria Isabel Alfonso Galipienso. 2006

    Planificación (scheduling)

    El planificador es un módulo que se carga dinámicamente en el sistemaVarias políticas de planificación:

    Basada en prioridades estáticasLa tarea más prioritaria es la que procesa

    Basada en el plazo de finalizaciónLa tarea cuyo deadline esté mas próximo es la que procesa

    Algoritmo RMEl usuario puede implementar su propio planificador

    54Maria Isabel Alfonso Galipienso. 2006

    El reloj de tiempo real

    Si tenemos un sistema con una granularidad de reloj grande, el release jitter es excesivamente alto.

    Para aumentar aumentar la precisión del reloj sin pérdida de eficiencia:

    Se reprograma el chip del reloj para que nos interrumpa bajo demanda, no a intervalos periódicosEl reloj interrumpe únicamente cuando realmente lo necesitamos, cuando una tarea deba activarse.

  • 28

    55Maria Isabel Alfonso Galipienso. 2006

    Tareas de tiempo real

    Las tareas de tiempo real se ejecutan en el mismo espacio de direcciones que el núcleo de LinuxSe ejecutan como los módulos del núcleo: pueden ser cargadas dinámicamenteNo pueden hacer llamadas al sistema convencionales ni usar memoria dinámica

    56Maria Isabel Alfonso Galipienso. 2006

    Comunicación entre tareas: RT-FIFOs (I)

    Las Real-Time FIFOs son un mecanismo de comunicación entre tareas de tiempo real y procesos convencionales de LinuxFuncionamiento similar al de los pipesSe garantiza que en ningún momento las tareas de tiempo real se quedarán bloqueadas al intentar leer o escribir sobre una rt-fifo.

    Si la lectura o escritura no se puede realizar las funciones devuelven un flag de errorSe evita el problema de la “inversión de prioridades”

  • 29

    57Maria Isabel Alfonso Galipienso. 2006

    Comunicación entre tareas: RT-FIFOs (II)

    Las tareas de tiempo real son las únicas que pueden crear y destruir rt_fifosLas RT-Fifos tienen un reflejo en el sistema de ficheros como dispositivos especiales

    /dev/rtf0/dev/rtf1

    Las tareas de tiempo real acceden a las RT-Fifo mediante llamadas especiales. Las RT-Fifo se identifican mediante un entero.Los procesos de Linux acceden con las llamadas convencionales para la lectura y escritura sobre ficheros.

    openreadwrite

    rtf_creatertf_destroyrtf_create_handlerrtf_getrtf_putrtf_resize

    # mknod /dev/rtf0 c 63 0# mknod /dev/rtf1 c 63 1# mknod /dev/rtf2 c 63 2

    58Maria Isabel Alfonso Galipienso. 2006

    Fifos vs. memoria compartida

    Los datos son encolados. No hay hecesidad de protocolospara preevenirsobreescriturasNo es necesario mantenerlos límites de los mensajesLos fifos son canales punto a punto

    Se define de forma estáticaun número máximo de fifos

    Los datos no se encolan. Se necesitan protocolos parapreevenir sobreescriturasNo se pueden escribir datosestructuradosPuede haber cualquiernúmero de tareascompartiendo memoria.La memoria física es el únicolímite

    FIFOS MEMORIA COMPARTIDA

  • 30

    59Maria Isabel Alfonso Galipienso. 2006

    Diseño de aplicaciones con RTLinux

    Las aplicaciones están formadas por dos partes:

    Una parte de tiempo real, que debe ser rápida, simple, y "pequeña"El resto se ejecutará en el espacio de direcciones de usuario

    Las tareas se comunican con las de tiemporeal a través de los fifos

    60Maria Isabel Alfonso Galipienso. 2006

    Ejemplo de estructura de TR

    User Process

    RT Fifo

    RT Fifo

    RT Process

    Peripheral Device

    Linux Kernel

    NetworkDisk

    X Windows

    Display

  • 31

    61Maria Isabel Alfonso Galipienso. 2006

    Instalación de RT-Linux

    Se instala como un parche (patch) sobre el código fuente de Linux (Linux 2.0.30)Se recompila el núcleo de linux:make dep; make clean; make zlilo; make modules; make modules_install

    Se re-arranca la máquinaEn este momento linux se comporta normalmente, hasta que no carguemos el planificador no tendremos un sistema de tiempo real# modprobe rt_prio_sched

    62Maria Isabel Alfonso Galipienso. 2006

    Ejecución de tareas de TR

    Para poder ejecutar tareas de TR tendremos que cargar el planificadorUna RT task se carga igual que cualquier módulo

    Linux S.O.Llamadas al S.O.

    Scheduler

    Hardwarert_prio_sched# modprobe rt_prio_sched

    rt_proceso

    # modprobe rt_proceso

    rt_prio_sched

  • 32

    63Maria Isabel Alfonso Galipienso. 2006

    Ejemplo tarea tiempo real#ifndef MODULE #define MODULE #endif #define __RT__ #define __KERNEL__ #define MODVERSIONS #include #include #include #include #include #include #include RT_TASK tasks[]; void fun(int computo) { int buc,x; while(1){ for (buc=0; buc

  • 33

    65Maria Isabel Alfonso Galipienso. 2006

    Ejemplo escritura rt_fifo (II)

    Compilar la tarea:gcc -I /usr/src/linux/include/linux -O2 -Wall -D_KERNEL_ -D_RT_ -c Rt-task.c

    Para ejecutar la tarea necesitamosCargar el planificador y el módulo de las rt_fifos

    # modprobe rt_prio_sched# modprobe rt_fifo_new

    Insertar el módulo en el kernel# insmod Rt-task.o

    También necesitamos un proceso Linux normal que abra el fichero /dev/rtf1 y lea de él

    lsmod -> muestra los módulosactualmente cargados en el núcleo

    rmmod -> descarga un módulo