SISTEMA OPERATIVO MH 1.5

Carlos Villarrubia
Luis Jimnez
Eduardo Domnguez

Escuela Universitria de Informtica
Universidad de Castilla - La Mancha
Ciudad Real, Espaa


1.- Introduccin
MH es un sistema operativo multihilo creado con fines docentes. Sus objetivos son ilustrar de 
la forma ms sencilla los conceptos tericos comunes en los sistemas operativos modernos 
con un ejemplo real. Por comodidad de desarrollo, MH necesita del sistema operativo MS-
DOS para su inicializacin. Una vez inicializado MS-DOS no se utiliza nunca e inclusive MH 
inhibe cualquier llamada a MS-DOS por parte de los hilos del sistema.

MH es un sistema monoproceso con capacidad para la gestin de varios hilos de ejecucin de 
ese proceso. 

Las llamadas al sistema estn divididas en dos grupos: Un grupo para la creacin, destruccin 
y gestin de hilos y otro grupo para la entrada/salida a travs de la consola del sistema.

El nico proceso del sistema corresponde a la imagen del programa init. A partir de este 
proceso se pueden crear hilos de ejecucin adicionales de este proceso. De forma adicional se 
tienen tres funciones para realizar entrada y salida por la consola del sistema.

2.- Arquitectura del sistema
El diseo de MH corresponde a un sistema operativo monoltico con una divisin en mdulos 
segn el objetivo de las variables y funciones del sistema.

El sistema esta dividido en los siguientes mdulos :

consola : Incluye todo el tratamiento y funciones para la lectura y escritura de caracteres por la 
consola del sistema.
hilos : Constituye la implementacin de la gestin de los hilos del sistema.
lista : Tiene funciones para la manipulacin de las diferentes listas de hilos.
memoria : Contiene el cdigo para la inicializacin y asignacin de memoria del sistema.
varios : Funciones de utilidad no especificas de MH.

Adicionalmente se tiene un mdulo (mh.c) con la inicializacin del sistema.

3.- Gestin de procesos
MH slo tiene un proceso (proceso init) con un hilo de ejecucin asociado y un espacio de 
memoria. Este proceso puede de forma dinmica crear y destruir hilos de ejecucin 
adicionales.

Un hilo de ejecucin tiene pocos recursos asociados de forma individual. Exactamente un hilo 
de ejecucin slo posee de forma individual una entrada en la tabla de hilos y una pila de 
tamao predeterminado.

La estructura de datos ms importante para la gestin de hilos es la tabla de hilos (extern 
THilo thTablaHilos[NUMMAXHILOS])cuyos elementos son del tipo THilo. La 
implementacin de la tabla de hilos se realiza con un array con un tamao mximo. La 
identificacin de cada hilo es a travs del indice del hilo en el array.

typedef struct {
   int estado;    /* Estado del hilo */
   int tipo;      /* Tipo de hilo: nucleo o usuario */
   int modo;      /* Modo de ejecucion: nucleo o usuario */
   unsigned ss;   /* Segmento de pila */
   unsigned isp;  /* Puntero inicial de pila */
   unsigned sp;   /* Puntero de pila en modo */
   int far *pmarca;  /* Puntero a la marca del segmento de pila 
*/
   TRegsPila far *pregs;   /* Puntero a la estructura inicial 
de registros */
   THiloFunc pfunc;  /* Puntero a la funcion de un hilo del 
nucleo */
   int arg; /* Argumento de la funcion de un hilo del nucleo */
   unsigned long diftick;  /* Diferencia de ticks para hilo 
dormido */
   int antid;  /* Indice del anterior hilo en la lista */
   int sigid;  /* Indice al hilo posterior en la lista */
} THilo;

A su vez tenemos otras variables tiles para la gestin de hilos como int nHiloActual 
que indica el hilo actual en ejecucin e int hHiloAnterior que indica el anterior hilo en 
ejecucin.

MH utiliza dos clases de hilos de ejecucin : hilos del ncleo e hilos de usuario. La nica 
diferencia entre ellos es que un hilo del ncleo utiliza el espacio de direcciones de memoria 
del ncleo y un hilo de usuario el espacio de direcciones de memoria del proceso del usuario 
(init).

Los estados de los hilos son : EJECUCION, LISTO, DORMIDO y BLOQUEADO.

Un hilo slo puede estar en una lista, por lo tanto, los campos antid y sigid indica el antecesor 
y sucesor.

Todo el estado de un hilo no se guarda en su estructura de la tabla de hilos. Cuando un hilo 
esta en un estado diferente a ejecucin el contenido de los registros del procesador excepto SS 
y SP se guarda en la cima de la pila. A tal efecto se utiliza la definicin de funciones de 
manejo de interrupciones del compilador. De tal forma que una declaracin del tipo :

void interrupt manejador(void)tiene un inicio y fin con la 
siguiente secuencia de instrucciones mquina.

push  ax
push  bx
push  cx
push  dx
push  es
push  ds
push  si
push  di
push  bp

teniendo en cuenta que cuando se produce una interrupcin el procesador introduce el 
contenido de los registro de flags, CS e IP en la pila antes del inicio del manejador de 
interrupcin tenemos la siguiente situacin de la pila antes de la ejecucin del manejador.


Cima de la pila 	BP
DI
SI
DS
ES
DX
CX
BX
AX
IP
CS
FLAGS

cuando acaba la funcin de manejo de la interrupcin el compilador introduce las siguientes 
instrucciones mquina para recuperar el contexto de ejecucin del hilo.

pop   bp
pop   di
pop   si
pop   ds
pop   es
pop   dx
pop   cx
pop   bx
pop   ax
iret

donde iret recupera los valores de los registro IP, CS y FLAGS de la pila.

Con este esquema la conmutacin de contexto entre dos hilos se realiza de forma automtica 
por las funcines definidas como manejadores de interrupciones donde en su cuerpo se cambia 
los valores de control de la pila del procesador (SS y SP).

void interrupt ConmutarContexto(void)
{
   thTablaHilos[nHiloAnterior].sp = _SP;
   _SS = thTablaHilos[nHiloActual].ss;
   _SP = thTablaHilos[nHiloActual].sp;
}

La manipulacin del contexto de ejecucin de un proceso se realiza a travs del campo 
estructura pregs de su entrada a la tabla de hilos que apunta a la cima de la pila que tiene 
tantos campos como registros el procesador excepto SS y SP. Estos campos son 
particularmente importantes en la inicializacin de los hilos.

La planificacin de los hilos se realiza en la funcin void Planificador(void)donde 
se manipula la lista de hilos en estado de preparados para ejecucin Tlista 
tlHilosPreparados y se actualiza el valor de las variables nHiloActual y 
nHiloAnterior. La planificacin puede ser preventiva o no en funcin de la variable 
bPreventivo. Si esta variable tiene un valor distinto de 0 el manejador del reloj expulsara 
del procesador a este hilo cuando haya consumido TICKSQUANTUM ticks consecutivos de 
reloj. El nmero de ticks de reloj por segundo se define en la inicializacin con la variable 
lHZReloj que puede tener un valor mnimo de 19 ticks/segundo y un valor mximo de 
1.193.180 ticks/segundo aunque el lmite real estar en funcin de la velocidad del procesador 
del sistema (tpicamente a un mximo de 100.000 ticks/segundo en un sistema Pentium 133).

4.- Gestin de memoria
La gestin de memoria es muy simple. En la inicializacin calcula la memoria total del 
sistema y va asignando memoria para las pilas de todos los hilos posibles del sistema. No 
existe posibilidad en la versin actual de tener un manejo de memoria dinmico.
Cada hilo tiene una pila con un tamao predeterminado que se asigna en la inicializacin. Al 
fin de cada pila existe una marca con un valor predefinido que se compara peridicamente 
para detectar si ese hilo ha utilizado ms zona de pila.

5.- Gestin de entrada/salida
Los nicos dispositivos perifricos utilizados por MH corresponde al teclado y la pantalla 
asociado al computador. A este par de dispositivos se les menciona como consola del sistema. 
La utilizacin de la pantalla se simple pues es un dispositivo direccionable por posiciones de 
memoria. En la inicializacin el sistema reconoce el modo grfico de la tarjeta 
(monocromtico o color) que es utilizado posteriormente.
El teclado de la consola es el nico dispositivo que puede dejar a un hilo en estado de 
BLOQUEADO. Esto es debido a que es posible no tener ningn carcter en el buffer de 
lectura del teclado.

6.- Creacin de programas para MH
El compilador utilizado para el sistema operativo MH y sus programas de aplicacin ha sido 
Borland C++ 3.1. Este entorno de programacin por defecto genera aplicaciones para el 
sistema operativo MS-DOS. En el caso del desarrollo del programa init se tienen que utilizar 
los prlogos y eplogos de MH y no de MS-DOS. Este se realiza enlazando el modulo 
ccom.obj a los archivos objetos del programa init. Adicionalmente se necesita el archivo 
objeto sistema.o y el archivo de cabecera sistema.h para realizar las llamadas al sistema 
operativo MH.

A tal efecto se utiliza un archivo por lotes ccom.bat en el directorio init que automatiza estas 
tareas incluyendo la inclusin de la cabecera con los tamaos de las distintas regiones del 
programa (cdigo, datos y pila). A tal efecto se debe consultar el archivo init.map para saber 
el tamao de estas reas.


Todas las llamadas al sistema se realizan a travs de la interrupcin 134 y los argumentos de 
las llamadas se pasan a travs de los registros del procesador. Para facilitar la programacin 
con MH se tiene un archivo sistema.c que realiza estas operaciones y ofrece un entorno de 
programacin en base a funciones C. Las diferentes llamadas al sistema con su interfaz en C 
son :

Gestin de hilos :
int MHNuevoHilo(pHiloFunc pHFuncion, int nArg, unsigned 
uiPrologo);
int MHTerminarHilo(int IdHilo);
int MHFinHilo(void);
int MHDormirHilo(unsigned long NumTicks);

Gestin de la consola :
char MHLeerCaracter(void);
int MHEscribirCadena(const char far *c);
int MHEscribirCaracter(char c);

Un ejemplo de proceso init con la creacin de tres hilos de ejecucin que imprimen 
concurrentemente tres caracteres diferentes sera :

#include "sistema.h"

void Hilo(int narg)
{
	int i;

	for (i=0 ; i<300; i++) MHEscribirCaracter('A' + narg);
}

void main(void)
{
	MHNuevoHilo(Hilo, 0);
	MHNuevoHilo(Hilo, 1);
	MHNuevoHilo(Hilo, 2);
}

Como se puede observar, se utiliza la funcin de creacin de hilos MHNuevoHilo con un 
argumento menos que en la llamada al sistema anloga. Esto es debida a que el entorno de 
desarrollo para MH proporciona un prologo comn para todos los hijos de ejecucin y no es 
necesario especificarlo.
