/*
 * $Id: garbage.txt 6072 2003-07-13 14:51:56Z alex_degarate $
 */

/*
 * Las siguientes partes son derechos adquiridos de sus autores individuales.
 * www - http://www.harbour-project.org
 *
 * Copyright 2000 Alejandro de Grate <alex_degarate@hotmail.com>
 * Documentacin en Espaol de:
 *         Readme, hb_gcAlloc(), hb_gcFree(), hb_gcLockItem(),
 *         hb_gcUnlockItem(), hb_gcCollectAll(), hb_gcItemRef(), HB_GCALL()
 *
 * Copyright 2000 brian Brian Hays <bhays@abacuslaw.com>
 * Documentacin en Ingls de:
 *         Readme, hb_gcAlloc(), hb_gcFree(), hb_gcLockItem(),
 *         hb_gcUnlockItem(), hb_gcCollectAll(), hb_gcItemRef(), HB_GCALL()
 *
 * Vea doc/license.txt por los trminos de la licencia.
 *
 */


/*  $DOC$
 *  $FUNCNAME$
 *      Colector de memoria
 *  $CATEGORY$
 *      Documento
 *  $ONELINER$
 *      Lame con informacin de la recoleccin de memoria.
 *  $DESCRIPTION$
 *      El recolector de memoria (Garbage Collector  GC) usa la siguiente
 *      lgica:
 *      - primero recolectar todas las ubicaciones de memoria que puedan
 *        constituirse en "basura"
 *      - luego inspeccionar todas las variables, por si esos bloques estn
 *        todava referenciados.
 *
 *      Note que slo arrays, objetos y bloques de cdigo son recolectados
 *      porque esos son los nicos tipos de datos que pueden causar:
 *      auto-referencias
 *            ( a [1] : = a )
 *       referencias circulares:
 *            ( a[1] := b; b[1] := c; c[1] := a )
 *      que no pueden ser apropiadamente desasignadas por un simple conteo
 *      de referencia.
 *
 *      Como todas las variables en Harbour son almacenadas dentro de algunas
 *      tablas disponibles (eval stack, tabla de memvars y array de variables
 *      estticas), entonces chequear si la referencia es todava activa es
 *      bastante fcil y no requiere ningn tratamiento especial durante la
 *      la asignacin de memoria. Adicionalmente el recolector de memoria
 *      inspecciona algunos datos internos usados por la implementacin de
 *      objetos de Harbour que tambin almacena algunos valores que pueden
 *      contener referencias de memoria. Estos datos son usados para inicia-
 *      lizar variables de instancia de la clase, y son almacenadas en
 *      variables compartidas por la clase.
 *
 *      En casos especiales cuando el valor de una variable de Harbour es
 *      almacenada internamente en algn area esttica (a nivel de lenguaje
 *      C  asembler), por ejemplo SETKEY() almacena bloques de cdigo que
 *      sern evaluados cuando se presione una tecla, el recolector de
 *      memoria no ser capaz de inspeccionar esos valores porque este no
 *      conoce su ubicacin. Esto podra ocasionar que algunos bloques de
 *      memoria sean liberados prematuramente. Para prevenir la prematura
 *      desasignacin de esos bloques ellos deben ser bloqueados para el
 *      recolector de memoria.
 *
 *      Para ello se definen distintos estados del bloque de memoria:
 *
 *      #define HB_GC_UNLOCKED   0  // desbloqueado
 *      #define HB_GC_LOCKED     1  // No recolectar el bloque de memoria
 *      #define HB_GC_USED_FLAG  2  // bit para la bandera usado/no usado
 *
 *      El bloque de memoria puede ser bloqueado con hb_gcLockItem(), mtodo
 *      recomendado si un tem de estructura es usado  con la funcin
 *      hb_gcLock() si un puntero directo a memoria es usado.
 *      El bloque de memoria puede ser desbloqueado por hb_gcUnlockItem() 
 *      hb_gcUnlock().
 *
 *      Ntese sin embargo que todas las variables pasadas a una funcin de
 *      bajo nivel son pasadas mediante la pila de evaluacin (eval stack),
 *      as ellas no necesitan bloquearse durante la llamada a la funcin.
 *      El bloqueo puede ser requerido, si un valor pasado es copiado dentro
 *      de algn rea esttica para hacerla disponible para otras funciones
 *      de bajo nivel, llamadas despus de la salida de la funcin que
 *      almacena el valor. Esto es requerido porque el valor es removido de
 *      la pila de evaluacin despus de la llamada a la funcin y esta no
 *      puede seguir siendo referenciada por otras variables.
 *
 *      Sin embargo la inspeccin de todas las variables puede ser una
 *      operacin de un gran consumo de tiempo. Esto requiere que todos los
 *      arrays asignados tengan que ser recorridos a travs de todos sus
 *      elementos para encontrar ms arrays.
 *      Tambin todos los bloques de cdigo son inspeccionados, en busca de
 *      variables locales separadas que ellos estan referenciando. Por esta
 *      esta razn, la busqueda por bloques de memoria no referenciados es
 *      realizada durante los estados inactivos.
 *
 *      El estado inactivo es el estado cuando no hay un cdigo real de la
 *      aplicacin ejecutndose. Por ejemplo, el cdigo del usuario es
 *      detenido durante 0.1 segundo por INKEY(0.1) - Harbour esta chequeando
 *      slo el teclado durante este tiempo. Esto deja sin embargo suficiente
 *      tiempo para muchas otras tareas en segundo plano. Una de esas tareas
 *      en segundo plano, puede ser la bsqueda de bloques de memoria no
 *      referenciados.
 *
 *      Asignando memoria </par>
 *      -----------------
 *
 *      El recolector de memoria, recoge bloques de memoria asignados con
 *      llamadas a la funcin hb_gcAlloc().   La memoria asignada por
 *      hb_gcAlloc() debera ser liberada con la funcin hb_gcFree().
 *
 *
 *      Bloqueando memoria  </par>
 *      ------------------
 *
 *      La memoria asignada con hb_gcAlloc() debera ser bloqueada para
 *      prevenir una automtica liberacin como un puntero de memoria si no
 *      es almacenado dentro de una variable a nivel de Harbour. Todos los
 *      valores de Harbour (items), almacenados internamente en reas
 *      estticas de lenguaje C deben ser bloqueadas.
 *      Vea hb_gcLockItem() y hb_gcUnlockItem() para ms informacin.
 *
 *
 *      La recolecin de memoria  </par>
 *      ------------------------
 *
 *      Durante la bsqueda de memoria no referenciada, el recolector de
 *      memoria (RM) est usando un algoritmo llamado "mark & sweep", marcar
 *      y barrer. Este es realizado en tres etapas:
 *
 *      1) Marcar todos los bloques asignados por el RM con un bandera:
 *      "sin uso"
 *
 *      2) barrer (buscar) todos los lugares conocidos y limpiar las banderas
 *      sin uso por los bloques de memoria que son referenciados all;
 *
 *      3) finalizar recolectando por desasignacin de todos los bloques de
 *      memoria que an estan marcados como sin uso y que no estn bloqueados.
 *
 *      Para acelerar las cosas un poco, la etapa de marca es simplificada
 *      por la inversin del significado de la bandera "sin uso". Despus de
 *      la desasignacin de los bloques sin uso, todos los bloques todava
 *      activos son marcados con la bandera "usado" as nosotros podemos
 *      invertir el significado de esta bandera al estado "sin uso" en la
 *      prxima recolecin.
 *      Todos los bloques de memoria nuevos  sin bloquear son automtica-
 *      mente marcados como "sin uso" usando la bandera actual, lo cual
 *      asegura que todos los bloques de memoria son marcados con la misma
 *       bandera antes de que la etapa de barrido comience.
 *
 *      Ver hb_gcCollectAll() y hb_gcItemRef()
 *
 *
 *      Llamando al recolector de memoria desde cdigo Harbour
 *      ------------------------------------------------------
 *
 *      El RM puede ser llamado directamente desde un programa en Harbour.
 *      Esto es til en situaciones donde no hay estados inactivos
 *      disponibles  la aplicacin esta trabajando en un bucle sin
 *      interaccin con el usuario y hay muchas asignaciones de memoria.
 *      Vea HB_GCALL() por una explicacin de como llamar a esta funcin
 *      desde el cdigo de Harbour.
 *  $SEEALSO$
 *      hb_gcAlloc(),hb_gcFree(),hb_gcLockItem(),hb_gcUnlockItem(),hb_gcCollectAll(),hb_gcItemRef(),HB_GCALL(),HB_IDLESTATE()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      hb_gcAlloc()
 *  $CATEGORY$
 *      Colector de memoria
 *  $ONELINER$
 *      Asigna memoria que ser recolectada por el recolector de memoria.
 *  $SYNTAX$
 *      #include <hbapi.h>
 *      void *hb_gcAlloc( ULONG ulSize, HB_GARBAGE_FUNC_PTR pCleanupFunc );
 *  $ARGUMENTS$
 *      <ulSize>  es el tamao solicitado del bloque de memoria.
 *
 *      <pCleanupFunc> es un Puntero a la funcin HB_GARBAGE_FUNC que ser
 *                     llamada directamente antes de la liberacin del bloque
 *                     de memoria sin uso  NULL. Esta funcin debera
 *                     liberar toda otra memoria asignada y almacenada dentro
 *                     del bloque de memoria.
 *      Por ejemplo, esta libera todos los items almacenados dentro del array
 *      La funcin recibe un slo parmetro: el puntero a la memoria asignada
 *      por hb_gcAlloc().
 *  $RETURNS$
 *      Devuelve un puntero a la memoria asignada  esta generar un error
 *      interno irrecuperable.
 *  $DESCRIPTION$
 *      hb_gcAlloc() es usada para asignar la memoria que ser rastreada por
 *      el RM. Este permite una apropiada liberacin de memoria en el caso
 *      de variables auto-referenciadas  con referencias cruzadas a nivel
 *      de Harbour.
 *      La memoria asignada con esta funcin debera ser liberada con la
 *      funcin hb_gcFree()  esta ser automticamente desasignada por el
 *      RM si no esta bloqueada  si no esta referenciada por alguna
 *      variable a nivel de Harbour.
 *  $EXAMPLES$
 *      Vea  ../source/vm/arrays.c
 *
 *     PHB_BASEARRAY pArr = (PHB_BASEARRAY) :
 *                           hb_gcAlloc( sizeof( HB_BASEARRAY), ;
 *                                       hb_arrayReleaseGarbage );
 *  $STATUS$
 *      C
 *  $COMPLIANCE$
 *      Esta funcin es una extensin de Harbour.
 *  $PLATFORMS$
 *      Todas
 *  $FILES$
 *      Archivo fuente: ../source/vm/garbage.c
 *  $SEEALSO$
 *      hb_gcFree(),hb_gcLockItem(),hb_gcUnlockItem()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      hb_gcFree()
 *  $CATEGORY$
 *      Colector de memoria
 *  $ONELINER$
 *      Libera la memoria que fu asignada con hb_gcAlloc().
 *  $SYNTAX$
 *      void hb_gcFree( void *pMemoryPtr );
 *  $ARGUMENTS$
 *      <pMemoryPtr> es el puntero a la memoria a liberar. Este puntero de
 *                   memoria debe ser asignado con la funcin hb_gcAlloc().
 *  $RETURNS$
 *      Nada.
 *  $DESCRIPTION$
 *      La funcin hb_gcFree() es usada para liberar la memoria que fu
 *      asignada con la funcin hb_gcAlloc().
 *  $EXAMPLES$
 *      Vea ../source/vm/arrays.c
 *      hb_gcFree( (void *) pBaseArray );  // puntero al array a liberar
 *  $STATUS$
 *      C
 *  $COMPLIANCE$
 *      Esta funcin es una extensin de Harbour.
 *  $PLATFORMS$
 *      Todas
 *  $FILES$
 *      Archivo fuente: ../source/vm/garbage.c
 *  $SEEALSO$
 *      hb_gcAlloc(),hb_gcLockItem(),hb_gcUnlockItem()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      hb_gcLockItem()
 *  $CATEGORY$
 *      Colector de memoria
 *  $ONELINER$
 *      Bloquea la memoria para prevenir la desasignacin por el RM.
 *  $SYNTAX$
 *      void hb_gcLockItem( HB_ITEM_PTR pItem );
 *  $ARGUMENTS$
 *      <pItem>  es el puntero a la estructura item que ser bloqueada.
 *               El item pasado puede ser de cualquier tipo de datos, aunque
 *               arrays de objetos y bloques de cdigos son bloqueados
 *               solamente. Otros tipos de datos no necesitan bloqueo, as
 *               que ellos son simplemente ignorados.
 *  $RETURNS$
 *      Nada.
 *  $DESCRIPTION$
 *      La funcin hb_gcLockItem() es usada para bloquear el puntero de
 *      memoria almacenado en la estructura item pasada. Este suprime la
 *      liberacin de memoria si el RM no encuentra alguna referencia a
 *      este puntero.
 *      El RM almacena un contador de bloqueo y cada llamada a esta funcin
 *      incrementa el contador. El item es bloqueado si el contador es mayor
 *      que cero.
 *  $EXAMPLES$
 *      Vea ../source/rtl/setkey.c
 *      // bloquea un codeblock para prevenir la liberacin por el RM
 *      hb_gcLockItem( sk_list_tmp-> pAction );
 *  $STATUS$
 *      C
 *  $COMPLIANCE$
 *      Esta funcin es una extensin de Harbour.
 *  $PLATFORMS$
 *      Todas
 *  $FILES$
 *      Archivo fuente: ../source/vm/garbage.c
 *  $SEEALSO$
 *      hb_gcAlloc(),hb_gcFree(),hb_gcUnlockItem()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      hb_gcUnlockItem()
 *  $CATEGORY$
 *      Colector de memoria
 *  $ONELINER$
 *      Desbloquea la memoria para prevenir la liberacin por el RM
 *  $SYNTAX$
 *      void hb_gcUnlockItem( HB_ITEM_PTR pItem );
 *  $ARGUMENTS$
 *      <pItem>  es el puntero a la estructura item que ser bloqueada.
 *               El item pasado puede ser de cualquier tipo de datos, aunque
 *               arrays de objetos y bloques de cdigos son bloqueados
 *               solamente. Otros tipos de datos no necesitan bloqueo as
 *               que ellos son simplemente ignorados.
 *  $RETURNS$
 *      Nada.
 *  $DESCRIPTION$
 *      La funcin hb_gcUnlockItem() es usada para desbloquear el puntero de
 *      memoria almacenado en la estructura item pasada, que fu previamente
 *      bloqueada con una llamada a hb_gcLockItem(). Esto permite liberar
 *      la memoria durante la recoleccin de memoria sin uso si el RM no
 *      encuentra ninguna referencia a este puntero. El RM almacena el
 *      contador de bloqueo, cada llamda a esta funcin decrementa el
 *      contador.
 *      Esta funcin no libera la memoria almacenada dentro del item,
 *      la memoria debe ser desasignada sin embargo durante la recolecin
 *      de memoria sin uso ms cercana, si el contador de bloqueo es
 *      igual a cero y el puntero de memoria no es referenciado por
 *      ninguna variable a nivel de Harbour.
 *  $EXAMPLES$
 *      Vea ../source/rtl/setkey.c
 *      hb_gcUnlockItem( sk_list_tmp-> pAction );  // libera el item
 *  $STATUS$
 *      C
 *  $COMPLIANCE$
 *      Esta funcin es una extensin de Harbour.
 *  $PLATFORMS$
 *      Todas
 *  $FILES$
 *      Archivo fuente: ../source/vm/garbage.c
 *  $SEEALSO$
 *      hb_gcAlloc(),hb_gcFree(),hb_gcLockItem()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      hb_gcCollectAll()
 *  $CATEGORY$
 *      Colector de memoria
 *  $ONELINER$
 *      Examina todos los bloques de memoria y libera la memoria sin uso.
 *  $SYNTAX$
 *      void hb_gcCollectAll( void );
 *  $ARGUMENTS$
 *      Ninguno.
 *  $RETURNS$
 *      Nada.
 *  $DESCRIPTION$
 *      Esta funcin examina la pila de evaluacin, las tablas de memvars,
 *      el array de variables estticas y las tablas de clases creadas en
 *      busca de bloques de memoria referenciados. Despus de examinar todos
 *      los bloques de memoria sin uso y los bloques que no estan bloqueados,
 *      son liberados.
 *  $STATUS$
 *      C
 *  $COMPLIANCE$
 *      Esta funcin es una extensin de Harbour.
 *  $PLATFORMS$
 *      Todas
 *  $FILES$
 *      Archivo fuente: ../source/vm/garbage.c
 *  $SEEALSO$
 *      hb_gcAlloc(),hb_gcFree(),hb_gcLockItem(),hb_gcUnlockItem()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      hb_gcItemRef()
 *  $CATEGORY$
 *      Colector de memoria
 *  $ONELINER$
 *      Marca la memoria para prevenir la desasignacin por el RM.
 *  $SYNTAX$
 *      void hb_gcItemRef( HB_ITEM_PTR pItem );
 *  $ARGUMENTS$
 *      <pItem>  es el puntero a la estructura item que ser examinada.
 *               El item pasado puede ser de cualquier tipo de datos, aunque
 *               arrays de objetos y bloques de cdigos son bloqueados
 *               solamente. Otros tipos de datos no necesitan bloqueo as
 *               que ellos son simplemente ignorados.
 *  $RETURNS$
 *      Nada.
 *  $DESCRIPTION$
 *      El recolector de memoria usa la funcin hb_gcItemRef() durante la
 *      inspeccin de punteros de memoria referenciados.
 *      Esta funcin chequea el tipo del item pasado y examina recursivamente
 *      todos los otros bloques de memoria referenciados por este item, si
 *      ste es un array un objeto  un bloque de cdigo
 *
 *      NOTA: Esta funcin es reservada para el recolector de memoria (RM)
 *            solamente. Esta NO debe ser llamada desde el cdigo del usuario
 *            llamarla puede causar resultados impredecibles (bloques de
 *            memoria referenciados por el item pasado pueden ser liberados
 *            prematuramente durante la recolecin de memoria ms cercana).
 *  $STATUS$
 *      C
 *  $COMPLIANCE$
 *      Esta funcin es una extensin de Harbour.
 *  $PLATFORMS$
 *      Todas
 *  $FILES$
 *      Archivo fuente: ../source/vm/garbage.c
 *  $SEEALSO$
 *      hb_gcAlloc(),hb_gcFree(),hb_gcLockItem(),hb_gcUnlockItem()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      HB_GCALL()
 *  $CATEGORY$
 *      Colector de memoria
 *  $ONELINER$
 *      Inspecciona la memoria y libera los bloques de memoria sin uso
 *  $SYNTAX$
 *      HB_GCALL()
 *  $ARGUMENTS$
 *      Ninguno
 *  $RETURNS$
 *      NIL
 *  $DESCRIPTION$
 *      Esta funcin libera todos los bloques de memoria que son considerados
 *      como "basura".
 *  $STATUS$
 *      Harbour
 *  $COMPLIANCE$
 *      Esta funcin es una extensin de Harbour.
 *  $PLATFORMS$
 *      Todas
 *  $FILES$
 *      Archivo fuente: ../source/vm/garbage.c
 *  $SEEALSO$
 *      hb_gcCollectAll()
 *  $END$
 */  


