#include "routix/system.h"
#include <routix/paging.h>
#include "sys/list.h"
#include <sys/types.h>
#include <signal.h>
#include "routix/file.h"
Go to the source code of this file.
|
Definition at line 266 of file task.h. Referenced by cache_read(), sys_exec(), sys_execve(), sys_usleep(), sys_waitpid(), and tarea_init(). |
|
|
|
Definition at line 288 of file task.h. Referenced by exec_sigpending(), sys_fork(), sys_signal_check(), and sys_signal_correct(). |
|
Definition at line 127 of file task.h. Referenced by init_MM_base(). |
|
|
|
Definition at line 131 of file task.h. Referenced by sys_malloc_page(). |
|
|
|
Definition at line 238 of file task.h. Referenced by sys_malloc_page(). |
|
Definition at line 236 of file task.h. Referenced by sys_exec(), and sys_execve(). |
|
Definition at line 235 of file task.h. Referenced by sys_exec(), and sys_execve(). |
|
Definition at line 237 of file task.h. Referenced by sys_exec(), and sys_execve(). |
|
|
|
|
|
|
|
|
|
|
|
Definition at line 271 of file task.h. Referenced by sys_exec(), sys_execve(), and sys_malloc_page(). |
|
|
|
|
|
|
|
Definition at line 226 of file task.h. Referenced by sys_exec(), sys_execve(), and sys_fork(). |
|
Definition at line 215 of file task.h. Referenced by sys_proc_dump_v(), sys_waitpid(), and timer_dump(). |
|
Definition at line 225 of file task.h. Referenced by sys_get_ppid(), and sys_waitpid(). |
|
|
|
Definition at line 153 of file task.h. Referenced by exec_sigpending(), sys_exec(), and sys_execve(). |
|
Definition at line 152 of file task.h. Referenced by exec_sigpending(), sys_proc_dump(), sys_signal_check(), and sys_sigprocmask(). |
|
Definition at line 154 of file task.h. Referenced by sys_sigaction(). |
|
Definition at line 166 of file task.h. Referenced by _sys_kill(), and check_sigpending(). |
|
|
|
Definition at line 155 of file task.h. Referenced by _sys_kill(), exec_sigpending(), and sys_signal(). |
|
Definition at line 156 of file task.h. Referenced by exec_sigpending(). |
|
Definition at line 150 of file task.h. Referenced by sys_exec(), sys_execve(), and sys_fork(). |
|
Value: TASK_SIGNALS(task) = (struct task_signals *) \ malloc(sizeof(struct task_signals)); \ task_signals_alloc++; Definition at line 159 of file task.h. Referenced by sys_exec(), sys_execve(), and sys_fork(). |
|
Value: free(TASK_SIGNALS(task)); \ task_signals_free++; Definition at line 162 of file task.h. Referenced by sys_exit_mm(). |
|
|
|
Definition at line 151 of file task.h. Referenced by _sys_kill(), check_sigpending(), and sys_proc_dump(). |
|
Definition at line 272 of file task.h. Referenced by sys_exec(), and sys_execve(). |
|
|
|
|
|
Definition at line 217 of file task.h. Referenced by sys_waitpid(). |
|
Definition at line 270 of file task.h. Referenced by sys_exec(), sys_execve(), and sys_exit_mm(). |
|
|
|
|
|
|
|
|
|
Definition at line 147 of file task.c. Referenced by actualizar_eventos(), cache_read(), despertar(), endrequest(), start_scheduler(), sys_exec(), sys_execve(), and sys_fork(). |
|
Definition at line 128 of file task.c. Referenced by cache_read(), sys_renice(), and sys_usleep(). |
|
Definition at line 298 of file task.c. Referenced by sys_kill(), sys_proc_dump_v(), sys_renice(), and tarea_init(). |
|
Definition at line 111 of file task.c. Referenced by sys_exec(), sys_execve(), and sys_fork(). |
|
Definition at line 19 of file task.c. Referenced by start_scheduler(). |
|
Definition at line 186 of file task.c. Referenced by start_scheduler(), sys_exec(), sys_execve(), and sys_fork(). |
|
Definition at line 267 of file task.c. Referenced by init_new_task(). |
|
Saca a un proceso de la lista de procesos del scheduler Definition at line 325 of file task.c. Referenced by sys_exec(), sys_execve(), and sys_waitpid(). |
|
|
|
Definition at line 313 of file task.c. Referenced by sys_exec(), and sys_execve(). |
|
Definition at line 175 of file task.c. Referenced by sys_exit_notify(). |
|
|
Definition at line 147 of file task.h. Referenced by open(), and sys_show(). |
|
Definition at line 147 of file task.h. Referenced by close(), sys_exit_fs(), and sys_show(). |
|
Definition at line 230 of file task.h. Referenced by _sys_kill(), sleep_init(), start_scheduler(), sys_exit_notify(), tarea_init(), and wakeup_init(). |
|
|
|
|
|
Cantidad de frees desde la última llamada a "clear alloc".
Definition at line 292 of file task.h. Referenced by fat_file_find(), free(), open_FAT12(), and sys_show(). |
|
Cantidad de mallocs realizados desde la última llamada a "clear alloc".
Definition at line 292 of file task.h. Referenced by fat_file_find(), malloc(), open_FAT12(), and sys_show(). |
|
Definition at line 230 of file task.h. Referenced by check_sigpending(), start_scheduler(), sys_exec(), and sys_execve(). |
|
Definition at line 122 of file task.h. Referenced by despertar_task(), dormir_task(), exec(), execve(), and remover_task(). |
|
Definition at line 252 of file task.h. Referenced by encontrar_proceso_por_pid(), insertar_tarea(), ps(), remover_task(), scheduler(), start_scheduler(), sys_proc_dump(), and tarea_init(). |
|
8-May-2004 Giro de 90º en la implementación base de señales. Por cuestiones de concurrencia, y un análisis "profundo" del impacto que tienen recibir una señal mientras se procesa un handler de otra, decidí sobre la marcha cambiar la implementación. Lo que haré será lo siguiente: El check_sigpending irá verificando si hay señales pendientes. Suponiendo que haya más de una, lo que se hará será lo siguiente. Para el primer handler se pondrá su dirección en el EIP del contexto de la tarea, y se pusheará al fondo del stack la dirección de un wrapper (creado por execve) el cuál me restaura los registros usados por la tarea, y luego hará un ret (para lo cual tuve que haber puesto el EIP del contexto al fondo del stack). Para las demás señales pendientes que haya detectado check_sigpending, se pusheará su dirección en el stack, con lo que primero se ejecutará la primera señal pendiente detectada, al finalizar está se iran sacando sistemáticamente del stack las direcciones de los handlers de la última a hacia la segunda pendiente. Es decir, si al momento de schedulear tengo pendientes las señales 1,2,3 y 10 primero se ejecutará la 1, luego la 10, la 3 y finalmente la 2. 9-May-2004 La gata flora se apodera de mi :-) Luego de haber implementado el sistema comentado anteriormente, me he dado cuenta que no funciona (al menos no como lo implementé). Cuál es el problema ? Todos los handlers logran ejecutarse con continuidad sin que el kernel se entere. Si bien esto es altamente performante :-), no me permite ir variando la máscara de señales ( task->sigmask ) la cual me dice que señales debo ignorar mientras estoy en el handler actual. Asi que, anulo esta implementación y vuelvo a algo muy cercano a la implementación original. En primer lugar: la función check_sigpending recibe como parámetro un flag, el cuál indica si debe o no guardar el contexto de la tarea. Esto creo lo explique en reiteradas oportunidades, pero en pos de aumentar la posibilidad de comprensión, lo volveré a explicar. Sólo debo guardar el contexto de la tarea en dos ocasiones: 1) Si tengo que interrumpir la ejecución de la tarea para ejecutar un handler. 2) Si debo interrumpir la interrupción de un handler para ejecutar otro handler (siempre y cuando task->sigmask me lo permita). En que caso no debo guardar el contexto ? Supongamos que estaba ejecutando la tarea, y recibo dos señales: guardo el contexto y ejecuto un handler. Cuando retorno de ejecutar ese handler (vía INT sys_signal_check) puedo ejecutar el otro handler sin necesidad de guardar el contexto, lo cuál hice unos instantes antes. A continuación se detalla el wrapper que se ejcuta una vez terminado el handler (el cuál se carga en la llamada execve): *(ptr_exit+12) = 0xb8; // Codigo de operacion: "mov eax, " *(unsigned long *)(ptr_exit+13) = SYS_SIGNALS | SYS_SIGNAL_CHECK; *(ptr_exit+17) = 0xcd; // int *(ptr_exit+18) = 0x50; // 0x50 *(ptr_exit+19) = 0x5e; // pop esi // Con estos popeos recupero los registros de propósito general *(ptr_exit+20) = 0x5f; // pop edi // que fueron pusheados antes de ejecutar un handler de señal *(ptr_exit+21) = 0x5a; // pop edx *(ptr_exit+22) = 0x59; // pop ecx *(ptr_exit+23) = 0x5b; // pop ebx *(ptr_exit+24) = 0x58; // pop eax *(ptr_exit+25) = 0xc3; // retn new_task->sigcheck_addr = GET_OFFSET(ptr_exit + 12) + mem->vdir; Este wrapper se ubica en el segmento de datos de la tarea, y se guarda su dirección en task->sigcheck_addr. Esa dirección se pone en el stack de la tarea, como dirección de retorno del handler :-) 12-May-2004 Ya tenemos la base del sistema de posteo y entrega (post & deliver) de señales. Es el momento de hablar de la implementación de las máscaras de señal. Vamos a tener dos tipos de máscaras: la primera seteada mediante la llamada al sistema sigprocmask, la cuál indica a que señales debemos inhibir mientras ejecutamos código de la tarea; mientras que el segundo tipo será la máscara definida mediante la llamada sigaction la cuál nos dice que señales debo "ignorar" mientras ejecuto el handler de una señal en particular. Vale aclarar que el término "ignorar" no es del todo correcto, ya que según POSIX, cuando se IGNORA una señal, se la descarta (definiendo como handler de la señal a SIG_IGN). Que pasa entonces cuando yo pongo una máscara de señal que inhiba a la señal SIGCHLD, por ejemplo ? Cuando se reciba esa señal, se la va a marcar como pendiente (post), pero su handler se ejecutará (deliver) recién cuando se "desinhiba" de la máscara. A continuación voy a intentar dar una idea de como será la implementación. La forma real de entenderla es estudiando el código (y sí, no hay otra). Se ejecuta check_sigpending, para ver si hay señales pendientes, cuando se encuentra alguna, antes de preparar todo para ejecutar el handler, verifico si esa señal está inhibida mediante la máscara sigmask (que se encuentra en el task_struct de la tarea), usando la macro IS_MASKED. Obviamente la señal no se ejecuta mientras se encuentre inhibida. Ese valor sigmask, de donde sale ? Como ya aclaré anteriormente, puede ser seteado con la llamada sigprocmask o bien, es el valor sa_mask de la estructura sigaction, la cual se se define mediante la llamada sigaction. En esta primera aproximación, haremos lo siguiente. Cuando vamos a ejecutar un handler, pondremos como máscara (es decir en sigmask) al sa_mask de ese handler, y resguardaremos el valor que poseía sigmask en el mismo stack que vinimos manipulando (Si si, otra vez a meter mando en el stack...). Cuando se termine de ejecutar el handler, popearemos el valor del stack y lo regresaremos a sigmask. Para lograr esto tuvimos que modificar el código de sys_signal_check (sys_signal.c) y el de exec_sigpending (signal.c). Sencillamente pusheamos el valor de la máscara actual antes de pushear "signo" (el cuál es el parámetro que recibe el handler de señal). Luego, al retornar de la ejecución del handler, simplemente se popea la máscara. Realmente no mire como implementaron esto otros desarrolladores, pero me imagino que debe ser de una manera terriblemente similar. Me imagino esto ya que, al realizar testeos, encuentro que si utilizo sigprocmask desde un handler de señal, al salir del handler, esa nueva máscara que coloque la pierdo, es decir, se sobreescribe con la que se recupera del stack. Al ir a POSIX (particularmente sigprocmask) encuentro algo como esto: "When a thread's signal mask is changed in a signal-catching function that is installed by sigaction() the restoration of the signal mask on return from the signal-catching function overrides that change (see sigaction()).", lo que me indica que probablemente hallan almacenado las máscaras dentro de una pila. 22-May-2004 Es realmente problematico que no se encolen las señales, ya que si un proceso crea 10 hijos, y todos ellos terminan simultaneamente, varios quedarán en Zombies, ya que hay solo 1 bit disponible en task->sigpending. Se me ocurrió como forma fácil de solucionar esto, colocar en la estructura task_signal un entero por cada señal, en el cuál podemos almacenar la cantidad de señales de un tipo que hay. Cada vez que ejecutamos un handler, decrementamos ese valor. De este modo, no perdemos señales. Definition at line 144 of file task.h. Referenced by sys_show(). |
|
Definition at line 144 of file task.h. Referenced by sys_show(). |
|
Definition at line 121 of file task.h. Referenced by inicializarTss(), init_MM_base(), and start_scheduler(). |
|
Definition at line 146 of file task.h. Referenced by sys_show(), and umalloc_page(). |
|
Definition at line 146 of file task.h. Referenced by sys_show(), and ufree_page(). |