1. Por qué un simulador de tiempo real
Los sistemas de tiempo real requieren garantías formales. Un simulador permite verificar si un conjunto de tareas cumple sus plazos antes de implementarlo en un sistema real. También permite experimentar con los parámetros para entender los límites de cada algoritmo.
Este simulador es el último del bloque 9 y cierra el estudio de la planificación en tiempo real. A partir del bloque 10, se baja a Linux.
2. Arquitectura
El simulador tiene las mismas partes que los anteriores, con dos algoritmos de tiempo real:
| Parte | Responsabilidad | Funciones |
|---|---|---|
| Modelo | Representar una tarea periódica. | crearTarea |
| Generador | Producir conjuntos de tareas reproducibles. | generarTareas |
| RM | Simular Rate Monotonic. | simularRM |
| EDF | Simular Earliest Deadline First. | simularEDF |
| Planificabilidad | Calcular utilización y límites. | planificabilidad |
| Vista | Dibujar Gantt y tabla. | dibujarGantt, renderTabla |
| Controlador | Leer controles, ejecutar, actualizar. | dibujar |
3. Simulación de RM
RM asigna prioridades estáticas por período. La simulación ejecuta las tareas por unidades de tiempo, eligiendo en cada instante la tarea lista con el período más corto:
function simularRM(tareas, horizonte) {
var restante = tareas.map(function (t) { return t.ejecucion; });
var proximaLlegada = tareas.map(function (t) { return 0; });
var plazo = tareas.map(function (t) { return t.periodo; });
var bloques = [];
var t = 0;
var orden = tareas.map(function (t, i) { return i; }).sort(function (a, b) {
return tareas[a].periodo - tareas[b].periodo;
});
while (t < horizonte) {
var elegida = -1;
for (var i = 0; i < orden.length; i++) {
var ti = orden[i];
if (restante[ti] > 0 && t >= proximaLlegada[ti] && t < plazo[ti]) {
elegida = ti;
break;
}
}
if (elegida === -1) {
t++;
for (var i = 0; i < tareas.length; i++) {
if (restante[i] <= 0 && t >= proximaLlegada[i] + tareas[i].periodo) {
proximaLlegada[i] += tareas[i].periodo;
plazo[i] = proximaLlegada[i] + tareas[i].periodo;
restante[i] = tareas[i].ejecucion;
}
}
continue;
}
bloques.push({ pid: tareas[elegida].id, inicio: t, fin: t + 1 });
restante[elegida]--;
t++;
for (var i = 0; i < tareas.length; i++) {
if (restante[i] <= 0 && t >= proximaLlegada[i] + tareas[i].periodo) {
proximaLlegada[i] += tareas[i].periodo;
plazo[i] = proximaLlegada[i] + tareas[i].periodo;
restante[i] = tareas[i].ejecucion;
}
}
}
return bloques;
}
4. Simulación de EDF
EDF asigna prioridades dinámicas por plazo. La simulación es similar a RM, pero en cada instante se elige la tarea con el plazo más cercano:
function simularEDF(tareas, horizonte) {
var restante = tareas.map(function (t) { return t.ejecucion; });
var proximaLlegada = tareas.map(function (t) { return 0; });
var plazo = tareas.map(function (t) { return t.periodo; });
var bloques = [];
var t = 0;
while (t < horizonte) {
var elegida = -1;
var minPlazo = Infinity;
for (var i = 0; i < tareas.length; i++) {
if (restante[i] > 0 && t >= proximaLlegada[i] && t < plazo[i]) {
if (plazo[i] < minPlazo) { minPlazo = plazo[i]; elegida = i; }
}
}
if (elegida === -1) {
t++;
for (var i = 0; i < tareas.length; i++) {
if (restante[i] <= 0 && t >= proximaLlegada[i] + tareas[i].periodo) {
proximaLlegada[i] += tareas[i].periodo;
plazo[i] = proximaLlegada[i] + tareas[i].periodo;
restante[i] = tareas[i].ejecucion;
}
}
continue;
}
bloques.push({ pid: tareas[elegida].id, inicio: t, fin: t + 1 });
restante[elegida]--;
t++;
for (var i = 0; i < tareas.length; i++) {
if (restante[i] <= 0 && t >= proximaLlegada[i] + tareas[i].periodo) {
proximaLlegada[i] += tareas[i].periodo;
plazo[i] = proximaLlegada[i] + tareas[i].periodo;
restante[i] = tareas[i].ejecucion;
}
}
}
return bloques;
}
5. Planificabilidad
El simulador calcula la planificabilidad de ambos algoritmos:
- Utilización total (U): suma de Ci/Pi.
- Límite de RM: n·(2^(1/n) − 1).
- Límite de EDF: 1,000.
Además, verifica si cada tarea cumple su plazo en la simulación: si en algún período la tarea no termina antes del plazo, se marca como «no cumple».
6. Gantt de ambas
El simulador muestra el Gantt de RM y de EDF uno encima del otro, para comparar cómo se ejecutan las tareas en cada algoritmo. Los bloques se comprimen (instancias consecutivas del mismo pid se fusionan) para que el Gantt sea legible.
7. Tabla de resultados
La tabla muestra, para cada tarea, su período, ejecución, utilización y si cumple el plazo con RM y con EDF:
function renderTabla(tareas, cumpleRM, cumpleEDF, filasEl, promEl) {
filasEl.innerHTML = '';
var U = 0;
tareas.forEach(function (t, i) {
var tr = document.createElement('tr');
[ 'τ' + t.id, t.periodo, t.ejecucion,
(t.ejecucion / t.periodo).toFixed(3),
cumpleRM[i] ? 'Sí' : 'No',
cumpleEDF[i] ? 'Sí' : 'No' ].forEach(function (v) {
var td = document.createElement('td');
td.textContent = v;
tr.appendChild(td);
});
filasEl.appendChild(tr);
U += t.ejecucion / t.periodo;
});
var n = tareas.length;
var limiteRM = n * (Math.pow(2, 1 / n) - 1);
promEl.textContent = 'U = ' + U.toFixed(3) +
' | Límite RM = ' + limiteRM.toFixed(3) +
' | Límite EDF = 1,000';
}
8. Los controles
Los controles permiten ajustar el conjunto de tareas:
- Tareas: número de tareas periódicas (2 a 5).
- Período base: período base (5 a 20). Los períodos se generan a partir de este valor.
- Ráfaga: tiempo de ejecución base (1 a 5).
- Semilla: semilla del generador pseudoaleatorio.
9. Simulador interactivo
Este simulador verifica si un conjunto de tareas cumple sus plazos con RM y con EDF. Cambia los parámetros y observa:
Simulador · tiempo real (RM y EDF)
Rate Monotonic
EDF
| Tarea | Período | Ejecución | Utilización | RM cumple? | EDF cumple? |
|---|---|---|---|---|---|
10. Verificación y casos de prueba
| Caso | Entrada | Resultado esperado |
|---|---|---|
| Baja utilización | 2 tareas, períodos 10, rafagas 2,2 | U = 0,4. Planificable por RM y EDF. |
| Alta utilización | 3 tareas, períodos 5,10,15, rafagas 2,3,4 | U = 0,97. Planificable por EDF, no garantizado por RM. |
| Sobrecarga | 2 tareas, períodos 5,5, rafagas 3,3 | U = 1,2. No planificable por ninguno. |
| Un proceso | 1 tarea, período 10, rafaga 5 | U = 0,5. Planificable por ambos. |
11. Resumen
- El simulador verifica si un conjunto de tareas cumple sus plazos con RM y EDF.
- Muestra el Gantt de ambas y la tabla de resultados.
- Calcula la utilización total y los límites de planificabilidad.
- RM tiene límite n·(2^(1/n) − 1); EDF tiene límite 1,000.
- Si U > 1, no es planificable por ningún algoritmo.
- El simulador es la culminación del bloque 9 (tiempo real).
12. Preguntas de repaso
Intenta responder cada una antes de abrir la respuesta.
1. ¿Qué verifica el simulador?
Si un conjunto de tareas periódicas cumple sus plazos con RM y con EDF.
2. ¿Qué muestra el Gantt?
La ejecución de las tareas en el tiempo, con RM y con EDF.
3. ¿Qué calcula la planificabilidad?
La utilización total y los límites de RM y EDF.
4. ¿Qué ocurre si U > 1?
No es planificable por ningún algoritmo.
5. ¿Qué ocurre si U ≤ límite RM?
Planificable por RM y por EDF.
6. ¿Qué ocurre si límite RM < U ≤ 1?
Planificable por EDF, no garantizado por RM.
7. ¿Cómo se comprime el Gantt?
Fusionando instancias consecutivas del mismo pid.
8. ¿Qué parámetros ajusta el simulador?
Número de tareas, período base, ráfaga base y semilla.
9. ¿Qué bloque del curso cierra este simulador?
El bloque 9 (planificación en tiempo real).
10. ¿Qué algoritmo admite más carga?
EDF (hasta U = 1,000).
Para practicar
- Ejecuta el simulador con U < 0,7 y verifica que ambos cumplen.
- Aumenta la ráfaga hasta que U > 1 y observa el fallo.
- Encuentra un caso donde RM falla pero EDF cumple.
- Modifica el simulador para mostrar el número de plazos incumplidos.
- Implementa la planificabilidad exacta (verificación por simulación, no solo por utilización).
- Investiga cómo SCHED_DEADLINE de Linux verifica la planificabilidad.