Manual de Programacion OS
Manual de Programacion OS
Condiciones de distribucin
El presente manual se distribuye Reconocimiento-CompartirIgual 2.5. Bajo estas licencias, usted es libre de: copiar, distribuir y comunicar pblicamente la obra hacer obras derivadas hacer un uso comercial de esta obra Bajo las condiciones siguientes: Reconocimiento. Debe reconocer los crditos de la obra de la manera especificada por el autor o el licenciador. Compartir bajo la misma licencia. Si altera o transforma esta obra, o genera una obra derivada, slo puede distribuir la obra generada bajo una licencia idntica a sta. Al reutilizar o distribuir la obra, tiene que dejar bien claro los trminos de la licencia de esta obra, y puede redistribuirla bajo cualquiera de las dos licencias. Alguna de estas condiciones puede no aplicarse si se obtiene el permiso del titular de los derechos de autor Los derechos derivados de usos legtimos u otras limitaciones reconocidas por ley no se ven afectados por lo anterior. bajo una licencia dual GFDL 1.2 / Creative Commons
Crditos
Este manual ha sido realizado por Sergio Costas Rodrguez http://www.rastersoft.com [email protected] La versin original de documento se encuentra en rastersoft.com [1].
Introduccin
En este documento voy a intentar explicar el funcionamiento y el API de OS/2. Con esto intento hacer un pequeo manual de programacin de este Sistema Operativo, algo que se echa en falta al hojear las listas de libros de casi cualquier librera, por muy especializada que est en Informtica. Pretende ser tambin el complemento del compilador EMX/GCC, un excelente compilador de C totalmente freeware, disponible para OS/2. Debo advertir que el API no se encuentra descrito en su totalidad. Por ejemplo, faltan algunas llamadas puntuales muy poco usadas, como por ejemplo el acceso al hardware mediante IOCTL. Tampoco viene descrito cmo trabajar con el Presentation Manager, sino que se 'limita' a la multitarea, gestin de memoria, comunicacin interproceso y acceso a pantalla y teclado en sesiones de modo texto. Por qu el formato HTML? Las razones de haber usado el formato HTML en la confeccin de este documento en vez de usar el formato INF de OS/2 han sido tres:
Manual de programacin de OS/2 facilidad de edicin de los fuentes portabilidad del texto y posibilidad de lectura en el browser preferido por el usuario (el propio OS/2 incluye uno de serie, en el Bonus Pack) no tengo ningn editor de INFs
Manual de programacin de OS/2 Operativos multitarea. La idea consista en tener varios programas simultneamente en memoria, si bien, como el ordenador es nico, solo uno estara activo en cada momento. Cuando dicho programa hace una operacin de Entrada/Salida en la que se pierde tiempo de CPU (como leer una tarjeta, por ejemplo), mientras la mecnica realiza la operacin de bsqueda y lectura, el ordenador conmuta al siguiente programa que tiene en memoria, el cual continuar ejecutndose hasta que haga una operacin de Entrada/Salida. Cuando se llega al ltimo, se vuelve a empezar. Para ese momento, la operacin de Entrada/Salida pedida por el primer programa ya estar lista, con lo que podr seguir su ejecucin. De esta forma, hemos aprovechado un tiempo que antes perdamos. Finalmente, llegamos a los sistemas distribuidos. Generalmente, lo que tenemos es una red de ordenadores (por ejemplo, en una universidad es normal tener una gran cantidad de PC's) conectados entre s. Si nos fijamos, normalmente solo unos cuantos estn en uso en cada momento, y el resto simplemente se dedican a ejecutar un bonito salvapantallas, o peor an, a realizar la esttica funcin de caro pisapapeles. En otras palabras, estamos desperdiciando una vez ms tiempo de proceso. Para solucionarlo, se han ideado los Sistemas Operativos distribuidos. Estos sistemas operativos son el siguiente paso en la evolucin de los Sistemas Operativos multitarea. La idea consiste en que en los Sistemas Operativos multitarea los programas suelen estar divididos en varios Threads o hilos de ejecucin. Cada uno de estos Threads se puede ver como un programa absolutamente independiente de los dems, si bien, trabajando todos en conjunto forman el programa completo. Dado que cada Thread es independiente de los dems, nada impedira, en principio, que se ejecutase cada uno en un procesador diferente. Esa es la base de los Sistemas Operativos distribuidos: cada nuevo Thread es ejecutado en una mquina distinta, de modo que la potencia de clculo se halla distribuida por toda la red. De esta forma, los equipos que estaban inactivos son aprovechados al mximo. Por desgracia, esta idea resulta extremadamente compleja de implementar, por lo que esta clase de Sistemas Operativos se encuentran todava poco extendidos.
Historia de OS/2
OS/2 son las siglas de "Sistema operativo de segunda generacin". La idea de OS/2 surgi entre IBM y Microsoft a mediados de los 80, en un intento de hacer un sucesor de MS-DOS, el cual ya empezaba a acusar el paso del tiempo y resultaba claramente desaprovechador de los recursos de las mquinas de la poca (basadas en el Intel 286). OS/2 1.0 sali en abril de 1987 y era un sistema operativo de 16 bits, pues estaba pensado para trabajar sobre el microprocesador 286. Sin embargo, aprovechaba plenamente el modo protegido de este ordenador, haciendo uso de sus capacidades para proteccin de memoria, gestin de multitarea, etc. El resultado fue un S.O. estable, rpido y muy potente. OS/2 ya tena incorporada desde esa primera versin la multitarea real. Se podan ejecutar varias sesiones simultneamente, en cada una de ellas se podan tener mltiples programas, y cada uno de ellos poda tener mltiples threads en ejecucin. Se trataba de una multitarea jerrquica, con cuatro niveles de prioridad: Crtico (til para programas que requieran atencin casi constante por parte de la CPU, como un mdem), Primer plano (correspondiente al programa que tiene acceso a la pantalla, teclado y ratn), Medio (programas lanzados por el usuario que se ejecutan en BackGround) y Desocupado (tareas de poca importancia o lentas, como el Spooler de impresin). Dentro de cada nivel (a excepcin del de Primer plano), existen 32 niveles de prioridad, los cuales son asignados dinmicamente a cada programa por el S.O. en funcin del porcentaje de uso de la CPU, de los puertos de E/S, etc. OS/2, adems, permita memoria virtual, con lo que se podan ejecutar programas ms largos que lo que la memoria fsica instalada permitira en principio (los requerimientos de aquella versin eran un 286 con 2 megas de memoria). Por otro lado, inclua la caracterstica de comparticin de cdigo: al cargar dos veces un mismo programa, el cdigo de este no se duplicaba en memoria, sino que el mismo cdigo era ejecutado por dos Threads diferentes. Esto permita ahorrar mucha memoria.
Manual de programacin de OS/2 Esta versin de OS/2 era ntegramente en modo texto. Si bien el Sistema Operativo daba la posibilidad de usar los modos grficos de la tarjeta del ordenador, no inclua ningn API que ayudase en ello, recayendo todo el trabajo de diseo de rutinas de puntos, lneas, etc en el programador de la aplicacin. Esto no era realmente tan problemtico, pues era lo que se haca (y se hace) en el mundo del MS-DOS. Sin embargo, se echaba en falta un entorno grfico como Windows. En la versin 1.1, aparecida en octubre de 1988, lleg por fin el Presentation Manager, un gestor de modo grfico, junto con la primera versin de Work Place Shell. Ambos formaban un entorno grfico muy parecido al an no comercializado Windows 3.0. Tambin hizo su aparicin el formato de ficheros HPFS (High Performance File System). Este sistema de ficheros complementaba al clsico FAT, que era el usado por MS-DOS y por OS/2 1.0; sin embargo, ofreca una gran cantidad de ventajas, tales como Menor fragmentacin de ficheros: HPFS busca primero una zona en donde el archivo entre completo, con lo que la fragmentacin de ficheros es prcticamente inexistente. De hecho, IBM recomienda desfragmentar los discos duros una vez al ao, y solo a los paranoicos. Mayor capacidad: HPFS admite discos duros de hasta 512 gigabytes de capacidad, manteniendo el tamao del cluster (unidad mnima de informacin almacenable) en 512 bytes o un sector. En FAT, el tamao mnimo de cluster para un disco duro es 2048 bytes, y para discos mayores aumenta (un disco duro de 1 giga tiene un tamao de cluster de 32Ks). Soporte para nombres largos: permite nombres de hasta 256 caracteres. Mayor seguridad: si al grabar en un sector se detecta un error, se marca automticamente como defectuoso y se graba en otra parte. Mayor velocidad en el acceso, gracias a la estructura jerrquica de directorios, que optimiza el acceso a disco. El gran problema de OS/2 es que segua siendo un S.O. de 16 bits, con lo que no aprovechaba plenamente las capacidades de los 386 de la poca, que empezaron a extenderse con ms velocidad de la esperada. Segn una revista del sector, Microsoft sugiri hacer una versin de 32 bits (que obligara a ejecutarla en ordenadores 386 o superiores), pero IBM insisti en perfeccionar la de 16 bits. Sobre quien dijo cada cosa realmente solo se puede especular. Lo nico que se sabe a ciencia cierta es que la versin de OS/2 de 32 bits presentada por MicroSoft en 1990 era casi igual que la versin 1.3, con la nica diferencia de que el kernel era de 32 bits. IBM, por su parte, quera un escritorio orientado a objetos, y no el clsico shell de OS/2 1.x (el cual MicroSoft copiara para su Windows 3.0). Puestas as las cosas, finalmente se rompi el acuerdo entre ambos. OS/2 2.0, la primera versin de OS/2 de 32 bits, iba a salir inicialmente a finales de 1990; pero al no contar con la ayuda de Microsoft, IBM no fue capaz de sacarlo hasta 1992, dndole a Windows 3.0 el tiempo suficiente para asentarse en el mercado. OS/2 2.0 tena todas las ventajas de los anteriores OS/2, unido al nuevo ncleo de 32 bits. No se trataba, por tanto, de un retoque de la versin de 16 bits, sino un sistema operativo prcticamente nuevo que aprovechaba al mximo las capacidades del modo protegido del microprocesador 386. Sin embargo, iba ms all que Windows, pues al contrario que ste, ofreca compatibilidad garantizada con todas las aplicaciones de 16 bits anteriores, gracias a la inclusin del API original de 16 bits junto con el nuevo de 32, y adems sin perdida de prestaciones. As mismo, ofreca tambin compatibilidad con Windows 2.x y 3.0, junto con una compatibilidad con MS-DOS muy mejorada, gracias al modo V86 que incorporan los micros 386 y del que careca el 286: en OS/2 1.x la compatibilidad DOS era muy limitada, quedando reducida a una sola tarea y realizando un cambio entre modo real y modo protegido del microprocesador, adems de consumir de manera permanente 640 Ks de memoria. Aparte, la emulacin no era todo lo buena que caba esperar. Todos estos problemas desaparecieron en la versin 2.0, pudiendo tener varias sesiones DOS totalmente independientes entre s, con una compatibilidad cercana al 100% y beneficindose de las capacidades de Crash Protection del OS/2, que impiden que un programa pueda colapsar el sistema entero. Por otro lado, el Work Place Shell (el shell de trabajo grfico, de ahora en adelante WPS) fue muy mejorado, resultando un shell totalmente orientado a objetos, con acceso directo a los ficheros, carpetas dentro de carpetas,
Manual de programacin de OS/2 ficheros sombra (conocidos como alias en los sistemas UNIX) y un escritorio de verdad. A su lado, el shell de Windows 3.0 quedaba a la altura del betn. IBM consigui vender OS/2 2.0 en grandes cantidades; sin embargo, no consigui su autentico despegue, en parte por culpa de la falta de apoyo por parte de las empresas de software. El API del Presentation Manager, aunque similar al de Windows, tena muchas diferencias, con lo que las empresas tuvieron que elegir entre uno u otro, ante la imposibilidad de muchas de ellas de dividir su talento entre ambos sistemas. A principios de 1994 aparece OS/2 Warp, nombre comercial de la versin 3.0 de OS/2. En ella surgen nuevos elementos: un kit completo de multimedia (mejora del que traa la versin 2.1) y el Bonus Pak, un kit de aplicaciones que permite ponerse a trabajar con el ordenador nada ms instalar el Sistema Operativo, pues contiene elementos como un Kit de conexin a Internet completo, el paquete integrado IBM Works (formado por un procesador de textos, hoja de clculo, base de datos y graficos de empresa, junto con el PIM, que aade ms funcionalidades aprovechando las capacidades drag&drop del WPShell), soft de terminal, soft de captura y tratamiento de vdeo, etc. As mismo, la cantidad de hardware soportado fue ampliado de manera considerable, soportando casi cualquier dispositivo existente en el mercado: CD-Roms, impresoras, tarjetas de sonido, soporte PCMCIA, tarjetas de vdeo, tarjetas de captura de vdeo, tarjetas SCSI, etc. Los requisitos mnimos de esta versin seguan siendo un 386sx a 16MHz con 4 megas de RAM, los mismos que Windows 3.11, y poda ejecutar programas DOS, OS/2 16bits, OS/2 32 bits, Windows 2.x y Windows 3.x (inclua adems el API Win32s, con lo que se podan ejecutar incluso programas Windows de 32bits). IBM se meti en una campaa publicitaria a nivel mundial para promocionar esta nueva versin, la cual, sin embargo, no dio los resultados esperados por ser demasiado light (todos recordaremos aquel anuncio de las monjitas en el convento, cuando una le dice a otra que ya tiene el nuevo OS/2 Warp, contando las nuevas caractersticas de este sistema operativo). A pesar de eso, OS/2 es ampliamente utilizado en mltiples empresas, bancos sobre todo, en donde su estabilidad es la mayor garanta (los propios cajeros automticos funcionaban inicialmente con OS/2 1.0, si bien actualmente usan OS/2 Warp). Poco despus sale al mercado una revisin de Warp, denominada Warp Connect, la cual aade un kit completo de conexin a redes, soportando prcticamente cualquier estndar de red, incluyendo Novell Netware, TCP/IP, etc. junto con soporte para SLIP y PPP. En Noviembre de 1996 se hizo la presentacin de Merln, nombre clave de OS/2 4.0, y que, en contra de lo que mucha gente piensa, no tiene nada que ver con el mtico mago de la corte del rey Arturo, sino con un pjaro parecido a un guila (siguiendo la nueva filosofa de IBM de nombrar sus creaciones con nombres de aves). Merln trae todo lo que ofreca OS/2 3.0, pero lo amplia con un conjunto extra de caractersticas, como son: Un soporte todava mayor de hardware. Mayor simplicidad de instalacin. Libreras OpenDoc (compatibles con OLE 2.0, pero ms potentes). Libreras OpenGL, que permiten aprovechar las capacidades 3D de las tarjetas que soporten este estndar. API de desarrollo Open32, que permiten recompilar con suma facilidad las aplicaciones escritas para Windows'95 y Windows NT, de forma que aprovechen al mximo los recursos de OS/2. Un Bonus Pack ampliado, incluyendo una nueva versin del IBMWorks basada en OpenDoc, y las utilidades LotusNotes. Un Kernel an ms optimizado. Escritorio mejorado, ofreciendo una orientacin a objeto an mayor. Un extenso soporte de conectividad, superior a la versin Connect de Warp 3.0, lo que le convierte en el cliente de red universal, pudiendo conectarse a casi cualquier servidor (no solo Warp Server, sino Windows NT server, Novell, etc).
Manual de programacin de OS/2 Sesiones DOS reales (el micro se conmuta realmente a modo real, y todo el contenido de la RAM se guarda en disco, quedando el Sistema Operativo y el resto de las utilidades congelados, pudiendo rearrancar en cualquier momento. Es til para juegos o programas de DOS muy exigentes, que se niegan a funcionar en una sesin DOS virtual). La caracterstica estrella de cara al marketing: el VoiceType. Se trata de un software reconocedor de voz, capaz de funcionar con cualquier tarjeta de sonido, y que permite al usuario trabajar exclusivamente mediante el dictado de comandos. Este sistema, al contrario que otros disponibles hasta el momento, realmente reconoce el habla de forma continua, de modo que no solo se puede usar para navegar por el escritorio y controlar programas, sino que sirve perfectamente para dictar cualquier tipo de texto, como artculos, cartas, etc. sin tocar una sola tecla. Se trata, por tanto, de un avance de los que sern, sin duda, los sistemas operativos del futuro.
En este grfico vemos como est construido el acceso a los dispositivos en OS/2.
En el esquema, vemos que la aplicacin se comunica con el Sistema de Ficheros de OS/2, que forma parte del ncleo, y ste determina a quien tiene que enviar o de quien debe leer los datos. Si el programa quiere acceder a la pantalla, el Sistema de Ficheros enva los caracteres al Subsistema de Vdeo (VIO), que es la parte encargada de controlar la totalidad de accesos a la pantalla. Lo mismo si se trata del teclado, el ratn o un fichero de disco. La razn de usar el Sistema de Ficheros para acceder tanto a los archivos de disco como a los dispositivos, es que permite que el programa no se tenga que preocupar de la estructura de estos: cualquier entrada o salida ser tratada como un conjunto de caracteres en serie. Esta independencia de estructura es cmoda para algunas aplicaciones, pero en otras puede ser mejor poder acceder directamente a cada dispositivo, normalmente por razones de velocidad. Esa es la razn de que OS/2 permita a las aplicaciones acceder directamente a los Subsistemas de Vdeo (VIO), teclado (KBD) y ratn (MOU). A travs de estos, podemos por ejemplo hacer funciones de Scroll en la pantalla, conocer la posicin del ratn, etc. Podemos comparar los Subsistemas de OS/2 con la BIOS del ordenador, si bien estos son ms completos que aquella en muchas funciones, y sobre todo mucho ms rpidos.
Comparticin de ficheros
Dado que OS/2 es un Sistema Operativo multitarea, puede ocurrir que dos (o ms) programas intenten acceder a la vez a un mismo fichero de disco. Para evitar interferencias, OS/2 ofrece una serie de opciones de comparticin de archivos, que se especifican en el momento de abrirlos. Estas son: Modos de acceso al fichero READ_ONLY: solo se va a leer del fichero. WRITE_ONLY: solo se va a escribir en el fichero. READ_WRITE: se va a leer y escribir (es el valor por omisin). Modos de comparticin DENY_ALL: OS/2 rechaza cualquier peticin posterior de abrir ese archivo. DENY_READ: OS/2 rechaza cualquier peticin de abrir ese archivo para lectura. DENY_WRITE: OS/2 rechaza cualquier peticin de abrir ese archivo para escritura. DENY_NONE: OS/2 permite cualquier operacin con ese archivo.
Los modos de comparticin permiten elegir la forma en que otros programas acceden al fichero que tenemos abierto. Por ejemplo, si tenemos un programa que lee del fichero prueba.txt y lo enva a la impresora, lo lgico es que lo abra como READ_ONLY, pues no va a escribir nada en l. Por otro lado, no puede permitir que otro programa modifique el fichero, pero no le importa que pueda leerlo, por lo que como modo de acceso asigna READ_ONLY. De esta forma, si otro programa intenta acceder al mismo fichero, OS/2 solo le dar acceso si intenta acceder en modo READ_ONLY; si intenta abrirlo como WRITE_ONLY o READ_WRITE, OS/2 le devolver un error.
Gestin de dispositivos
A travs del sistema de ficheros podemos acceder tambin a los dispositivos fsicos que forman el ordenador. Existen normalmente una serie de archivos que identifican a cada perifrico y que nos permiten enviar y recibir datos hacia y desde ellos. Los nombres de los archivos de que disponemos son: COM1-COM4: maneja los puertos serie del ordenador. CLOCK$: el reloj del sistema. CON: gestiona la consola (en lectura es el teclado, en escritura, la pantalla). SCREEN$: maneja la pantalla. KBD$: maneja el teclado. LPT1-LPT3: maneja los puertos paralelo (normalmente la impresora). NUL: dispositivo nulo. Todo lo que se enve a l simplemente es ignorado. POINTER$: gestiona el dispositivo de puntero (el ratn).
Los dispositivos cuyo nombre acaba en $ no son accesibles directamente por los programas, y es preciso usar funciones especficas para acceder a ellos. Esto da una mayor riqueza y control sobre ellos.
10
Busqueda de ficheros
En muchas ocasiones un programa necesita conocer todos los ficheros que coinciden con un patrn determinado. Es el caso, por ejemplo, de querer mostrar una lista de ficheros que acaben en AL, o que tengan la letra F en el tercer lugar, etc. Para ello, OS/2 facilita una serie de funciones que permiten realizar esto. En ellas se debe especificar un nombre de fichero, sabiendo que: El smbolo ? sustituye a cualquier carcter situado en esa posicin. As, la bsqueda de program?.exe devolver los nombres de los ficheros que empiecen por program, a continuacin tengan un carcter cualquiera, y por ltimo, terminen con .exe, como por ejemplo, programa.exe, o programz.exe; pero no devolver programad.exe ni programa. El smbolo * sustituye a cualquier cadena situada desde esa posicin en adelante. As, la bsqueda de prog* devolver cualquier fichero que empiece por prog, tenga lo que tenga despus. Por ejemplo, devolver programa, progs... DosFindFirst DosFindNext DosFindClose
11
Variables de entorno
Para permitir la colocacin de programas en mltiples directorios y simplificar algunas opciones de configuracin, OS/2 facilita las variables de entorno. Se trata de una serie de variables que se definen bien en la lnea de comandos, bien en el CONFIG.SYS, por medio de la sentencia SET. Por ejemplo, la lnea SET mi_variable=C:\OS2UTIL\MIPROGRAMA asigna a la variable de entorno mi_variable el valor C:\OS2UTIL\MIPROGRAMA. De este modo, el usuario puede especificar el directorio en donde estarn diversas partes de un programa, o bien diversas opciones para ste. Por ejemplo, el compilador EMX requiere de algunas variables de este tipo para saber donde estn las libreras, documentacin, etc. El propio OS/2 hace uso de esta facilidad para implementar variables como el PATH de datos, etc. DosScanEnv
12
El subsistema de vdeo
El subsistema de vdeo (VIO) es el encargado de gestionar la comunicacin entre los programas y la pantalla. Es, sin duda, el subsistema ms complejo de los tres, y el que ofrece, por tanto, mayores posibilidades. Dado que puede haber varios programas ejecutndose a la vez en el sistema, pero solo uno puede acceder a la vez a la pantalla (normalmente el programa que se encuentra en primer plano o foreground), es necesario virtualizar sta por medio de un buffer de pantalla propio de cada programa: el LVB (Logic Video Buffer, buffer de vdeo virtual). Cuando una aplicacin quiere escribir en pantalla y se encuentra en segundo plano (background), su salida se escribe en dicho LVB. En el momento en que el usuario conmuta dicho programa a primer plano, el LVB se copia tal cual en la memoria de pantalla, y el resto de las escrituras van a sta directamente. Si se vuelve a conmutar dicho programa a segundo plano, OS/2 copia lo que hubiese en pantalla en ese momento al LVB. De este modo, el programa nunca sabe ni le preocupa cuando est en primer o en segundo plano.
Funciones VIO
Salida por TTY virtual En un extremo se encuentra el primer servicio que ofrece el subsistema VIO, que es el de salida TTY. Este servicio es casi idntico a la salida de caracteres por medio del sistema de archivos. De hecho, ste, cuando comprueba que lo que el programa enva va dirigido a la pantalla, usa este servicio para realizar la funcin. Cual es la diferencia entre uno y otro, entonces? Las diferencias son dos: la primera es que el uso del subsistema VIO es una opcin ms rpida que el sistema de ficheros; la segunda es que si usamos el subsistema, no podremos redireccionar la salida a un fichero, o a otro dispositivo de salida. Siempre ir a la pantalla. El servicio TTY admite los caracteres de control estndar del ASCII, y tambin puede soportar ANSI, si ste es activado mediante la llamada correspondiente. VioWrtTTY VioGetAnsi VioSetAnsi VioGetMode VioSetMode VioGetState VioSetState Salida de cadenas de caracteres Los siguientes servicios se encargan del tratamiento de la pantalla a ms bajo nivel. Con ellos podemos imprimir largas cadenas de caracteres con atributos y leer los caracteres que hay en determinadas posiciones de la pantalla. Tambin podemos repetir un carcter o una pareja carcter-atributo un nmero determinado de veces. Los atributos son bytes que definen el color de tinta y de fondo para cada carcter, as como otras caractersticas como el parpadeo. Estn compuestos por un byte, el cual se divide en dos nibbles (grupos de 4 bits). El nibble de menor peso determina el color de la tinta del carcter, y el de mayor peso el color de fondo y, segn se encuentre activo o no, el parpadeo del carcter. La distribucin es como sigue: Parpadeo activado Bit Significado 7 Parpadeo del carcter 6 Rojo del fondo 5 Verde del fondo 4 Azul del fondo 3 Intensidad de la tinta
13
Intensidad activada Bit Significado 7 Intensidad del fondo 6 Rojo del fondo 5 Verde del fondo 4 Azul del fondo 3 Intensidad de la tinta 2 Rojo de la tinta 1 Verde de la tinta 0 Azul de la tinta Los bits de color activan directamente cada una de las componentes del monitor, de modo que stas se suman directamente, dando lugar a los siguientes colores: 0 4 Negro Rojo 1 5 Azul Magenta 2 6 Verde Amarillo 3 7 Celeste Blanco
El bit de intensidad se limita a hacer estos colores ms o menos brillantes. Estos servicios orientados a carcter siguen siendo independientes del hardware utilizado de modo que no es necesario saber como se trabaja a nivel fsico con ellos. Por otra parte, el propio OS/2 optimiza las transferencias para cada uno de ellos, de modo que se consigue la mayor velocidad posible, y se eliminan ciertos problemas inherentes a algunos sistemas grficos (por ejemplo, en las tarjetas CGA sincroniza automticamente la escritura con el retrazado vertical, de modo que se evita la aparicin de nieve en la pantalla). Tanto cuando hacemos una lectura como una escritura, si excedemos el fin de una lnea se seguir leyendo en la siguiente, y si llegamos al final de la pantalla no se seguir leyendo ni imprimiendo. VioWrtCellStr VioWrtCharStr VioWrtCharStrAtt VioWrtNAttr VioWrtNCell VioWrtNChar VioReadCellStr VioReadCharStr Funciones de Scroll El subsistema VIO ofrece, adems, la posibilidad de realizar scroll de ventanas en modo texto. Con este conjunto de funciones, podemos desplazar parte o toda la pantalla en cualquiera de las cuatro direcciones posibles. La razn de incluirlas es que resulta mucho ms rpido que hacer una rutina que lea cada posicin del buffer de vi-deo y la reescriba en el lugar adecuado, aparte de que se trata de una funcin muy comn en casi cualquier programa. VioScrollDn VioScrollLf VioScrollRt VioScrollUp
Manual de programacin de OS/2 Definicin y movimiento del cursor El cursor (el cuadradito parpadeante) es totalmente definible por el usuario en las sesiones de texto y grficos de OS/2. Podemos definir tanto su tamao como su posicin dentro del carcter. Al contrario que en MS-DOS, cuando escribimos en la pantalla de OS/2 la posicin del cursor no se cambia. Esto se hace as para ganar tiempo. Normalmente el cursor solo se usa cuando hay que introducir datos por teclado, y el resto de las veces se suele hacer desaparecer de la pantalla. Esta es la razn de que halla un conjunto de funciones para situar el cursor. De esta manera se gana en velocidad. VioGetCurPos VioSetCurPos VioGetCurType VioSetCurType Acceso al LVB Cuando se necesite alta velocidad, se puede pedir acceso directo al buffer virtual de vi-deo asociado con la aplicacin. Al hacerlo, OS/2 devuelve un puntero a la zona de memoria en donde est situado, con lo que podremos escribir en l como si se tratase de la pantalla fsica. Una vez que hemos terminado, debemos enviar una orden de retrazado, que har que OS/2 copie el LVB a la pantalla fsica (siempre que la aplicacin se encuentre en primer plano). Esto significa que los cambios que hagamos en el LVB no son visibles hasta que nosotros queramos. Usar esta opcin implica que perdemos el aislamiento entre el hardware y nosotros: dado que el LVB no es ms que una copia del buffer real de pantalla, es necesario que nuestro programa conozca la geometra y la forma de almacenamiento de los datos en sta. VioGetBuf VioShowBuf Acceso directo al buffer real de vdeo En el extremo opuesto se encuentran las funciones de acceso directo al vi-deo. Con ellas, OS/2 da acceso directo a la memoria de pantalla. Sin embargo, esto que en el DOS de siempre es la opcin ms normal y comn, puede resultar catastrfico en un Sistema Operativo multitarea como OS/2; no se hundira el suelo bajo nuestros pies, pero la pantalla podra ser alterada en un momento poco oportuno... si OS/2 no tomase las debidas precauciones. Para que un programa pueda acceder directamente a la memoria real de vi-deo, es absolutamente necesario que se encuentre en primer plano. Esto es as porque si escribiese algo en pantalla cuando estuviese en background, machacara la imagen de la aplicacin que se encontrase en ese momento en primer plano. Lo primero que hay que hacer es pedir la direccin fsica de la memoria de vdeo. OS/2 devuelve un selector (o varios) a dicha zona de memoria (ver modos de direccionamiento del 286). Estos selectores deben ser convertidos a punteros antes de poder trabajar con ellos. Pueden ser varios pues cada selector no puede apuntar a un bloque de memoria mayor de 64Ks, el cual es tambin, casualmente, el tamao de cada bloque de memoria de las tarjetas de vdeo actuales. Esto ayuda a simplificar el acceso, pues en modos como 640x480x16colores no necesitaremos cambiar de bancos; OS/2 nos devuelve un selector que apunta a cada uno de ellos, con lo que solo tenemos que acceder normalmente como si fuese memoria lineal, y el Sistema Operativo conmutar de uno a otro automticamente. El hecho de obtener un selector no significa que dispongamos de acceso todava a la pantalla. De hecho, si intentsemos escribir o leer algo en ese momento y la aplicacin no se encontrase en primer plano, OS/2 la cerrara inmediatamente, dando un Fallo de Proteccin General (el cual ya sabemos que no es tan fatal como el de Windows, pues en OS/2 solo afecta a la aplicacin que lo ha provocado, dejando intacto al Sistema Operativo y al resto de los programas).
14
Manual de programacin de OS/2 Cada vez que queramos acceder a la memoria fsica de vi-deo, debemos bloquear el acceso al buffer. Si el programa estaba en primer plano, OS/2 devolver un valor afirmativo al retornar de la llamada, y bloquear el selector de programas. Esto significa que el usuario no podr conmutar la sesin actual a segundo plano hasta que sta termine el acceso. Sin embargo, el resto de las aplicaciones siguen funcionando en segundo plano, sin verse afectadas por este hecho. Por supuesto, esto puede ser peligroso, y OS/2 toma algunas precauciones: si el sistema est bloqueado y el usuario hace una conmutacin de tarea, si el programa no desbloquea el conmutador antes de un cierto tiempo definido por el sistema, queda congelado y se realiza la conmutacin. Por eso es recomendable desbloquear cada x tiempo el selector de programas y volverlo a bloquear. Si por el contrario el programa se encontraba en segundo plano, hay dos opciones: OS/2 puede retornar un cdigo de error al programa, con lo que este sabr que no tiene acceso al buffer y puede seguir trabajando en otra cosa, o bien OS/2 congelar al programa hasta que el usuario lo pase a primer plano, momento en que lo despertar indicndole que tiene acceso al buffer real. Una vez que OS/2 ha devuelto un resultado afirmativo, el programa tiene acceso total a la memoria de vi-deo. Cuando haya terminado, tiene que proceder a desbloquear la pantalla, de modo que OS/2 pueda desbloquear el selector de programas y devolver el sistema a la normalidad. VioGetPhysBuf VioScrLock VioScrUnLock Existe una dificultad adicional a la hora de trabajar con acceso directo a la pantalla. Se trata de que OS/2, al conmutar de una tarea a otra, solo guarda el contenido de la pantalla si sta se encontraba en modo texto (esto se cumple para OS/2 1.x. En Warp 4, sin embargo, SI conserva el contenido de la pantalla, pero no se si se cumple tambin para OS/2 2.x o 3.x). Si estbamos trabajando en modo grfico, el contenido se perder. Para evitarlo, OS/2 facilita la posibilidad de crear un thread (este concepto ser explicado ms adelante, cuando veamos la multitarea a fondo) que ser activado cuando el programa vaya a cambiar de primer a segundo plano, y viceversa. Esto es as para permitir que un programa pueda almacenar el contenido de la pantalla en modo grfico cuando no tiene bloqueado el acceso a la memoria de vi-deo. Es el thread SavRedrawWait. Para implementarlo, es necesario crear un nuevo thread en el que se ejecute la llamada VioSavRedrawWait. Esta llamada bloquear el thread hasta que el usuario pulse CTRL+ESC, momento en que OS/2, antes de conmutar de tarea, despertar a dicho thread indicndole que debe almacenar el contenido de la pantalla. Cuando el thread termine, debe volver a ejecutar la llamada, con lo que OS/2 sabr que ha finalizado. El thread se quedar dormido de nuevo, y solo ser despertado cuando el usuario vuelva a conmutar a primer plano el programa. Entonces OS/2 le indicar que debe repintar la pantalla. VioSavRedrawWait La inclusin de este sistema de acceso puede parecer innecesaria, a la vista de la potencia del acceso al LVB; la razn de haberla implementado fue que, cuando sali OS/2, no llevaba todava el Presentation Manager, el gestor de ventanas, sino que era un Sistema Operativo en modo texto, por lo que se incluy este sistema para poder acceder en modo grfico a la pantalla, dado que VIO no ofrece ninguna facilidad como el trazado de puntos o lneas. Actualmente, al disponer de un completo (y complejo) gestor de ventanas, este mtodo puede parecer intil, sin embargo, para juegos puede ser muy til, pues permite acceder a pantalla completa en modos como 320x200 en 256 colores, lo que permite una alta velocidad de refresco, as como una gran facilidad de manejo. Hay que sealar que el acceso directo a la memoria de vdeo solo se puede hacer estando en una sesin de pantalla completa; no funcionar en una sesin de ventana.
15
16
El subsistema de teclado
El subsistema de teclado es el encargado de gestionar el acceso de los programas a este perifrico. Al igual que el subsistema de vdeo, no es necesario usarlo para escribir programas sencillos de cara al interface de usuario, pues se puede acceder fcilmente a l a travs del sistema de archivos. Es ms, el uso del subsistema de teclado no ofrece casi ninguna ventaja en lo que a velocidad se refiere. Por tanto para qu usarlo? Simplemente porque el acceso a travs del sistema de archivos solo nos permite detectar cdigos ASCII, pero no la pulsacin de teclas de funcin, o, por ejemplo, si tenemos pulsada la tecla ALT, o CTRL, etc. Para este tipo de funciones necesitamos usar los servicios del subsistema de teclado.
Funciones KBD
Acceso a nivel de cadenas de caracteres La primera posibilidad que ofrece el subsistema de teclado es leer caracteres, lo cual se puede hacer de dos formas: por cadenas, o carcter a carcter. La lectura por cadenas es exactamente igual que el uso de los servicios del sistema de archivos. De hecho, es el servicio que emplea la funcin DosRead cuando tiene que leer del teclado. Sin embargo, no necesita un indicativo de dispositivo abierto, ni participa en el redireccionamiento de E/S. Adems, funciona de modo diferente segn el modo de teclado en que se encuentre: ASCII, BINARIO o ECO. Con este sistema, se leen caracteres hasta que el buffer definido est lleno o hasta que se pulse el carcter de retorno, que por defecto es el retorno de carro (tecla enter). KbdStringIn KbdGetStatus KbdSetStatus La lectura por caracteres es un acceso ms a bajo nivel. En este caso podemos saber exactamente qu tecla est pulsada y cual no, y saber si adems se encuentran apretadas teclas como Ctrl, Alt, AltGr, etc. Adems, si el informe de cambio est activo, se notificar no solo cuando se pulse una tecla, sino tambin cuando se suelte. KbdCharIn KbdPeek Por ltimo, tenemos una funcin que nos permite vaciar el buffer de teclado, de modo que todas las pulsaciones hechas hasta el momento que no han sido atendidas sern borradas. KbdFlushBuffer
Modos de teclado
Los modos de teclado se definen como: ASCII En este modo, que es el modo por defecto, el teclado es sensible al retorno de carro. Esto significa que cuando el usuario teclee datos, la llamada no retornar hasta que ste pulse ENTER. Siempre se debe leer de forma sncrona, por lo que la opcin NO ESPERA de KbdStringIn no est soportada. El campo de longitud se utiliza para determinar qu cantidad del buffer de entrada es afectado por las funciones de edicin de lnea (como F3=recupera la ultima cadena, F1=recupera carcter, etc). Si se pone a 0, la edicin est desactivada. En este modo, los cdigos de caracteres de dos bytes (DBCS) se retornan de forma completa.
Manual de programacin de OS/2 BINARIO En este modo, solo se retorna cuando el buffer se llena por completo, y el retorno de carro no tiene ningn significado especial. ECO Si el modo ECO est activo, todo lo que se pulse aparecer en pantalla automticamente; en caso contrario, no lo har. El modo ECO solo puede estar fijado con el modo ASCII, nunca con el BINARIO.
17
El subsistema de ratn
El subsistema de ratn controla todo lo referente a este dispositivo. Lo primero que hay que hacer para trabajar con el ratn es abrir el dispositivo. Esta accin crea una cola de eventos para el ratn e inicializa todos los parmetros de la sesin a un valor conocido. MouOpen MouClose La cola de eventos del ratn almacena todos los sucesos ocurridos con ste dispositivo, de modo que puedan ser ledos por el programa en el momento adecuado. Un evento es, por ejemplo, mover el ratn, pulsar un botn, soltarlo... Existe la posibilidad de filtrar determinados eventos, de modo que al leer la cola, el resultado ser exactamente igual que si no se hubiesen producido. Cuando se lee la cola, se puede especificar adems si la funcin retornar an en el caso de que sta est vaca, o bien si debe esperar a que haya algn evento en ella. Adems de esto, podemos conocer en cualquier momento la posicin actual del ratn, as como cambiarla por otra. Estas opciones deben usarse slo con fines de actualizar alguna variable del programa; si se pretende que sea el propio programa el que pinte el cursor, es mejor leer las coordenadas por medio de la cola de eventos. MouReadEventQue MouGetEventMask MouSetEventMask MouFlushQue MouGetNumQueEl MouGetPtrPos MouSetPtrPos El controlador de ratn puede encargarse l mismo de pintar el cursor en pantalla (solo en sesiones de texto), o bien relegar dicha accin al programa. As mismo, puede devolver las coordenadas bien en coordenadas de pantalla, bien en Mickeys, que son unidades naturales del ratn. Por otro lado, es posible definir un rea de la pantalla que ser especifica de la aplicacin, de modo que el controlador no pintar el cursor cuando ste se encuentre dentro de aquella. Por defecto, este rea ocupa toda la pantalla. MouDrawPtr MouRemovePtr MouGetDevStatus MouSetDevStatus Por ltimo, es posible obtener informacin sobre las caractersticas de nuestro ratn. MouGetNumButtons MouGetNumMickeys
18
Manual de programacin de OS/2 Gestin de memoria en el modo protegido del 286 El microprocesador 286 incluye dos modos de funcionamiento: el modo real, en el que se comporta exactamente igual que un 8086, y el modo protegido, en el que surgen capacidades nuevas, como memoria virtual, proteccin de segmentos, etc. La forma de acceder a la memoria en el modo protegido, que es en el que trabaja OS/2 1.x, es mediante una combinacin de dos valores de 16 bits cada uno: un selector y un offset o desplazamiento. El valor del selector se almacena en un registro del microprocesador, y se usa como ndice para acceder a una tabla de selectores. Conviene sealar que esta tabla se almacena en la memoria RAM del sistema; esto explica que el hecho de cargar un nuevo valor en el registro de selector consuma mucho tiempo, pues hay que hacer dos lecturas a RAM (cada entrada de esta tabla ocupa 4 bytes), aparte de numerosas comprobaciones. En esta tabla se definen los distintos segmentos accesibles por el programa, y entre estos datos se incluye la posicin base de cada uno. El offset indica el valor a sumar a dicha direccin base para obtener la direccin del dato. Dado que la direccin base almacenada en la tabla de selectores viene definida con 24 bits, podemos situar cada segmento en cualquier punto de la memoria fsica (el 286 tiene un bus de direcciones de 24 lineas, luego puede direccionar hasta 16 megas), y recorrerlo con el valor de offset. Dado que este valor es de 16 bits, el tamao mximo de cada segmento es de 64 kilobytes. En este grfico se ve el proceso seguido para calcular una direccin en base al valor del selector y del offset. INSERTAR GRFICO Vemos que este sistema nos permite cambiar de sitio cada uno de los segmentos sin que el programa falle. Esto es porque el programa se refiere a cada segmento a travs de un selector, y no por medio de su direccin base, como ocurre en el modo real. Si para compactar la memoria, el OS/2 necesita mover el segmento 3 a otra zona, cambiar tambin la direccin base en la tabla de selectores. Como el programa se refiere a esa zona como el 'Selector 3', siempre acceder de forma correcta. Tambin vemos que el tamao de cada segmento es variable, pudiendo medir desde 1 byte hasta 64 Kbytes. Si el segmento mide menos que el mximo y se intenta leer o escribir ms all de sus lmites, se produce un error, una excepcin, que hace que OS/2 intercepte el programa y lo termine inmediatamente. Lo mismo si se carga un valor no vlido en el registro de selector. Este esquema permite adems implementar un sistema de memoria virtual. Entre los muchos datos que se almacenan en la tabla de selectores, uno de ellos es si ese segmento est presente o no en la memoria fsica. Si el programa carga en el registro de selector un valor correspondiente a un segmento no presente, se produce una excepcin, la cual salta al gestor de memoria virtual que lo que har ser pasar a disco un segmento poco usado, marcndolo como no presente, cargar en esa zona el segmento reclamado por el programa, marcarlo como presente y anotar su direccin base en la tabla de selectores, y devolver el control a la aplicacin. De este modo se puede trabajar con ms memoria que la que tiene fsicamente la mquina. Este esquema tiene un pequeo problema: dado que los segmentos pueden tener un tamao variable, puede ser necesario liberar varios pequeos para hacer sitio a uno grande. Adems, la memoria puede fragmentarse con facilidad, lo que obliga a reorganizarla para juntar pequeos huecos libres en uno solo grande. Todo esto consume tiempo extra durante el intercambio a disco. Pensando en esto, en el 386 se mejor el modo protegido, de modo que se facilita la gestin de la memoria virtual.
19
Manual de programacin de OS/2 Gestin de memoria en el modo protegido del 386 Cuando se cre el microprocesador 386, al ser un micro de 32 bits se vari la estructura del modo protegido para darle una mayor potencia, aparte de permitirle direccionar los 4GBytes que permite su bus de direcciones de 32 bits. En principio, el modo protegido del 386 funciona igual que el del 286: tenemos un registro de selector de 16 bits y uno de offset, esta vez de 32 bits, y en la tabla de selectores disponemos esta vez de 32 bits para indicar la posicin base de cada segmento. Sin embargo, disponemos solamente de 20 bits para indicar la longitud de cada segmento. Esto nos la limitara, en principio, a una longitud mxima de 1 mega por segmento. Sin embargo, los diseadores de Intel reservaron un bit de granularidad entre los muchos reservados del registro de estado. Este bit permite conseguir segmentos de hasta 4 GBytes con solo 20 bits. El truco consiste en que, si el bit est a cero, la unidad de longitud ser 1 byte, con lo que solo podremos tener segmentos de hasta 1 mega. En este modo se es compatible con el 286. Pero si este bit se pone a 1, la unidad ser 4 KBytes. Esto significa que un segmento puede tener una longitud mltiplo de esta: 4, 8, 12, 16, 20, 24, 28, 32, etc KBytes. En total, podemos disponer de hasta 64 TeraBytes de memoria para cada programa. Sin embargo, cuando usamos memoria virtual, este mtodo tiene un inconveniente que ya comentamos: dado que los segmentos pueden tener un tamao variable, puede ser necesario liberar varios pequeos para hacer sitio a uno grande. Adems, la memoria puede fragmentarse con facilidad, lo que obliga a reorganizarla para juntar pequeos huecos libres en uno solo grande. Todo esto consume tiempo extra durante el intercambio a disco. Para evitarlo, se incluy el modo paginado. Si este modo est activo, las direcciones que salen de la suma del selector y del offset son pasadas por un esquema como el siguiente: INSERTAR GRFICO Aqu vemos que el sistema se ha complicado mucho ms. Mediante este, podemos dividir la memoria en bloques de 4KBytes, e intercambiar solo aquellos que nos interese. De esta forma, si tenemos que cargar un segmento de 24 KBytes, solo liberaremos 24 KBytes de otro segmento, y no un segmento completo. Esto acelera las transferencias, elimina la fragmentacin (los bloques de 4KBytes que forman un segmento no tienen por qu ser consecutivas) y evita el crecimiento incontrolado del fichero de Swap. Sin embargo, hace el sistema algo ms lento, pues tiene que hacer ms accesos a la RAM (todas estas tablas se sitan en la RAM normal). Para evitarlo, se incluyeron una serie de Buffers que retienen las paginas de direccin y de tabla mas usadas. En OS/2 2.0 y posteriores se define un nico segmento para cada programa, de 4 GBytes de longitud (si bien la cantidad de memoria disponible para uso propio es de 'solo' 512 MBytes) y se activa el modo paginado. De esta forma el acceso es ms rpido, pues no es necesario cargar mltiples valores en el registro de selector, y conservamos la capacidad de memoria virtual. Esta es la razn de que, cada vez que se hace una reserva de memoria (con DosAllocMem o similar) la cantidad se redondea al mltiplo de 4KBytes superior.
20
Multitarea
Concepto de thread
Un thread (que de una forma un poco 'basta' se puede traducir como hilo) es la unidad bsica de ejecucin de OS/2. Cualquier programa que se ejecute consta de, al menos, un thread. Un thread se puede considerar como la agrupacin de un trozo de programa junto con el conjunto de registros del procesador que utiliza y una pila de mquina. El conjunto de los registros y de la pila de cada thread se denomina contexto. Como sabemos, en un Sistema Operativo multitarea, la CPU se reparte entre cada programa a ejecutar. Para ser ms precisos, el S.O. reparte la CPU entre todos los threads a ejecutar en cada momento (pues un programa puede contener varios threads), simplemente aduendose de esta y saltando al siguiente. Sin embargo, esta conmutacin no se puede hacer de cualquier manera. Cada vez que el S.O. se aduea de la CPU para cedersela a otro thread, los registros y la pila (o sea, el contexto del hilo) contienen unos valores determinados. Por eso, el S.O.
Manual de programacin de OS/2 guarda todos esos datos en cada cambio, de modo que al volver a conmutar al thread inicial, pueda restaurar el contexto inicial. No olvidemos que OS/2 es un S.O. con multitarea preemptiva, lo que significa que la CPU puede ser arrebatada en cualquier momento. Esto significa que un thread no puede saber cuando se le va a arrebatar la CPU, por lo que no puede guardar los registros ni la pila de forma 'voluntaria'. Dado que la forma en que un programa funciona depende principalmente del contexto, dos threads distintos pueden compartir el cdigo de ejecucin. Esto significa que si queremos dos threads que hagan las mismas operaciones sobre dos grupos de datos distintos, no necesitamos duplicar el cdigo en memoria. Dado que conmutamos el contexto cada vez, aunque el cdigo sea el mismo, los resultados no lo son, pues los registros y la pila son diferentes. Sin embargo, esto tiene un pequeo problema: las zonas de datos son comunes para todos los threads de un mismo proceso (esto ocurre en cualquier S.O., no solo en OS/2). Eso implica que, en estos casos, es necesario que cada thread cree su propia zona de datos, esto es, usar memoria de asignacin dinmica (en C se usa MALLOC para crear una zona de memoria dinmica, si bien OS/2 tambin ofrece servicios de este tipo ms potentes). Por otro lado, debemos recordar que cada thread se ejecuta de forma absolutamente independiente. De hecho, cada uno trabaja como si tuviese un microprocesador para el solo. Esto significa que si tenemos una zona de datos compartida entre varios threads de modo que puedan intercambiar informacin entre ellos, es necesario usar algn sistema de sincronizacin para evitar que uno de ellos acceda a un grupo de datos que pueden estar a medio actualizar por otro thread. Estos servicios se vern ms adelante. Un thread puede crear otro thread usando una llamada de OS/2. Dado que no existe relacin del tipo padre-hijo entre threads, los nuevos alcanzan los mismos privilegios que sus hermanos. DosCreateThread Por ltimo, un thread acaba cuando vuelve al repartidor de threads. Trabajando en cdigo mquina, esto implica un FAR RET; trabajando en C, significa ejecutar una instruccin EXIT o bien llegar al fin del procedimiento MAIN. Cuando acaban todos los threads de un proceso, OS/2 lo mata, liberando la memoria que ocupaba y los distintos recursos, como ficheros de disco, etc. Existe otra forma de terminar un programa en OS/2, es mediante una llamada a DosExit. Esta llamada finaliza el thread actual. DosExit Un thread tiene control sobre otros threads, siempre que pertenezcan al mismo PROCESO, pudiendo terminarlos si es preciso. Tambin puede sincronizarse con ellos si es preciso, esperando a que alguno en concreto termine su ejecucin, o bien dormirlo hasta que le interese ponerlo en ejecucin de nuevo. DosKillThread DosWaitThread DosSuspendThread DosResumeThread
21
Concepto de proceso
Un proceso no es ms que un conjunto de threads que ejecutan el mismo cdigo, junto con las zonas de memoria asociadas a ellos y los ficheros que tienen abiertos. Un programa consta, al menos, de un proceso, y un proceso, al menos, de un thread. Cuando un programa tiene varios procesos, lo normal es que cada uno ejecute un cdigo distinto, los cuales se encuentran en ficheros ejecutables separados. Dos procesos solo pueden compartir una zona de memoria si esta es definida expresamente como tal. As mismo, es en este caso cuando los sistemas de sincronizacin a la hora de compartir memoria (de los que hablaremos ms adelante) se vuelven especialmente necesarios e importantes.
Manual de programacin de OS/2 DosExecPgm DosKillProcess Los threads que componen un proceso tienen un cierto control sobre los dems, pudiendo bloquearse entre s de forma temporal si alguno lo necesita, entre otras posibilidades. DosEnterCritSec DosExitCritSec Cada vez que un thread se aduea de un recurso del sistema (un fichero o un bloque de memoria), este pasa a formar parte del proceso al que pertenece dicho thread, y accesible a todos los threads de ste, pero los threads del resto de los procesos no tienen por qu poder acceder a estos. Por supuesto, si un proceso acaba o bien si es abortado (bien voluntariamente por el usuario, bien por un error o trap), OS/2 libera automticamente todos los recursos ocupados por ste. Sin embargo, esto no significa que no se deban liberar estos antes de finalizar los threads que componen el proceso. Es buena prctica hacerlo, aparte de que el hecho de cerrar los ficheros permite que se actualicen los datos que se han grabado en ellos. Si se crean dos procesos a partir del mismo cdigo, OS/2 tambin procede a realizar comparticin de cdigo, con el consiguiente ahorro de memoria. Sin embargo, este hecho no implica que los recursos de cada proceso sea compartido con el resto. En el caso de los procesos, s existe una relacin padre-hijo: si un proceso crea otro, el primero se denomina padre, y el segundo, hijo. Los hijos de un proceso, as como los hijos de los hijos, etc, se llaman descendientes. El proceso padre mantiene un control sobre toda su descendencia, de forma que puede matar a cualquier proceso perteneciente a sta. Cuando se crea un proceso hijo, este hereda los recursos del padre, a menos que estos fuesen adquiridos por el padre sin derecho a herencia. Esto es: si el padre ha abierto con derecho a herencia un fichero, sus hijos podrn acceder a l; en caso contrario, no podrn (a menos que lo vuelvan a abrir ellos mismos, y los privilegios de acceso lo permitan). Por ltimo, se puede escoger si un proceso hijo determinado se ejecuta de forma sncrona o asncrona. En el primer caso, el proceso padre se detiene hasta que el proceso hijo ha terminado; en el segundo, ambos procesos siguen ejecutndose de forma independiente.
22
Prioridades de ejecucin
En un S.O. multitarea, todos los procesos compiten por tener el mximo tiempo de CPU. Sin embargo, es obvio que no todos tienen la misma importancia. Por ejemplo, un programa que controle un MODEM tiene que tener prioridad sobre otro que controle una impresora, por ejemplo. Por esto existen las prioridades. En OS/2 existen cuatro niveles de prioridad, en orden de mayor a menor: Crtico. Primer plano. Medio. Desocupado (Idle).
En el nivel crtico se ejecutan aplicaciones que necesiten una atencin inmediata por parte del procesador, como sistemas de comunicaciones o en tiempo real (sonido, video,...). Dentro de este nivel existen 32 subniveles distintos de prioridad. El subnivel en el que se sita el programa es escogido por l mismo. Un ejemplo es el selector de programas del OS/2, el cual corre en el subnivel ms bajo (0) del nivel crtico. Para evitar una sobrecarga del sistema, es conveniente que los programas que se siten en nivel crtico consuman poco tiempo de CPU.
Manual de programacin de OS/2 En el nivel de primer plano se ejecuta la aplicacin que se encuentra en primer plano en ese momento. Solo tiene un subnivel de prioridad. En el nivel medio se ejecutan los programas normales, como las aplicaciones, juegos, etc. Tiene 32 subniveles distintos de prioridad. El subnivel en que se sita es escogido por OS/2, y varia de forma dinmica en funcin de los accesos de E/S y del tiempo de CPU que consuma el programa, de forma que los ms voraces tendrn menor prioridad que los menos. Por ltimo, en el nivel desocupado (o Idle Time) se sitan aquellos programas que no necesitan una atencin excesiva de la CPU. Es lo opuesto al nivel crtico. Tiene 32 subniveles de prioridad. El subnivel en el que se sita el programa es escogido por l mismo. Un ejemplo es el Spooler de Impresora, o bien un salvapantallas. DosSetPriority Vemos que un detalle importante a tener en cuenta en el diseo de un programa es el consumo de CPU que hace. Pero como podemos hacer que nuestro programa consuma poca CPU? La respuesta es: no realizar nunca una espera activa. Una espera activa es cuando entramos en un bucle que se limita a comprobar el estado de una variable, y solo salimos de l cuando cambia a un valor determinado. Un ejemplo es cuando queremos esperar a que el usuario pulse una tecla. Normalmente hacemos un bucle que se queda leyendo el teclado constantemente hasta que el usuario realice la pulsacin. El problema es que estamos desperdiciando un tiempo que se podra aprovechar para ejecutar otras cosas. Para evitarlo, OS/2 nos suele dar la posibilidad de esperar por nosotros. Por ejemplo, cuando vimos el subsistema de teclado, podamos pedirle a OS/2 que retornase de la llamada tanto si haba una tecla pulsada como si no, o bien que no devolviese el control hasta que se pulsase. Pues bien, si le pedimos que haga la segunda opcin, estaremos ahorrando ciclos de CPU. Esto es as porque OS/2 sabe que ese proceso no est listo para correr, por lo que repartir el tiempo de CPU nicamente entre el resto de los procesos, y no volver a dedicarle atencin hasta que el usuario pulse una tecla, momento en que volver a darle ciclos de CPU. Vemos que, de esta forma, OS/2 ahorra el tiempo que consumiramos si nos dedicsemos a hacer una espera activa, con lo que si ejecutamos varios programas a la vez tardarn menos que la suma del tiempo que tardaran en ejecutarse uno a uno, precisamente porque aprovechamos estos tiempos muertos. Por supuesto, no solo se ahorran estos, sino tambin los necesarios para mover los cabezales de los discos, escribir caracteres en la pantalla, etc. Si hay dos procesos listos para correr, siempre obtendr el procesador aquel que tenga mayor prioridad. Puede parecer que si un proceso siempre tiene cosas que hacer y est situado en un nivel alto, siempre se quedar con la CPU, dejando al resto de las tareas bloqueadas. Esta es la razn de que la prioridad de los procesos en el nivel medio sea dinmica: de esta forma, los procesos que consumen mucha CPU ven rebajada su prioridad, de modo que todos se ejecutan por igual. Por otro lado, existe un tiempo mximo durante el cual un proceso puede estar sin recibir ciclos de CPU. Transcurrido este, OS/2 le cambiar momentneamente la prioridad, de modo que recibir un intervalo de tiempo, volviendo a su prioridad original despus. Esto permite que los programas de prioridad desocupada obtengan siempre ciclos de CPU, aunque haya un proceso de nivel medio que consuma mucha (por ejemplo, un RayTracer).
23
Concepto de sesin
Hasta ahora, cada vez que nos referamos a un conjunto de Procesos, usbamos el trmino programa ; si bien algunas veces el uso fue correcto, en otras no fue as, y deberamos haber usado el trmino sesin. Una sesin es un conjunto de procesos, junto con una pantalla, teclado y ratn virtuales. Cada vez que abrimos un programa en modo texto, OS/2 crea para l una sesin, asignndole un LVB en donde escribir los datos de salida, y una cola de teclado y de ratn, en donde se almacenarn las pulsaciones y los movimientos hasta que pueda procesarlos. Si esa sesin se encuentra en primer plano, su VDU, cola de teclado y cola de ratn estarn conectadas directamente a la pantalla fsica, al teclado fsico y al ratn fsico, as hasta que el usuario conmute a otra sesin
Manual de programacin de OS/2 usando el selector de programas, el cual es una parte especial de OS/2 dedicada precisamente a gestionar las sesiones. Todos los procesos pertenecientes a una sesin acceden al mismo LVB y a la misma cola de teclado y ratn. Esto no es un problema, sino un efecto buscado, pues si es necesario, es posible desde una sesin crear otras nuevas y arrancar en ellas procesos, de modo que no interfieran con el actual. De aqu surge que tambin existe una jerarqua de sesiones, y ciertas implicaciones entre ellas. Por ejemplo, una sesin padre puede ser notificada de que ha terminado una sesin hijo. Tambin una sesin padre puede traer a primer plano a cualquiera de sus hijos (siempre y cuando ella est en primer plano), o vincularse a ellos, de modo que cuando uno sea trado a primer plano, el padre tambin lo haga (y viceversa). Por ltimo, un padre puede parar una sesin hijo, pero solo a ella, y no a sus 'nietos', o a ella misma. Sin embargo, cuando se para una sesin hijo, se paran tambin todas sus sesiones descendientes. DosStartSession DosStopSession DosSelectSession A nivel interno, los conceptos de Thread y Proceso estn implementados en el ncleo, mientras que el de Sesin lo est en los subsistemas (los cuales no pertenecen al ncleo), pues son ellos los que deciden cuando un conjunto de procesos puede acceder o no a la pantalla fsica, o al teclado. Por otra parte, el selector de programas es el encargado de gestionar cuando se conmuta de uno a otro. Normalmente, cada vez que arrancamos un programa, se crea una sesin para l; sin embargo, en algunos casos podemos desear que no se cree una pantalla virtual o una cola de entrada de teclado, por ejemplo si el programa no tiene que interactuar con el usuario. En estos casos, se puede arrancar en una sesin 'muda', a la cual no se podr conmutar mediante el selector de programas, y que finalizar cuando acabe dicho proceso/procesos. Para arrancar un programa as desde la lnea de comandos de OS/2, se usa la orden DETACH nombre de programa.
24
Manual de programacin de OS/2 El selector de programas incorpora dos Hot Keys o Teclas Calientes: Ctrl+Esc y Alt+Esc. La primera pasa la sesin actual a segundo plano y vuelve a poner el Shell en primer plano. Esto nos permite arrancar nuevas sesiones sin cerrar la actual. La segunda permite conmutar de una sesin a otra de forma cclica, pero sin pasar por la del Shell. OS/2 es muy atento con el usuario, y por eso tiene especial cuidado con el Shell. Dado que se trata del principal nexo de unin entre ambos, si se produce un error y el Shell se cierra, OS/2 abre uno nuevo inmediatamente, sin afectar para nada al resto de las aplicaciones que estaban corriendo. De esta forma el usuario nunca se queda sin control de la mquina. No olvidemos que el Shell es un programa ms, que no corre en el ncleo, y que por tanto puede contener errores. De todo esto deducimos varias cosas El Shell del sistema es un programa ms, que se ejecuta en una sesin independiente, por lo que nada impide que escribamos el nuestro propio. Un Shell nunca debe arrancar ningn programa en su misma sesin, pues eso implicara que el pulsar Ctrl+Esc no nos devolvera al Shell, sino al programa que estamos ejecutando en su sesin. Dado que el Shell es el padre de todas las sesiones que se arrancan, puede conmutar a cualquiera de ellas sin usar ningn truco especial, simplemente usando el API del selector de programas. Por esto mismo, tiene acceso a todas las sesiones de la lista de tareas de OS/2, y tambin puede matar a cualquiera de ellas.
25
Gestin de la memoria
OS/2, como cualquier Sistema Operativo multitarea, mantiene un estricto control sobre la memoria usada por cada programa. Esto es as porque un programa que sobreescribiese la memoria de otro lo hara fallar con casi total seguridad. OS/2 hace uso del modo protegido de los microprocesadores 386 y superiores para asegurar que cada programa tenga acceso solo a sus bloques de memoria, y no pueda machacar el contendido de otra zona. A la vez, se encarga de intercambiar zonas de memoria entre la RAM y el disco duro, implementando as un sistema de memoria virtual eficiente, con lo que puede ejecutar programas ms largos que los que la memoria fsica del ordenador permitira. Las funciones de asignacin y desasignacin dinmica de memoria son extremadamente tiles en programas en los que no sepamos la cantidad de esta que vamos a necesitar. Un ejemplo puede ser una zona de memoria para descomprimir imgenes en un visualizador: dado que cada una puede medir cualquier longitud, reservar una cantidad excesiva de forma esttica hace al programa lento, y reservar poca puede impedir visualizar imgenes grandes. La solucin es comprobar el tamao de la imagen y reservar una zona de memoria dinmica acorde con este, liberndola al terminar. DosAllocMem DosFreeMem Otra funcin es la de crear zonas de memoria compartida. Se trata de bloques de memoria a los que pueden acceder dos procesos distintos de forma simultnea, y se usan para intercambiar grandes cantidades de informacin de forma rpida, y para compartirla. Existen dos formas de compartir un bloque de memoria: una es mediante un nombre que refiera a ese bloque; otra es mediante un puntero que seale a su inicio. DosAllocSharedMem En el primer caso, se debe especificar un nombre para el bloque que cumpla el convenio de nombres de ficheros de OS/2, y adems debe empezar por \SHAREMEM\. Por ejemplo, un nombre vlido sera \SHAREMEM\BLOQUE.DAT. DosGetNamedSharedMem
Manual de programacin de OS/2 Si no se especifca un nombre, la memoria solo podr ser compartida mediante el intercambio de un puntero que seale al inicio del bloque. Si ambos procesos conocen este valor, podrn acceder a dicho bloque pidindolo o asignndolo. Para comunicarlo, es necesario usar la comunicacin entre procesos, que veremos ms adelante. DosGetSharedMem DosGiveSharedMem
26
Subasignacin de memoria
La asignacin de memoria es una parte muy importante en cualquier sistema operativo. Da a los programas la capacidad de adaptarse dinmicamente a las necesidades de cada momento. Sin embargo, hay un coste relativamente elevado en la asignacin de memoria dinmica. En cada peticin es preciso buscar una zona libre, cambiar los descriptores de segmento, y cargar los registros de nuevo. Todo esto lleva un tiempo muy elevado, debido a la propia arquitectura del microprocesador. Lo mismo ocurre al liberar una zona. De aqu se saca una conclusin clara: utiliza toda la memoria que necesites, pero evita asignar y desasignar constantemente bloques. La solucin consiste en asignar un bloque de tamao moderado y dentro de l subasignar bloques de tamao ms pequeo, aumentando el tamao del bloque fsico slo cuando se necesita ms espacio. Para ayudar en esto, OS/2 ofrece un grupo completo de subasignacin de memoria. DosSubAllocMem DosSubFreeMem DosSubSetMem DosSubUnsetMem La primera accin consiste en reservar un bloque de memoria con DosAllocMem. Este bloque de memoria es necesario prepararlo para subasignacin con DosSubSetMem. Una vez hecho esto, podemos asignar y desasignar pequeos bloques con DosSubAllocMem y DosSubFreeMem como si ussemos las llamadas de siempre, pero con la diferencia de que ser notablemente ms rpido. Sin embargo, no debemos olvidar que se trata de un solo bloque de memoria subdividido, por lo que aunque tengamos subasignado un bloque, podemos salirnos de l por accidente sin que el sistema d un error (siempre, claro est, que no nos salgamos de la memoria asignada). Debemos ver las funciones de subasignacin de memoria simplemente como una ayuda en la gestin de sta. Para cualquier aplicacin es exactamente lo mismo dividir nosotros mismos un bloque de memoria de forma lgica que usar estas funciones. La ventaja consiste en que nos ahorramos programar un grupo de funciones que compruebe cuanto espacio nos queda libre y en donde y actualice las estructuras. Se trata de una ganancia en comodidad. Una aplicacin clara de estas funciones se ver cuando expliquemos las colas de mensajes, pues en ellas se hace uso intensivo de pequeos bloques de memoria que se crean y liberan constantemente.
27
Concepto de semforo
Un semforo es una estructura diseada para sincronizar dos o ms threads o procesos, de modo que su ejecucin se realice de forma ordenada y sin conflictos entre ellos. El por qu no se pueden usar directamente otras estructuras mas clsicas, como por ejemplo usar una variable comn para decidir si se puede o no acceder a un recurso, se debe a que estamos en un sistema multitarea: hacer esto implicara realizar una espera activa (un bucle, comprobando constantemente si la variable est o no a 0, y as saber si podemos seguir ejecutando o no). Por otro lado, puede ocurrir algo mucho peor: supongamos que un proceso comprueba la variable, y ve que el recurso est libre, por lo que procedera a cambiar dicha variable de valor y seguir. Pues bien, si justo despus de la comprobacin pero antes de que cambie el valor se conmuta de tarea (puede pasar, pues el sistema operativo puede hacerlo en cualquier momento), y el nuevo proceso comprueba la variable, como todava no se ha actualizado, creer que el recurso est libre, e intentar tomarlo, haciendo que ambos programas fallen. Lo peor del caso es que se tratar de un error aleatorio: unas veces fallar (cuando se produzca cambio de tarea en ese punto) y otras no. Para evitarlo, se idearon los semforos. Un semforo bsico es una estructura formada por una posicin de memoria y dos instrucciones, una para reservarlo y otra para liberarlo. A esto se le puede aadir una cola de threads para recordar el orden en que se hicieron las peticiones. Se empieza por inicializar la posicin de memoria a 1 (o al valor correspondiente si ese recurso concreto admite ms de un acceso simultneo). Esto se hace en el inicio del programa principal. A continuacin, cada vez que un thread o un proceso quiera acceder a dicho recurso (por ejemplo, un fichero), har primero una peticin con la primera de las llamadas disponibles. Cuando el S.O. ejecuta esa llamada, comprueba el valor que hay en la posicin de memoria del semforo, y si es distinta de cero, se limita a restarle 1 y devolver el control al programa; sin embargo, si ya es cero, duerme al proceso que hizo la peticin y lo mete en la cola de procesos, en espera de que el semforo se ponga a un valor distinto de cero. Por ltimo, cuando el proceso ha terminado el acceso al recurso, usa la segunda llamada para liberar el semforo. Cuando el S.O. la ejecuta, comprueba si la cola del semforo est vaca, en cuyo caso se limita a incrementar el valor del semforo, mientras que si tiene algn proceso, lo despierta, de modo que vuelve a recibir ciclos de CPU y sigue su ejecucin. Si haba varios procesos en espera, se irn poniendo en marcha uno tras otro a medida que el anterior va liberando el semforo. Cuando termina el ltimo, el semforo se vuelve a poner a 1. Se trata, por tanto, del mismo proceso que seguiramos con la variable, pero con la ventaja de que es un mecanismo estndar para todos los procesos, y como es una operacin atmica (esto es, que durante su ejecucin no se admiten cambios de tarea), no surje el problema de que una conmutacin pueda producir errores aleatorios. Vemos que la primera vez que un proceso usa el semforo, este tiene valor 1, por lo que pasa a cero y el proceso puede acceder al recurso. Si durante ese tiempo otro proceso quiere acceder tambin, al usar el semforo, este tiene valor cero, por lo que el S.O. deja de darle ciclos de CPU. Cuando el primer proceso ha terminado, libera el recurso, con lo que el S.O. puede comprobar que el segundo proceso est esperando, por lo que le vuelve a dar ciclos. En este punto, el proceso sigue como si nunca hubiese sido detenido. Este tipo de semforos son los de Exclusin mutua, o Mutex. DosCreateMutexSem DosOpenMutexSem DosCloseMutexSem DosQueryMutexSem DosReleaseMutexSem DosRequestMutexSem Otra utilizacin de los semforos es cuando uno o ms procesos tienen que esperar a que otro halla terminado una tarea. Para ello, el primer proceso borra el semforo y con una primitiva adecuada se pone a esperar a que el
Manual de programacin de OS/2 semforo se active (posted). Mientras, el segundo proceso va trabajando, y cuando termina lo que tiene que hacer, activa el semforo, con lo que el primer proceso vuelve a ponerse en marcha, sin haber desperdiciado ciclos de CPU. Son semforos evento. Vemos que puede haber varios procesos esperando por el mismo semforo, y el thread que lo activa no tiene por qu saber cuantos son. Cobran su importancia cuando el evento no es producido por otro thread, sino por otras funciones del S.O., como las de sincronizacin, que veremos ms adelante. DosCreateEventSem DosOpenEventSem DosCloseEventSem DosPostEventSem DosQueryEventSem DosResetEventSem DosWaitEventSem Los semforos se identifican con un nombre, el cual tiene la forma \SEM32\un_nombre. Un_nombre es el identificador del semforo. Existe la posibilidad de crear un semforo sin nombre, en cuyo caso se puede especificar si es un semforo compartido o no (por otros procesos).
28
Temporizadores en OS/2
En muchos casos, un programa necesita perder tiempo, esto es, esperar unos segundos sin hacer nada, o similar. Un sistema muy usado en programas DOS consiste en un bucle de espera, que tarde justo el tiempo que nos interesa. Sin embargo, este sistema es bastante imperfecto, pues si el programa funciona bien en un ordenador concreto, en otro que sea ms rpido o ms lento no lo har. La segunda solucin que 'encontraron' los programadores fue usar el timer del ordenador, un integrado que puede ser programado para que provoque interrupciones cada n milisegundos. Como ese chip es el mismo en todos los PCs, sin importar su velocidad, permite que los programas funcionen igual en todos. En OS/2, sin embargo, no se puede permitir esto, pues puede haber mltiples programas que necesiten el temporizador a la vez. Para solucionarlo, surgen los temporizadores. Antes de nada, conviene sealar que los temporizadores de OS/2 (as como los de cualquier otro S.O. multitarea) no son todo lo precisos que sera deseable. Esto se debe en primer lugar a que, aunque especifiquemos la temporizacin al milisegundo, ser redondeado al ciclo superior del conmutador de tareas (en OS/2, normalmente, son 32 milisegundos). Por otro lado, OS/2 es un Sistema Operativo multitarea por prioridades, por lo que puede ocurrir que en el momento en que expire un temporizador, haya otro proceso de ms prioridad esperando a ejecutarse, en cuyo caso se producir otro retardo. Sin embargo, existen maneras de minimizar estos efectos, y OS/2 las ofrece. Una primera clasificacin de los temporizadores los divide en sncronos y asncronos. Un temporizador sncrono se activa y no devuelve el control al thread hasta que este termine. Es el caso ms bsico: si queremos hacer una pausa de 1 segundo, llamamos a la funcin DosSleep, y el thread correspondiente se dormir durante el tiempo fijado. DosSleep Sin embargo, puede no interesarnos este sistema, sino que durante ese intervalo podemos necesitar hacer alguna operacin y luego dormirnos hasta terminarlo. Por ejemplo, queremos un programa que, una vez por segundo, imprima un carcter en pantalla. Una primera idea sera imprimir un carcter, dormir un segundo, imprimir otro, dormir un segundo, etc. Sin embargo, el hecho de imprimir el carcter consume algo de tiempo, luego estamos gastando algo ms. Por otro lado, ese tiempo es variable, en funcin de la velocidad del ordenador y de la tarjeta grfica. Por eso existen los temporizadores asncronos. Un temporizador asncrono necesita de un semforo, pues lo necesita para notificar al thread que se ha acabado el intervalo de tiempo. La idea es la siguiente: el thread inicializa el temporizador, el cual activa el semforo y empieza
Manual de programacin de OS/2 a contar, pero devuelve el control al programa. Este sigue trabajando (imprimira el carcter o lo que tuviese que hacer), y cuando termine, espera a que el semforo se active (post) (que ser hecho por el temporizador cuando expire). De este modo, no importa cuanto dure el proceso que haga el thread: siempre esperar un segundo (o el tiempo elegido, redondeado al ciclo del conmutador de tareas). DosAsyncTimer Como decamos, la temporizacin no es precisa por estar redondeada a 32 milisegundos. Esto puede ser problemtico cuando se encadenan temporizaciones. En el ejemplo anterior, si programamos un temporizador para cada segundo, la ejecucin de la instruccin cada vez ya lleva algo de tiempo, y adems, los redondeos se van sumando cada vez ms, de modo que podemos llegar a tener un desfase entre el ritmo que debera llevar y el que lleva realmente. Para eso, existe otro temporizador asncrono que borra un semforo no una vez, sino constantemente, a cada paso del ciclo. Es este el que deberamos usar en nuestro ejemplo. Este temporizador, como es cclico (est contando constantemente intervalos del tiempo que queramos, y no una sola vez como haca el primero) puede tener en cuenta el redondeo del conmutador de tareas, y minimizar su efecto. DosStartTimer DosStopTimer Por ltimo, tenemos las funciones de fecha y hora, las cuales permiten obtener y cambiar estos datos. Un detalle importante es que solo existe una fecha y una hora. Esto significa que si un programa los cambia, lo hace para todos, no solo para l mismo. DosGetDateTime DosSetDateTime
29
Cauces
Otra manera de intercambiar informacin son los cauces (pipes). En OS/2 existen dos tipos: con nombre (named pipes) y sin nombre (unnamed pipes). Los cauces son vistos por el programador como un fichero ms, en el que, o bien puede leer, o bien escribir. La cuestin es que un extremo pertenece a un thread y el otro a otro distinto, y si uno de ellos escribe en ese fichero (recordemos que el sistema de archivos de OS/2, al igual que el de cualquier otro S.O., consigue que no sepamos diferenciar cuando trabajamos con un fichero de disco, con un cauce, o con la pantalla), cuando el otro lea, encontrar los datos grabados. Podramos definirlo como una tubera (la cual es otra de las traducciones que he encontrado en algunos libros) que conecta los dos threads, y que se maneja con las mismas ordenes que el sistema de ficheros: DosRead, DosWrite y DosClose. Cuando creamos una unnamed pipe, el sistema nos devuelve dos handles o indicativos: uno para lectura y otro para escritura. El thread que cre el cauce debe quedarse con uno, y enviar el otro al otro thread. Para ello puede usar un pequeo bloque de memoria compartida, definiendo claramente como acceder a ella. Dado que los dems threads van a acceder solo en lectura, no hara falta incluir un semforo.
Manual de programacin de OS/2 Los cauces tienen una opcin muy interesante (y til), que consiste en la posibilidad de duplicar handles. Usando la llamada DosDupHandle, se pueden crear dos handles para un mismo cauce. Lo interesante es que se puede dar no solo el siguiente nmero libre, sino el que se quiera. Haciendo esto, se puede asignar a un cauce el valor 0 y a otro el 1, y redirigir as la entrada y salida estndar (STDIN y STDOUT) del programa en curso. Esto es precisamente lo que hace el interprete de comandos de OS/2 para hacer la redireccin desde la lnea de comandos. DosCreatePipe DosDupHandle En las versiones 1.x de OS/2 solo existan estos cauces; sin embargo, su potencia quedaba ligeramente oscurecida por el hecho de tener que usar memoria compartida para pasar un handle al otro thread. Para evitarlo, se aadieron en OS/2 2.0 y superiores las named pipes, o cauces con nombre (denominacin horrible a mas no poder. Espero sugerencias para una posible traduccin). En estos, al crearlos se les asigna un nombre del tipo \PIPE\un_nombre. Dentro de un_nombre puede ir cualquier cadena. Ejemplos vlidos son \PIPE\EJEMPLO, \PIPE\CURSO\OS2\EJEMPLO_DE_PIPE. Cuando un thread cualquiera quiere acceder a ese cauce, solo tiene que referirse a l por dicho indicativo. Esto resulta mucho ms cmodo, pues basta con fijar durante la programacin el nombre que se le va a dar, y no hace falta pasarlo de forma dinmica en cada ejecucin. Sin embargo, adems de crearlo, es necesario que el proceso servidor lo haga disponible a los clientes. DosCreateNPipe DosConnectNPipe DosDisConnectNPipe Para que un cliente acceda a una named pipe, tiene que usar DosOpen, usando como nombre de fichero el nombre de la pipe. El segundo parmetro es un puntero a una variable de tipo HPIPE, que contendr un handle que podremos usar con DosRead, DosWrite y DosClose para manejar la pipe. El tercer parmetro contendr un puntero a un ULONG, en el cual se almacenar la causa por la que no se ha podido abrir la pipe (es mejor usar los cdigos de error que se devuelven de la forma normal en vez de ste valor). El cuarto parmetro contiene la longitud del buffer que se reservar. Es conveniente que tenga un tamao ms bien grande. El resto de parmetros son particularizaciones para las pipes de los parmetro normales de DosOpen. Se debe tener cuidado al definir las named pipes. Hay que tener en cuenta que el servidor tiene ciertos privilegios que el cliente no tiene, como por ejemplo disponer de un semforo que le indique cuando hay datos en el cauce. Un cliente tendra que hacer una espera activa en el caso de querer estar siempre disponible a travs de ese cauce. Por otro lado, cualquier cliente se puede conectar a una pipe, por lo que el servidor no puede saber (en principio) quien le est reclamando el servicio. Al revs s ocurre, pues todo cliente sabe quien es el servidor de un cauce determinado por el nombre de ste. DosSetNPipeSem DosQueryNPHState DosSetNPHState DosWaitNPipe DosPeekNPipe Un detalle importante es que las unnamed pipes son unidireccionales. Esto es, si se quiere intercambiar datos en ambos sentidos, son necesarios dos cauces, no se puede usar el mismo. El sentido de la comunicacin lo decide el que cree el cauce, al enviar uno u otro handle. En el caso de named pipes, por el contrario, el creador puede determinar si la comunicacin va del servidor al cliente, al revs, o en ambos sentidos.
30
31
Colas
Los cauces no siempre son la solucin ideal. En muchos casos necesitamos poder tratar elementos separados en vez de una secuencia de bytes, y adems puede ser necesario que se organicen de forma distinta a la clsica FIFO (First In First Out, el primero en entrar es el primero en salir). Incluso puede ser necesario eliminar elementos antes de que los lean los destinatarios. Para esto se crearon las colas. Una cola es similar a un cauce con nombre (named pipe), pero en vez de escribirse bytes en ella, se escriben secuencias de longitud variable que son tratadas como elementos independientes. Por ejemplo, si en un cauce introduzco la secuencia Esto es una prueba, puedo leer solo la primera letra, o las dos primeras, o unas cuantas, pero la frase ser tratada como un conjunto de elementos separados. En una cola, sin embargo, sera tratada siempre como un solo elemento. Cuando el proceso lee de la cola, leer la frase completa, y no podr leer solo un trozo, o incluso pegarlo a otro elemento introducido despus. Por otro lado, la ordenacin de los elementos en las colas es definible por el usuario. As, puede ser FIFO (First In First Out, el primero en entrar es el primero en salir), LIFO (Last In First Out, el ltimo en entrar es el primero en salir), o bien por prioridades. Un ejemplo del primer tipo de colas sera una cola de un cine: el primer espectador que llega ser el primero en obtener la entrada, y as sucesivamente. Un ejemplo del segundo tipo de colas sera una pila de revistas. Cuando pongo una nueva, la aado en la cima, y cuando cojo una, cojo la que est arriba de todo: la ltima en llegar es la primera en salir. Por ltimo, un ejemplo de una cola con prioridad podra ser una recepcin oficial. No importa el orden en que lleguen los dignatarios; estos siempre saldrn en orden descendente de rangos: primero el presidente invitado, luego el del pas, luego ministros, etc. Y si mientras salen, llega algn rezagado, todos los de rango inferior le cedern su sitio. Las colas se denominan, como viene siendo habitual, con un nombre propio, que es de la forma \QUEUES\nombre_de_la_cola, con nombre_de_la_cola un nombre que la define. Dado que las colas no trabajan con secuencias de bytes individuales sino con mensajes discretos, no usan las llamadas del sistema de archivos, sino que disponen de su propio conjunto de instrucciones para leer y escribir en ellas. DosCreateQueue DosOpenQueue DosReadQueue DosWriteQueue DosQueryQueue DosCloseQueue Solo el proceso que crea la cola tiene la capacidad de eliminarla o de purgar (borrar) sus elementos, as como de leer de ella; sin embargo, cualquier otro proceso puede tener acceso a ella en el sentido de escribir. An ms interesante resulta el hecho de que es posible saltarse el orden normal de la cola y leer un elemento situado en una posicin concreta. As mismo, es posible hacer una lectura sncrona, en la cual se espera hasta que aparezca un elemento (si no haba ninguno) o bien una lectura asncrona, usando un semforo, en la cual se pueden seguir haciendo operaciones y resincronizar cuando se desee, de forma similar a los temporizadores. Sin embargo, hay algunas restricciones en este caso: el semforo debe ser abierto por todos los procesos que llaman a DosWriteQueue para aadir un elemento a la cola. Tambin es posible buscar en la cola un elemento concreto y examinarlo, pero sin eliminarlo de la cola. Adems podemos saber el nmero de elementos que contiene la cola. DosPeekQueue DosPurgeQueue
Manual de programacin de OS/2 El trabajo con colas es distinto que con los cauces. En los primeros, definimos una ristra de bytes que deben ser enviados a los procesos. Aqu, sin embargo, nos limitamos a enviar un puntero, el cual ser el que le llegue a los dems en el orden adecuado. Los datos a enviar son almacenados en zonas de memoria compartidas. Para verlo ms claro, veamos como haramos para enviar varios mensajes a travs de una cola: En primer lugar, necesitamos definir una serie de bloques de memoria compartidos, dando acceso a ellos al proceso dueo de la cola, si es necesario. En segundo lugar, almacenamos el primer mensaje en uno de los bloques, y lo escribimos en la cola dando como puntero del mensaje el que apunta a dicho bloque. El proceso dueo, cuando reciba el mensaje de la cola, recibir nicamente el puntero a ste, accediendo realmente en el bloque de memoria compartida. Cuando se ha terminado con la cola, se libera sta y los bloques de memoria compartida. Vemos, por tanto, que la cola no transmite realmente los mensajes, sino simplemente el orden en que se debe acceder a ellos, pues estos estn siempre accesibles a todos los procesos por estar en memoria compartida. Dado que la asignacin de bloques de memoria es un proceso relativamente lento, la mejor solucin consiste en subasignar bloques de memoria, uno para cada mensaje, dentro de un bloque mayor de memoria compartida.
32
Apndice A
1. /Llamadas DOSxxx del sistema de ficheros/ 2. /Llamadas DOSxxx para multitarea/ 3. /Llamadas DOSxxx para gestin de sesiones/ 4. /Llamadas DOSxxx para gestin de memoria/ 5. /Llamadas DOSxxx para semforos/ 6. /Llamadas DOSxxx para temporizadores/ 7. /Llamadas DOSxxx para cauces (pipes)/ 8. /Llamadas DOSxxx para colas/ 9. /Llamadas VIOxxx para acceso a la pantalla/ 10. /Llamadas KBDxxx para acceso al teclado/ 11. /Llamadas MOUxxx para acceso al ratn /
Apndice B
1. /Apendice B - cdigos de error de OS/2/ asdasdasdss
Referencias
[1] http:/ / www. rastersoft. com/ OS2/ CURSO/ INDICE. HTM
33
Licencia
Creative Commons Attribution-Share Alike 3.0 Unported http:/ / creativecommons. org/ licenses/ by-sa/ 3. 0/