tema 4dccia.ua.es/dccia/inf/asignaturas/str/temario/tema4.pdfcontenido accediendo a posiciones de...
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, ¶m);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