Examen de SISTEMAS DE TIEMPO REAL Duración 90 minutos (con libros y apuntes) 5 de junio de 2002 NOMBRE: Pregunta 1 (1 punto) ¿Son bloqueantes las primitivas POSIX pthread mutex lock y pthread mutex unlock? Pregunta 2 (1 punto) ¿Es posible con la transferencia ası́ncrona de control de Ada y los temporizadores de POSIX detectar que el código de una tarea sobrepasa su peor caso de tiempo de cómputo (WCET)? ¿Qué mecanismo harı́a falta? Pregunta 3 (1 punto) Un sistema operativo dispone de un reloj formado por el registro contador de un temporizador hardware de 16 bits que se incrementa a una frecuencia de 216 Hz y una variable entera de 16 bits. Cada vez que el contador alcanza el valor máximo solicita una interrupción y reinicia la cuenta desde 0. El manejador de interrupción incrementa la variable entera. Calcule la resolución y el rango de los valores de tiempo para este sistema. Pregunta 4 (2 puntos) ¿Se pueden producir interbloqueos cuando se utiliza un protocolo de acceso a recursos de herencia del techo de prioridad? ¿Por qué? Pregunta 5 (2 puntos) Modifique el código del cuerpo de la tarea esporádica de la segunda práctica para que detecte el incuplimiento de su plazo de respuesta. ¿Habrı́a que modificar Interrupt Semaphore? Pregunta 6 (3 puntos) A continuación se muestra la codificación de un productor-consumidor con threads POSIX, sincronizados con un mutex y dos variables condicionales. Se pide: 1. Codificar las lı́neas 35 y 36 2. Explicar el comportamiento del programa 3. ¿En qué lı́neas y bajo qué circunstancias se bloquean los threads? #define MAX BUFFER 1024 /* tamaño del buffer */ #define DATOS A PRODUCIR 100000 /* datos a producir */ /* mutex para controlar el acceso al buffer compartido */ pthread mutex t mutex; pthread cond t no lleno; /* llenado del buffer */ /* vaciado del buffer */ pthread cond t no vacio; int n elementos; /* elementos en el buffer */ /* buffer común */ int buffer[MAX BUFFER]; 5 main(int argc, char *argv[ ]) 10 pthread t th1, th2; pthread mutex init(&mutex, NULL); pthread cond init(&no lleno, NULL); pthread cond init(&no vacio, NULL); 15 pthread create(&th1, NULL, Productor, NULL); pthread create(&th2, NULL, Consumidor, NULL); pthread join(th1, NULL); pthread join(th2, NULL); 20 pthread mutex destroy(&mutex); pthread cond destroy(&no lleno); pthread cond destroy(&no vacio); 25 exit (0); void Productor(void) /* código del productor */ int dato, i ,pos = 0; for(i=0; i DATOS A PRODUCIR; i++ ) dato = i; /* producir dato */ pthread mutex lock(&mutex); /* acceder al buffer */ /* si buffer lleno */ /* bloqueo */ buffer[pos] = dato; pos = (pos + 1) % MAX BUFFER; n elementos ++; pthread cond signal(&no vacio); /* buffer no vacı́o */ pthread mutex unlock(&mutex); 30 35 40 pthread exit(0); 45 void Consumidor(void) /* código del consumidor */ int dato, i ,pos = 0; for(i=0; i DATOS A PRODUCIR; i++ ) pthread mutex lock(&mutex); /* acceder al buffer */ while (n elementos == 0) /* si buffer vacı́o */ pthread cond wait(&no vacio, &mutex);/* bloqueo */ dato = buffer[pos]; pos = (pos + 1) % MAX BUFFER; n elementos ; pthread cond signal(&no lleno); /* buffer no lleno */ pthread mutex unlock(&mutex); printf("Consume %d \n", dato); /* consume dato */ 50 55 pthread exit(0); 60