next up previous contents
Next: Proceso V86: Up: El hilo Virtual V86 Previous: Creación del hilo en

Manejo de excepciones para el hilo V86.

Cuando el hilo virtual V86 genera una excepción, Mach suspende la ejecución de este hilo y notifica la excepción al puerto asociado para este propósito --en nuestro caso el proceso monitor contiene este puerto de excepción--. Cuando el proceso monitor recibe este mensaje primero verifica el tipo de excepción que se ha generado --las excepciones pueden ser de tipo aritmético, de protección o señales de hardware-- y dependiendo de esto se procede a hacer una simulación, si es de protección o de hardware, o una corrección de datos, si es aritmético. Cuando se ha atendido la excepción el proceso monitor notifica a Mach para que se reanude la ejecución del hilo virtual V86, como se muestra en la figura 6.1.
  
Figure 6.1: Manejo de excepciones del hilo V86.
\begin{figure}
\epsfxsize=240pt
\hspace{.1in}
\epsffile{excepDOS.eps}
\end{figure}

Para que el monitor pueda manejar las excepciones debe tener asociado un puerto de excepcion al hilo V86, y atender los mensajes que lleguen por este puerto, y después mandar a llamar al manejador de excepciones. Esto se realiza con el llamado exc_server e implantando el protocolo catch_exception_raise.

Una vez que el monitor ha creado el proceso V86 se queda en un ciclo esperando recibir algún mensaje de error por el puerto de excepción que asoció al hilo V86:

 port_t          port_ex; 
 struct msg { 
  msg_header_t   header; 
  char           data[64]; 
 }               i_msg, o_msg, *i, *o; 

 while(1) {
   i = &i_msg; o = &o_msg; 
   i_msg.header.msg_size = 64; 
   i_msg.header.msg_local_port = port_ex;  
   if((msg_receive( &(i_msg.header), MACH_RCV_MSG, 0))   
       r==RCV_SUCCESS) { 
        if (exc_server(&(i_msg.header), &(o_msg.header))) 
            msg_send( &(o_msg.header), MACH_SEND_MSG, 0); 
     }
  }
Con el llamado msg_receive el monitor espera un mensaje a través del puerto port_ex --el mensaje de entrada i_msg tiene asociado el puerto de excepción--. Una vez que recibe el mensaje, manda a ejecutar al manejador de excepciones del usuario (la implantación de catch_exception_raise). Y, finalmente, el ciclo se termina cuando le envía un mensaje al kernel, para informar que ha manejado la excepción.

El usuario tiene la opción de escribir su manejador de excepciones implantando el protocolo catch_exception_raise.

kern_return_t catch_exception_raise(port_t p, thread_t th, 
       task_t tk, int exception, int code, int subcode)
{
   i386_thread_state_t state; 
   kern_return_t error; 
   thread_get_state(th, i386_THREAD_STATE, &state, &state_count); 
   switch(exception) { 
   case EXC_BAD_INSTRUCTION:
        do_bad_instruction (&state); 
        break;
   case EXC_BREAKPOINT:
        do_breakpoint (&state);
        break;
   case EXC_BAD_ACCESS:
        do_bad_access(&state, subcode);
        break;
   case EXC_ARITHMETIC: 
        do_arithmetic (&state, code, subcode);
        break;
   }
Entonces el monitor puede ejecutar una función para cada tipo de excepción que se atrape.

El manejo de excepciones requiere que el proceso monitor realice operaciones de lectura y escritura a la tarea V86, esto se debe a que en la simulación de una instrucción es necesario conocer cual instrucción especial está generando la excepción --Mach notifica al monitor que ha ocurrido una excepción de protección, mas no le indica que instrucción lo ha ocasionado--, y dependiendo de esta instrucción, se procede a modificar el espacio de direcciones de la tarea V86 y el estado del hilo V86, tal y como lo haría el procesador si ejecutara la instrucción especial.

Para realizar estas operaciones se distinguen dos módulos principales en la aplicación: el proceso V86 y el monitor.



 
next up previous contents
Next: Proceso V86: Up: El hilo Virtual V86 Previous: Creación del hilo en
Amilcar Meneses
2002-10-03