sisoputnfrba / foro

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

Kernel: Planificador de Largo Plazo y Conexiones con Memoria #4265

Closed fernandodanielmaqueda closed 4 weeks ago

fernandodanielmaqueda commented 1 month ago

Lenguaje

C

Descripción

¡Buenas! ¿Cómo va? En nuestro grupo en Kernel para la Planificación de Largo Plazo, planteamos tener dos hilos persistentes (o sea, que se mantienen durante toda la ejecución del programa), sobre los cuales nos fueron surgiendo algunas dudas más que nada en relación con lo de las conexiones efímeras con Memoria:

También tenemos algunas consultas más en relación con la finalización de procesos:

  1. Para confirmar: si sólo el TID 0 de un proceso finaliza (ya sea porque éste utiliza la syscall THREAD_EXIT ó porque otro hilo utiliza THREAD_CANCEL sobre él), y siguen habiendo otros hilos de ese mismo proceso, ¿se debería finalizar el proceso completo (mandar también el resto de hilos a EXIT) o no?
  2. Para contemplar un caso border (que ustedes seguramente nos aseguran que esta situación nunca se dará en los tests): si un hilo con TID distinto de 0 utiliza la syscall PROCESS_EXIT (cuyo efecto sólo se le permite al TID 0 según entiendo del enunciado), ¿qué debería hacerse? ¿Enviar sólo ese hilo a EXIT o ignorarse sin hacer nada?

📔 Citas del enunciado/videos

(...) [Kernel] realizará conexiones efímeras para interactuar con el módulo Memoria.

Para las conexiones con el módulo Memoria, el Kernel deberá crear una nueva conexión para cada petición que requiera hacerle a la Memoria.

Planificador de Largo Plazo El Kernel será el encargado de gestionar las peticiones a la memoria para la creación y eliminación de procesos e hilos. Creación de procesos Se tendrá una cola NEW que será administrada estrictamente por FIFO para la creación de procesos. Al llegar un nuevo proceso a esta cola y la misma esté vacía se enviará un pedido a Memoria para inicializar el mismo, si la respuesta es positiva se crea el TID 0 de ese proceso y se lo pasa al estado READY y se sigue la misma lógica con el proceso que sigue. Si la respuesta es negativa (ya que la Memoria no tiene espacio suficiente para inicializarlo) se deberá esperar la finalización de otro proceso para volver a intentar inicializarlo. Al llegar un proceso a esta cola y haya otros esperando, el mismo simplemente se encola. Finalización de procesos Al momento de finalizar un proceso, el Kernel deberá informar a la Memoria la finalización del mismo y luego de recibir la confirmación por parte de la Memoria deberá liberar su PCB asociado e intentar inicializar uno de los que estén esperando en estado NEW si los hubiere. Creación de hilos Para la creación de hilos, el Kernel deberá informar a la Memoria y luego ingresarlo directamente a la cola de READY correspondiente, según su nivel de prioridad. Finalización de hilos Al momento de finalizar un hilo, el Kernel deberá informar a la Memoria la finalización del mismo, liberar su TCB asociado y deberá mover al estado READY a todos los hilos que se encontraban bloqueados por ese TID. De esta manera, se desbloquean aquellos hilos bloqueados por THREAD_JOIN o por mutex tomados por el hilo finalizado (en caso que hubiera).

Syscalls Procesos Dentro de las syscalls que se pueden atender referidas a procesos, tendremos 2 instrucciones PROCESS_CREATE y PROCESS_EXIT. PROCESS_CREATE, esta syscall recibirá 3 parámetros de la CPU, el primero será el nombre del archivo de pseudocódigo que deberá ejecutar el proceso, el segundo parámetro es el tamaño del proceso en Memoria y el tercer parámetro es la prioridad del hilo main (TID 0). El Kernel creará un nuevo PCB y un TCB asociado con TID 0 y lo dejará en estado NEW. PROCESS_EXIT, esta syscall finalizará el PCB correspondiente al TCB que ejecutó la instrucción, enviando todos sus TCBs asociados a la cola de EXIT. Esta instrucción sólo será llamada por el TID 0 del proceso y le deberá indicar a la memoria la finalización de dicho proceso. Threads Las syscalls que puede atender el kernel referidas a threads son 4: THREAD_CREATE, THREAD_JOIN, THREAD_CANCEL y THREAD_EXIT. THREAD_CREATE, esta syscall recibirá como parámetro de la CPU el nombre del archivo de pseudocódigo que deberá ejecutar el hilo a crear y su prioridad. Al momento de crear el nuevo hilo, deberá generar el nuevo TCB con un TID autoincremental y poner al mismo en el estado READY. ... THREAD_EXIT, esta syscall finaliza al hilo que lo invocó, pasando el mismo al estado EXIT. Se deberá indicar a la Memoria la finalización de dicho hilo.

💭 Soluciones posibles

Se nos ocurrieron varias soluciones posible para cada una, pero quisiéramos confirmar qué es lo esperado.

📝 Normas del foro

f-and commented 4 weeks ago

Buenas Fernando!

I. a. Si, porque como decís generarías condiciones de carrera si mandas solicitudes concurrentemente. I. b. Esto quedaría más a criterio del equipo ya que son decisiones de código que no afectan los logs obligatorios. Lo que no les recomendaría es en hacerse líos con hilos extra. II. a. Se podría hacer de forma concurrente, ya que ahora sí no habría condición de carrera entre los hilos por liberar memoria. II. b. Para hacertelo simple, no es algo que vayamos a probar y de paso metiendome a las consultas de liberación de procesos, ninguno de los casos se probaría por lo que no me enroscaría mucho con esa parte de la implementación ;)

Saludos.

fernandodanielmaqueda commented 4 weeks ago

¡Buenas Fede!

Gracias por tu respuesta.

Por cómo está redactado, uno podría entender que a lo que se refiere es a) crear ahí la estructura correspondiente al TCB (con TID 0) o b) enviarle la solicitud a Memoria (enviándole PID, TID 0 y el archivo de pseudocódiggo) para que cree el TID 0 del proceso en memoria.

Pero después también se establece:

PROCESS_CREATE, esta syscall recibirá 3 parámetros de la CPU, el primero será el nombre del archivo de pseudocódigo que deberá ejecutar el proceso, el segundo parámetro es el tamaño del proceso en Memoria y el tercer parámetro es la prioridad del hilo main (TID 0). El Kernel creará un nuevo PCB y un TCB asociado con TID 0 y lo dejará en estado NEW.

Aclarando que el TCB del proceso llegaría ya creado estando el PCB en NEW, la única posibilidad de las anteriores sería la b). Entonces lo que concluyo con todo eso es que a Memoria se le realizan dos solicitudes, una después de la otra: una para que cree el proceso (reservando una partición para el mismo), y la otra para que cree el hilo con TID 0 (abriendo el archivo de pseudocódigo e inicializando su contexto de ejecución). Por lo que de las 4 posibles soluciones que se nos ocurrieron en I) b., la 4- quedaría descartada, ¿correcto? De las tres restantes, nos quedaríamos con la 2- (aunque no sea lo mejor porque cerraríamos el socket anterior e inmediatamente volveríamos a abrir otro), si es que cumplimos con lo esperado.

Saludos.

f-and commented 4 weeks ago
  1. Si la opción 2 sería la más acertada porque cumplirías todos los criterios, y de paso ya modularizas las peticiones a simples funciones, para poder replicar la función luego con el THREAD_CREATE.
  2. Te diría que no te enrosques mucho con agregarle esa funcionalidad, es aceptable pero a su vez es muy poco probable que, no habiendo retraso en las interacciones entre Memoria y Kernel, se llame al THREAD_EXIT y haya suficiente tiempo como para que otro hilo pueda ponerse en EXEC, solicitar una instrucción de Memoria (donde si hay retraso), esperar a que devuelva THREAD_EXIT y volver a Kernel con esta syscall a ejecutar, como para que se ejecuten concurrentemente.
fernandodanielmaqueda commented 4 weeks ago

Perfecto, muchas gracias. Ahí quedó más claro. ¡Saludos!