Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sincronización entre la interrupción y el nuevo fetch #4395

Open
1 task done
nicolasizraelski opened this issue Nov 15, 2024 · 4 comments
Open
1 task done

Sincronización entre la interrupción y el nuevo fetch #4395

nicolasizraelski opened this issue Nov 15, 2024 · 4 comments

Comments

@nicolasizraelski
Copy link

🖋️ Descripción

Buenas! Con mi grupos nos encontramos con el siguiente problema. Cuando ejecutamos las pruebas, y se ejecuta la ultima instrucción (PROCESS_EXIT), el CPU:

  1. Se fija si hay interrupciones
  2. Busca la instruccion, recibe PROCESS_EXIT, hace el decode y execute, enviandole la syscall al kernel.
    En ese momento kernel desarrolla la rutina para atender dicha syscall y le envía una interrupción al cpu.
    El problema está en que en el momento en que el kernel ejecuta la rutina, y envía la interrupción, el CPU a veces comienza a realizar el fetch de la prox. instruccion, que no existe.

No estamos pudiendo resolver ese tema, ya que el cpu deberia esperar a ver si le llega una interrupcion antes de realizar el proximo fetch.

📚 Búsqueda en documentación/foros

No response

📄 Código relevante

No response

🐛 Cómo reproducir el error

No response

💻 Logs

Captura de pantalla 2024-11-14 205811

Adjunto captura de como se va desarrollando el programa. Como comportamiento esperado: El ultimo fetch no debería ejecutarse ya que se espera que la interrupción llegue antes.

📝 Normas del foro

  • Leí los lineamientos del foro
@RaniAgus
Copy link
Contributor

RaniAgus commented Nov 15, 2024

¡Buenas! Me detengo un segundo acá:

el cpu deberia esperar a ver si le llega una interrupcion

Esto no es cierto: el CPU no debe quedarse esperando a ver si le llega una interrupción, sino que debe chequear si mientras se encontraba en otra etapa del ciclo de instrucción (fetch, decode, execute...) le llegó una interrupción.

Un ejemplo de esto es la interrupción por fin de quantum: el CPU recibe la interrupción inmedatamente marcando un flag de interrupción, y luego cuando se llegue a la etapa de check interrupt verifica dicho flag.

Dicho esto, el PROCESS_EXIT de Kernel no causa el envío de una interrupción a CPU, porque justamente el Kernel ya tiene el control al momento de invocarse la syscall. Simplemente debe atender la syscall y replanificar:

File_001

En cambio, si Kernel debe atender cualquier otra syscall que no implique replanificar (ejemplo: MUTEX_UNLOCK), ahí sí el CPU debe primero chequear si hubo una interrupción y, de haberla, desalojar:

File_000

En cuanto a su consulta sobre "¿por qué nuestro CPU termina ejecutando una instrucción de más?", la verdad es que depende muchísimo de cómo hayan implementado su solución; y con solamente observar los logs de CPU no podemos decirles mucho.

Algún diagrama de secuencia como los que les mostré arriba (o un pseudocódigo similar a los que se ven en los ejercicios de plani) nos serviría de mucha más ayuda para entender la interacción entre Kernel y CPU en su TP.

Saludos

@nicolasizraelski
Copy link
Author

nicolasizraelski commented Nov 15, 2024

Buenas! Primero que nada muchisimas gracias por tomarse el tiempo de contestar, nos sirve mucho para ir aclarando el panorama.
Entiendo que cuando CPU tiene que ejecutar una syscall, debe enviarsela al kernel. Pero, en este momento, debería romper el ciclo de instrucción? Es decir, luego del check_interrupt, tener un break y no hacer un fetch hasta que el kernel le envie un nuevo dispatch?

Nuestro codigo esta estructurado de la siguiente manera:

El CPU recibe un dispatch del kernel, solicita el contexto a memoria, y ejecuta el siguiente ciclo de instruccion:

void iniciar_ciclo_instruccion() {
    int seguir = true;

    while (seguir) {
        fetch(); //pide la instruccion a mem

        decode(); 

        execute(); //ejecuta sobre el contexto de ejecucion, o le envia a kernel en caso de ser una syscall        *1

        if (check_interrupt()) { // Si en el hilo dedicado a atender el kernel_interrupt llego una interrupcion, devuelve el contexto y 
                                            // le avisa a kernel de la interrupcion. Devuelve true si hubo interrupcion.
            break;
        }

        liberar_instruccion(); // Libera memoria
    }
}
  • 1 . Mi duda es, aca yo debería marcar algun flag para romper el ciclo luego de interrupt si lo que ejecute fue una syscalll?

@iago64
Copy link
Contributor

iago64 commented Nov 15, 2024

Buenas! Cómo va?

Ahi tienen varias estrategias para resolver el problema.
Una posible implementación es romper el ciclo y arrancar desde el fetch cuando reciban el contexto de ejecución de nuevo, ya que uds al desalojar para que el Kernel "ejecute" la syscall, medio que rompieron el ciclo por su cuenta.
Otra opción es esperar una respuesta del kernel al pedido de syscall y que el mismo les diga que el proceso se tiene que bloquear y por lo tanto lo desalojan.

Busquen lo que les quede mas "simple" de implementar con respecto a como tienen la implementación en su código del kernel tambien.

Saludos.-

@nicolasizraelski
Copy link
Author

Okey perfecto. Muchas graicas!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants