sisoputnfrba / foro

Foro de consultas para el trabajo práctico
148 stars 7 forks source link

Sobre finalizar proceso en E/S #3777

Closed GonTurri closed 4 months ago

GonTurri commented 4 months ago

Buenas! ahora leyendo el issue #3772 me volvio a entrar la duda. Porque me habian dicho que no iban a mandarle finalizar proceso a un pid que este realizando alguna operacion de entrada salida, y aca dice que hay "esperar" a que termine???

Por favor si se puede aclarar un poco mas este caso lo agradeceria Desde ya muchas gracias

iago64 commented 4 months ago

Buenas!

En las pruebas no lo tenemos pensado, ahora nadie puede evitar que metas un dedaso y en lugar de matar el PID 4, mates el 5 que justo esta en una IO.

Saludos.-

GonTurri commented 4 months ago

Ok, entiendo tu punto pero implementar que se quede esperando a la io para mandarlo a exit no me parece nada trivial, si solo va a ocurrir como decis vos se me ocurre algo mas secillo que es: Cuando te llega el mensaje "termine" de la interfaz, que esta te mande el pid de la operacion correspondiente y que el kernel lo comparte con el primero de la cola, si son distintos hago un break y termine el handling de ese mensaje asumiendo que si paso eso es porque lo finalizaron desde consola. Ah y para que se entienda mejor, cuando le doy a finalizar proceso lo saco de una a la cola de bloqueados y lo mando a exit y despues la IO le manda el termine aparte si lo haces pausando la planificacion no tendria que haber conflictos de simultaneidad y eso Que opinas?

iago64 commented 4 months ago

Buenas! Cómo va?

¿No se te ocurre que capaz estas sobre diseñando la solución? A fines prácticos ¿Qué te cambia que el proceso "termine" en el medio de la ejecución de IO o que esperes al final? Si de todas formas la interfaz siguió ocupada durante el tiempo de la IO sin poder hacer otras cosas de los demas procesos encolados y dicho eso, no queremos que se rompan la cabeza haciendo algo para cortar la IO

Saludos.-

GonTurri commented 4 months ago

es que ese es el problema, yo lo finalizo desde la consola, yo no quiero que la consola se quede trabada esperando un evento que le corresponde a otro. Al menos en nuestra implementacion la consola y el "atendedor de interfaces" estan el hilos separados entonces ahi yo no quiero trabar a la consola. Entonces tengo que crear un hilo aparte y usar probablemente alguna solucion que incluya semaforos. Te muestro un poquito de codigo :

case IO_DONE:
        {
            t_interface_io_done_msg *msg = malloc(sizeof(t_interface_io_done_msg));
            interface_decode_io_done(packet->buffer, msg);
            log_info(logger, "Interface %s requested by pid %d done", msg->interface_name, msg->pid);
            handle_pause();
            scheduler.block_to_ready(this_blocked_queue, logger);
            sem_post(&scheduler.sem_ready);
            // print_ready_queue(logger);
            interface_destroy_io_done(msg);
            break;
        }

No te pido que lo entiendas todo pero basicamente cuando me llegue ese mensaje voy a hacer un pop de la cola de bloqueados, este hilo que si espera a que termine la interfaz es distinto al de la consola. Si se podrian comunicar de alguna forma, pero no se me ocurre nada sencillo sin complicarmela un monton como alguna lista compartida o algo asi. Espero se me este entendiendo

iago64 commented 4 months ago

Buenas! Cómo va?

Yo te hago una pregunta, si en lugar de complicarte tanto con semáforos, te agregas una variable que diga siguiente estado y en base a eso sepas que tenes que hacer cuando el proceso vuelve de IO? O Tener un flag de terminar que simule un poco el comportamiento de SIGTERM? Algo que tiene que ser la base de lo que hagan en el TP es que tiene que ser una solución lo más simple posible.

Saludos.-

GonTurri commented 4 months ago

Gracias por la respuesta otra vez, a ver si puedo pasar en limpio todo lo que me dijiste: Seria agregarle a mi tipo t_pcb un atributo (bool sigterm) el finalizar proceso le pone este flag en true para lo siguientes casos: 1) cuando esta bloqueado por E/S ,no asi por recursos, luego al hacer pop de bloqueados, preguntar if(pcb->sigterm) send_to_exit()

2) cuando esta ejecutando y justo se desalojo antes de que le llegue la interrupcion (alguna instruccion de E/S wait o signal) si hace exit no tiene mucho sentido. Igual estos casos me parecen medio peligrosos porque puede explotar todo si lo mato antes de hacer la logica de wait o signal. Me gustaria si se puede aclarar un poco estos casos borde. Entonces en mi dispatcher tambien haria el mismo if(pcb->sigterm) y lo mando a exit

Si ya estamos dando muchas vueltas lo podemos reveer en el soporte, pero bueno muchas gracias por ir respondiendo

iago64 commented 4 months ago

Buenas! Cómo va?

Me gusta que estemos empezando a poner las cosas mas en concreto y tranqui que mejor que todo quede escrito en el foro :)

El caso de bloqueo por E/S, esta perfecto como lo estas planteando.

Respecto al caso de la CPU y una salida para atender una syscall, es un caso borde, pero no se la compliquen tanto, manejenlo como cuando les llegan las interrupciones de fin de quantum, terminan de hacer el WAIT o el SIGNAL por el que fueron al kernel y despues en el check interrupt ven si tienen la interrupción y de ahi lo mandan de nuevo al Kernel para que este lo lleve amablemende a EXIT.

Saludos.-

GonTurri commented 4 months ago

Perdón una cosita más que no me cierra un poco, entonces si ponele mando a pid 1 y 2 a bloquearse por teclado, finalizó el pid 2. Entonces hasta yo no escriba 2 veces por teclado (el mismo) no va a finalizar pid 2? Me parece bastante delay pero sea como sea no hay problema en implementarlo

iago64 commented 4 months ago

Buenas!

Si vas a seguir preguntando no cierres el issue o en su defecto abrilo de nuevo porque si no le perdemos el rastreo y la duda muere en el olvido.

Lo que hablamos era para el caso donde el proceso que matamos estaba JUSTO ejecutando la IO, si tenes 2 procesos y matamos al segundo que esta bloqueado pero aun no esta usando la IO ahi si podrías matarlo de una, acordate que las interfaces atienden las peticiones de a 1.

Saludos.-

GonTurri commented 4 months ago

Perdón ! Lo quería reabrir y estaba desde el mobile y no encuentro el botón para reabrirlo Ya está entonces

GonTurri commented 4 months ago

Para, me vas a matar ya pero bueno, lo estuve pensando un poquito y al menos con nuestra implementacion no podemos hacer eso que decis, vuelve el mismo problema, este seria el codigo que se ejecuta en kernel cuando cpu hacer IO_GEN_SLEEP por ej:

 case IO_GEN_SLEEP:
    {
        handle_quantum();
        handle_pause();
        t_interface *interface = interface_middleware(packet->buffer, IO_GEN_SLEEP, pcb, logger);
        if (!interface)
            break;
        t_interface_io_gen_sleep_msg *msg = malloc(sizeof(t_interface_io_gen_sleep_msg));
        interface_decode_io_gen_sleep(packet->buffer, msg);
        interface_send_io_gen_sleep(interface->fd, pcb->context->pid, msg->work_units);
        interface_destroy_io_gen_sleep(msg);
        break;
    }

Lo imporatnte es ese

interface_send_io_gen_sleep()

Que va a hacer un send al fd de la interfaz correspondiente, es decir: 1) CPU me pide instruccion IO 2) push a cola bloqueados 3) send a la interfaz para que haga lo que tiene que hacer. Si, la interfaz atiende de a uno, si tiene mas de un mensaje va atendiendo por orden pero el mensaje ya quedo 4) interfaz me mando done, pop cola bloqueados

si hago lo que dijiste del caso que no es el primero de la cola el mensaje ya fue enviado y no se si hay alguna manera de cancelarlo. Entonces voy a tener un pop demas (por que ya lo saque a mano)

A menos que me digas que este send no iba aca y tengamos que rehacer todo el tp :( , no funcionaria bien eso que dijiste en nuestra implementacion

iago64 commented 4 months ago

Buenas!

Claro aca el problema es que dejaron el while de atender las peticiones del lado de la interfaz en lugar del lado del kernel, un poco que cambiaron las responsabilidades de cada uno, y si, se la van a complicar un poco mas.

Saludos.-

GonTurri commented 4 months ago

Ok! Me podrías aclarar un poco más cómo sería el funcionamiento correcto? así refactoreo todo por favor

iago64 commented 4 months ago

Buenas! Cómo va?

El problema está siendo que estas delegándole a la IO que tenga los N mensajes de las IO cuando vos como Kernel deberías ser el que le manda un proceso para IO y cuando te contesta que termino con le mandas el siguiente. Si lo queres ver, las IO deberían funcionar de manera parecida a la CPU, solo que siempre van por FIFO y cuando le mandas un proceso para hacer IO, no podes hacer nada con esa Interfaz hasta que te contesta que terminó, como con la CPU que cuando le mandas a ejecutar por FIFO, te quedas esperando a que te devuelva el Contexto de ejecución por algún motivo.

Saludos.-