8.9.- Los overlays Un overlay es parte de un programa que normalmente no reside en la memoria sino en disco hasta que se le necesita. Cuando eso ocurre la parte llamada se carga en el mismo espacio que ocupaba la anterior, lo que significa que con esta tecnica se pueden ejecutar programas masivos con una cantidad de memoria relativamente pequenia. Pero todo tiene un precio... los accesos frecuentes al disco provocaran que el sistema funciona bastante mas lento que si se cargara todo en memoria de una sola vez. La gestion de los overlays (localizacion del buffer, su carga etc) es realizada totalmente por turbo pascal, asi nosotros debemos indicarle a el, que unidades queremos que funcionen como overlays y turbo pascal se encargara del resto. Normalmente turbo pascal le da al buffer de overlay la cantidad que necesite la mayor de todas las unidades, aunque puede indicarse el tamanio del buffer si es preciso. Turbo Pascal colocara el buffer de overlay al final del programa ejecutable. Veamos como preparar un programa para usar overlays: PROGRAM OVERLAYS; {$F+} (* TODA LLAMADA A PROCEDIMIENTOS DEBE SER LEJANA *) (* EN UN PROGRAMA QUE USA OVERLAYS. *) USES OVERLAY,UNIDAD1,UNIDAD2,UNIDAD3,UNIDAD4,UNIDAD5; {$O UNIDAD2} (* PERMITE A ESTAS ACTUAR COMO OVERLAYS *) {$O UNIDAD5} El programa que acabamos de escribir permite que unidad2 y unidad5 funcionen como overlays, pero las demas unidades funcionaran de forma normal, ademas un programa que use overlays debe hacer llamadas lejanas en todos sus procedimientos, para ello se coloca la directiva {$F+} al principio del programa, cada unidad que se quiera convertir en overlay debe indicar con la directiva {$ }, adicionalmente la unidad overlay debe ser la primera en nombrarse para que turbo pascal pueda inicializar el gestor de overlays antes de convertir en overlay cualquier cosa. Parecen ser muchos requisitos pero faltan dos mas, en el programa fuente de cada unidad que se quiera convertir en overlay debe aparecer la directiva {$F+,O+} y ademas se requiere inicializar el gestor de overlays con ovrinit. Un ejemplo sencillo de esto: {$F+} PROGRAM OVERLAYS; USES OVERLAY,USACRT,OTRO; {$O USACRT} BEGIN OVRINIT ('NOMPROG.OVR'); (* EL NOMBRE DEL ARCHIVO DE OVERLAY *) BORRA; (* ES IGUAL AL DEL EJECUTABLE,SALVO *) ESCRIBE; (* POR LA EXTENSION .OVR. *) END. Ahora el listado de las unidades. {$F+} UNIT OTRO; (* ESTA NO FUNCIONA COMO OVERLAY *) INTERFACE (* PUESTO QUE FALTA LA DIRECTIVA {$O+} *) PROCEDURE ESCRIBE; IMPLEMENTATION PROCEDURE ESCRIBE; BEGIN WRITELN ('HOLA'); END; END. La unidad usacrt si funcionara como overlay; UNIT USACRT; {$F+,$O+} INTERFACE { CADA UNIDAD DEBE SER COMPILADA } { CON CODIGOS DE LLAMADA LEJANOS } PROCEDURE BORRA; IMPLEMENTATION USES CRT; PROCEDURE BORRA; BEGIN CLRSCR; END; END. Alguna vez querra diseniar un sistema con overlays, en este caso es importante verificar todos los posibles errores cuando se trabaja con ellos. La llamada a ovrinit dara los siguientes codigos de error cuando existen problemas: Ovrok = 0; Ovrerror = -1; Ovrnotfound = -2; Ovrnomemory = -3; Ovrioerror = -4; Ovrnoemsdriver = -5; Ovrnoemsmemory = -6; Y la constante ira a caer en la variable ovrresult. Esta demas decir que una buena aplicacion debe considerar todas las posibilidades de error. 8.9.1.-Otros procedimientos en la unidad overlay -Ovrclearbuf: Limpia el buffer de overlay. El espacio puede ser utilizado por una aplicacion sin overlays para almacenamiento temporal. -Ovrgetbuf: Nos devuelve un longint que indica la cantidad de memoria que se utilizara para el buffer de overlay. -Ovrinitems: Basta llamar a este procedimiento y los solapamientos se cargaran en la memoria expandida si pueden hacerlo, ademas recuerde que la memoria expandida es solo un poco mas lenta que la ram dos (debido al overhead que se produce en la mapeo de un area de memoria real a un bloque de 64k en la memoria convencional), esto significa que con este metodo se sobrepasa el limite de los 640k. -Ovrsetbuf(x): En "x" debe mandarsele la cantidad que se quiere tener como buffer de overlay, este debe ser mayor que la cantidad minima que reserva para si por defecto, y ademas debe ser menor que todo lo que quede en el heap (vease maxavail), para ello el heap debe estar sin variables dinamicas. 8.9.2.- Algunos problemas con los overlay Si define una unidad con manejadores de interrupciones, jamas debe convertirla en overlay puesto que puede ocurrir una interrupcion cuando el codigo que la gestiona no esta en la memoria, lo cual producira sin duda la caida del sistema. Tampoco debe convertir en overlay la propia unidad overlay puesto que es el mismo el que iniciliza la gestion de overlays. Cuando existe codigo de inicializacion en algunas unidades que funcionaran como overlays, no se puede hacer uses overlay en el programa principal, porque el gestor de los overlays debe ser instalado antes que cualquier unidad funcione como overlay (y como usted sabe la seccion de inicializacion es lo primero que se ejecuta en un programa). La solucion a esto es sencilla; cree una unidad vacia (sin la directiva {$O+} o sea que no sea overlay) solo con codigo de inicializacion, inicialice el gestor alli mismo y pongala antes que todo, por ejemplo: UNIT INSTALA; INTERFACE; USES OVERLAY; IMPLEMENTATION BEGIN OVRINIT ('NOMPROG.OVR'); END. y en el programa principal: USES INSTALA,UNIDAD1,ETC.... Como hemos podido apreciar los overlays en turbo pascal son de los mas sencillos de utilizar, todo ello debido a que Borland basa todo su sistema de overlays en la sofisticada tecnica VROOMM (virtual run-time object oriented memory manager) para gestion de memoria para todos sus lenguajes de programacion tales como el Borland C++ 3.0, Turbo Pascal etc. .