File:  [Repository ATC2] / ADD_ver_10 / Source Code / Source Files / Main.c
Revision 1.2: download - view: text, annotated - select for diffs
Tue Feb 28 14:54:21 2006 UTC (18 years, 8 months ago) by rico
Branches: MAIN
CVS tags: HEAD
*** empty log message ***

/********************************************************************/
/*  Main.c                                                          */
/*                                                                  */
/*                                                                  */
/*  Copyright (c) 1997-2006 Rafael Rico      (rafael.rico@uah.es)   */
/*                                                                  */
/*  Este fichero forma parte de ADD                                 */
/*  (Analizador de Dependencias de Datos)                           */
/*  Version 5.10.                                                   */
/*                                                                  */
/*                                                                  */
/*  ADD es software libre. Puede redistribuirlo y/o modificarlo     */
/*  bajo los términos de la Licencia Pública General de GNU         */
/*  según es publicada por la Free Software Foundation, bien bajo   */
/*  la versión 2 de dicha Licencia o bien (según su elección)       */
/*  bajo cualquier versión posterior.                               */
/*                                                                  */
/*  ADD se distribuye con la esperanza de que sea útil,             */
/*  pero SIN NINGUNA GARANTÍA, incluso sin la garantía MERCANTIL    */
/*  implícita y sin garantizar la CONVENIENCIA PARA UN PROPÓSITO    */
/*  PARTICULAR. Véase la Licencia Pública General de GNU para       */
/*  más detalles.                                                   */
/*                                                                  */
/*  Debería haber recibido una copia de la Licencia Pública General */
/*  junto con ADD. Si no ha sido así, escriba a la Free Software    */
/*  Foundation, Inc., 51 Franklin St, Fifth Floor,                  */
/*  Boston, MA  02110-1301  EEUU.                                   */
/*                                                                  */
/*  -------------------------- Historia --------------------------- */
/*                                                                  */
/*  $Id: Main.c,v 1.2 2006/02/28 14:54:21 rico Exp $                                                            */
/*                                                                  */
/*  Revisión 1.2. 01/2006                                           */
/*  Se añade la licencia GPL y documentación en estilo Javadoc      */
/*                                                                  */
/*  Revisión 1.1. 09/2005                                           */
/*  Versión inicial                                                 */
/*                                                                  */
/********************************************************************/

/******************************************************************************/
/* MÓDULO: Main.c                                                             */
/*                                                                            */
/******************************************************************************/
/* Fecha: 19 de septiembre de 2005                                            */
/******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "defines.h"
#include "tipos.h"
#include "main.h"

/* configuración */
struct argumentos configuracion;

/* bases de datos */
unsigned int num_nemonicos;
operacion *nemonicos = NULL;
unsigned int num_simbolos;
operando *simbolos = NULL;

unsigned int num_tiempos;
tiempo *ciclos = NULL;

/* recuentos */
unsigned long int *contadornemonicos = NULL;
unsigned long int *contadorlecturas = NULL;
unsigned long int *contadorescrituras = NULL;

/* contadores de instrucciones y ventanas */
unsigned long instruccion, ventana;

/* otros resultados */
double cpimedio = 0.0;
double tiempoejecucion = 0.0;
unsigned long *distribucionpasos = NULL;

/* posibles ubicaciones de datos */
unsigned int num_ubicaciones;
ubicacion *datos = NULL;

/* análisis de dependencias de datos */
int *pizarra_escrituras = NULL;
int **pizarra_lecturas = NULL;

unsigned char *vector = NULL;

struct punterosD matriz;
unsigned char **matrizC = NULL;    /* matriz de caminos de dependencias */
char **OrdenParcial = NULL;        /* lista de instrucciones según orden parcial de D */

/* parámetros asociados a las matrices */ 
parametromatriz *pasos = NULL;
parametromatriz *mediapasos = NULL;
parametromatriz *grado = NULL;
parametromatriz *mediagrado = NULL;
parametromatriz *acoplo = NULL;
parametromatriz *mediaacoplo = NULL;


/* declaro aquí mismo algunas funciones sencillas para no repetir secuencias de código */

void ProcesarInstruccion(unsigned int ins, unsigned char secuencia[12], fichainstruccion *tarjetaoperandos)
{
    AnalizarOperandosIA16(secuencia, tarjetaoperandos);

    if(configuracion.recuentos == SI) ActualizarRecuentos(tarjetaoperandos);

    if(configuracion.cpi == SI) CalcularCiclosInstruccion(tarjetaoperandos);

    if(configuracion.CPImedio == SI) ActualizarCPImedio(tarjetaoperandos->ciclosALU, tarjetaoperandos->ciclosBIU);

    if(configuracion.dependencias == SI)
    {
        AnalizarDependencias(tarjetaoperandos, ins);

        AnotarEscrituras(tarjetaoperandos, ins);
        AnotarLecturas(tarjetaoperandos, ins);

        /* si tengo que calcular el tiempo de ejecución */
        /* debo construir un array con el tipo de instrucción */
        /* y su latencia en ciclos */
    }
}

void IniciarVentana()
{
    if(configuracion.dependencias == SI)
    {
        IniciarPizarras();
        IniciarVectorDependencias();
        IniciarMatricesDependencias();
        if(configuracion.ordenparcial == SI) IniciarListaOrdenParcial();
        if(configuracion.matrizcaminos == SI) IniciarMatrizCaminos();
        if(configuracion.pasoscomputacion == SI) IniciarVariableAgregada(pasos);
        if(configuracion.gradoparalelismo == SI) IniciarVariableAgregada(grado);;
        if(configuracion.acoplamiento == SI) IniciarVariableAgregada(acoplo);
    }
}

void ProcesarVentana()
{
    if(configuracion.dependencias == SI)
    {
        GenerarMatrizD();        /* a partir de las matrices desacopladas */

        /* EXTRAIGO INFORMACIÓN DE LAS MATRICES */
        /* lista orden parcial (la función también puede devolver pasos) */
        if(configuracion.ordenparcial == SI) ListaOrdenParcial(matriz.D, OrdenParcial);
        /* matriz de caminos (la función también puede devolver pasos) */
        if(configuracion.matrizcaminos == SI) CalcularMatrizCaminos(matriz.D, matrizC);
        /* pasos de computación */
        if(configuracion.pasoscomputacion == SI)
        {
            /* pasos de computación de todas las matrices de dependencias */
            CalcularPasosComputacion(pasos);
            if(configuracion.distribucionpasos == SI) ActualizarHistogramaPasos();
            /* valor medio de pasos de computación */
            CalcularPromedioVariableAgregada(mediapasos, pasos, ventana);
        }
        /* grado de paralelismo (a partir de los pasos de computación) */
        if(configuracion.gradoparalelismo == SI)
        {
            /* grado de paralelismo a partir de los pasos de computación */
            CalcularGradoParalelismoNormalizado(pasos, grado);
            /* valor medio del grado de paralelismo */
            CalcularPromedioVariableAgregada(mediagrado, grado, ventana);
        }
        /* acoplamiento */
        if(configuracion.acoplamiento == SI);
        {
            /* grado de paralelismo a partir de los pasos de computación */
            CalcularAcoplamiento(acoplo);
            /* valor medio del grado de paralelismo */
            CalcularPromedioVariableAgregada(mediaacoplo, acoplo, ventana);
        }        

        if(configuracion.tiempo == SI) tiempoejecucion = CalcularTiempo();
    }
}

void ReservarMemoriaAnalisisDependencias()
{
    CrearPizarras();
    
    CrearVectorDependencias();

    CrearMatricesDependencias();

    if(configuracion.ordenparcial == SI) CrearListaOrdenParcial();
    if(configuracion.matrizcaminos == SI) CrearMatrizCaminos();
    if(configuracion.pasoscomputacion == SI)
    {
        pasos = CrearVariableAgregada();
        IniciarVariableAgregada(pasos);
        mediapasos = CrearVariableAgregada();
        IniciarVariableAgregada(mediapasos);
        if(configuracion.distribucionpasos == SI) CrearHistogramaPasos();
    }
    if(configuracion.gradoparalelismo == SI);
    {
        grado = CrearVariableAgregada();
        IniciarVariableAgregada(grado);
        mediagrado = CrearVariableAgregada();
        IniciarVariableAgregada(mediagrado);
    }
    if(configuracion.acoplamiento == SI);
    {
        acoplo = CrearVariableAgregada();
        IniciarVariableAgregada(acoplo);
        mediaacoplo = CrearVariableAgregada();
        IniciarVariableAgregada(mediaacoplo);
    }
}


void LiberarMemoriaAnalisisDependencias()
{
    LiberarMemoriaPizarras();
    LiberarMemoriaVectorDependencias();
    LiberarMemoriaMatricesDependencias();

    if(configuracion.ordenparcial == SI) LiberarMemoriaListaOrdenParcial();
    if(configuracion.matrizcaminos == SI) LiberarMemoriaMatrizCaminos();

    if(configuracion.pasoscomputacion == SI) {free(pasos); free(mediapasos);}
    if(configuracion.gradoparalelismo == SI) {free(grado); free(mediagrado);};
    if(configuracion.acoplamiento == SI) {free(acoplo); free(mediaacoplo);};

    if(configuracion.distribucionpasos == SI) LiberarMemoriaHistogramaPasos();
}





void main(int argc, char *argv[])
{
    /* puntero al fichero origen de datos */
    FILE *origendatos;
    /* total instrucciones y ventanas a procesar */
    unsigned long total_ins, total_ven;    
    /* secuencia en bytes de 2 instrucciones consecutivas */
    unsigned char secuencia[2*BYTES_POR_INSTRUCCION];
    /* reservo espacio para una estructura de tipo ficha de instrucción */
    fichainstruccion tarjetaoperandos;
    
    unsigned int i, ins;
    char cadena[MAX_LINE];
    char mensaje[MAX_LINE];
    unsigned char salvarventana = NO;
    char listadoventanas[MAX_LINE];

    /* inicio los punteros de las matrices de dependencias a NULL */
    /* es una medida higiénica pero no necesaria ya que la reserva de memoria */
    /* correspondiente a la declaración se hace rellenando con 0s */

    /* ver si es posible con {NULL, NULL...} */
    IniciarPunterosMatrices();

    /* NOTIFICACIONES DE SUCESOS Y ERRORES */
    /* inicio el fichero que va a recibir las notificaciones */
    IniciarNotificaciones();

    /* CONFIGURACIÓN */
    /* cargo la configuración de la aplicación por defecto */
    CargarConfiguracionInicial();
    /* modifico la configuración de la aplicación en función de los argumentos */
    CapturarArgumentos(argc, argv);

    /* escribo la configuración en el fichero de notificaciones */
    if(configuracion.nivelnotificaciones != EX_CFG) NotificarConfiguracion();

    /* BASES DE DATOS */
    CargarBasesDatos();

    /* CALCULOS A REALIZAR */
    if(configuracion.recuentos == SI) CrearContadores();
    if(configuracion.dependencias == SI) ReservarMemoriaAnalisisDependencias();

    /* FICHEROS A CREAR */
    if(configuracion.volcarBD == SI) SalvarBasesDatos();
    if(configuracion.crearficheroconfig == SI) CrearFicheroConfiguracion();

    /* CABECERA EN LA PANTALLA */
    MostrarCabecera();

    /* PROCESAMIENTO */
    if(configuracion.origen == TRAZA)
    {
        /* determino el rango de instrucciones a analizar */
        DeterminarRango();
        /* determino el número total de instrucciones */
        total_ins = (unsigned long)(configuracion.ultima - configuracion.primera + 1);
        /* determino el número de ventanas de instrucciones */
        total_ven = (unsigned long)total_ins/configuracion.ventana;
        /* inicio los contadores */
        instruccion = 1;    /* cuento las instrucciones desde el '1' */
        ventana = 0;
        /* listado de ventanas a volcar */
        strcpy(listadoventanas, configuracion.volcarventana);
        
        /* abro el fichero de traza */
        if((origendatos  = fopen(configuracion.ficherodatos, "rb")) != NULL)
        {
            sprintf(mensaje, "[Main] El fichero '%s' se ha abierto con éxito", configuracion.ficherodatos);
            Notificar(mensaje, NO_ERROR, ECO_NO);

            /* sitúo el puntero del fichero en la instrucción de comienzo */
            fseek(origendatos, (configuracion.primera - 1) * BYTES_POR_INSTRUCCION, SEEK_SET);

            /* leo el formato de la primera instrucción a tratar */
            /* y lo coloco en la parte alta de la secuencia (2ª instrucción) */
            for(i=0; i<BYTES_POR_INSTRUCCION; i++) secuencia[i+BYTES_POR_INSTRUCCION] = fgetc(origendatos);

            while(total_ven-ventana)
            {
                ventana++;

                /* indicar estado de procesamiento */
                PresentarEstadoProcesamiento(total_ven, ventana);

                IniciarVentana();                

                /* ¿salvar información de la ventana en curso? */
                if(listadoventanas[0] != '\0')        /* si el listado no es vacío */
                {
                    sprintf(cadena, "%lu", ventana);
                    if(BuscarElementoLista(listadoventanas, cadena) != 0)
                    {
                        salvarventana = SI;
                        EliminarElementoLista(listadoventanas, cadena);
                        /* construyo una planilla con resultados de la ventana en curso */
                        IniciarFicheroVentana();
                    }
                    else salvarventana = NO;
                }

                for(ins=0; ins<configuracion.ventana; ins++, instruccion++)
                {
                    /* paso el formato de la parte alta a la baja */
                    for(i=0; i<BYTES_POR_INSTRUCCION; i++) secuencia[i] = secuencia[i+BYTES_POR_INSTRUCCION];
                    /* leo el formato de la instrucción siguiente desde la traza */
                    for(i=0; i<BYTES_POR_INSTRUCCION; i++) secuencia[i+BYTES_POR_INSTRUCCION] = fgetc(origendatos);

                    ProcesarInstruccion(ins, secuencia, &tarjetaoperandos);
                    
                    if(configuracion.verinstruccion == SI) MostrarTarjeta(&tarjetaoperandos);

                    if(salvarventana == SI) Instruccion2FicheroVentana(&tarjetaoperandos);

                    /* _getch(); */
                }
                ProcesarVentana();

                if(configuracion.verventana == SI) MostrarVentana();

                /* salvo las matrices de la ventana en la planilla y sus parámetros */
                if(salvarventana == SI) Matrices2FicheroVentana();
            }

            /* cierro el fichero de traza */
            if(fclose(origendatos))
            {
                sprintf(mensaje, "[Main] El fichero '%s' no se ha podido cerrar", configuracion.ficherodatos);
                Notificar(mensaje, ERROR_SEGUIR, ECO_NO);
            }
            else
            {
                sprintf(mensaje, "[Main] El fichero '%s' ha sido cerrado con éxito", configuracion.ficherodatos);
                Notificar(mensaje, NO_ERROR, ECO_NO);
            }
        }
        else
        {
            sprintf(mensaje, "[Main] El fichero '%s' no se ha podido abrir", configuracion.ficherodatos);
            Notificar(mensaje, ERROR_SALIR, ECO_NO);
        }
    }

    else if(configuracion.origen == SECUENCIA)
    {
        /* abro el fichero de la secuencia */
        if((origendatos  = fopen(configuracion.ficherodatos, "r")) != NULL)
        {
            sprintf(mensaje, "[Main] El fichero '%s' se ha abierto con éxito", configuracion.ficherodatos);
            Notificar(mensaje, NO_ERROR, ECO_NO);

            /* cuento las instrucciones de la secuencia */
            ins = 0;
            while(!feof(origendatos))
            {
                fgets (cadena, MAX_LINE, origendatos);
                
                if (cadena[0]!='\n' && cadena[0]!='#') ins++;
            }
            configuracion.primera = 1;
            configuracion.ultima = ins;

            /* determino el número total de instrucciones */
            total_ins = (unsigned long)(configuracion.ultima - configuracion.primera + 1);
            /* determino el número de ventanas de instrucciones */
            total_ven = (unsigned long)total_ins/configuracion.ventana;
            /* inicio los contadores */
            instruccion = 1;    /* cuento las instrucciones desde el '1' */
            ventana = 0;
            /* listado de ventanas a volcar */
            strcpy(listadoventanas, configuracion.volcarventana);


            /* coloco el puntero del fichero al principio */
            fseek(origendatos, 0L, SEEK_SET);

            /* comienzo el análisis de la secuencia */
            while(total_ven-ventana)
            {
                ventana++;

                /* indicar estado de procesamiento */
                PresentarEstadoProcesamiento(total_ven, ventana);

                IniciarVentana();

                /* ¿salvar información de la ventana en curso? */
                if(listadoventanas[0] != '\0')        /* si el listado no es vacío */
                {
                    sprintf(cadena, "%lu", ventana);
                    if(BuscarElementoLista(listadoventanas, cadena) != 0)
                    {
                        salvarventana = SI;
                        EliminarElementoLista(listadoventanas, cadena);
                        /* construyo una planilla con resultados de la ventana en curso */
                        IniciarFicheroVentana();
                    }
                    else salvarventana = NO;
                }

                for(ins=0; ins<configuracion.ventana; ins++, instruccion++)
                {
                    do
                    {
                        fgets (cadena, MAX_LINE, origendatos);
                    }
                    while (cadena[0]=='\n' || cadena[0]=='#');
                
                    /* quito el caracter '\n' (0x0A) final de la cadena correspondiente a una línea de texto */
                    /* ¡OJO! si abro el fichero en modo binario el final de linea es "\r\n" (0x0D 0x0A) */
                    *(cadena+strlen(cadena)-1)='\0';

                    ConvertirHex2Bin(cadena, secuencia, BYTES_POR_INSTRUCCION);

                    ProcesarInstruccion(ins, secuencia, &tarjetaoperandos);

                    if(configuracion.verinstruccion == SI) MostrarTarjeta(&tarjetaoperandos);

                    /* salvo las instrucciones en la planilla de la ventana */
                    if(salvarventana == SI) Instruccion2FicheroVentana(&tarjetaoperandos);
                }

                ProcesarVentana();

                if(configuracion.verventana == SI) MostrarVentana();

                /* salvo las matrices de la ventana en la planilla y sus parámetros */
                if(salvarventana == SI) Matrices2FicheroVentana();
            }

            /* cierro el fichero de la secuencia */
            if(fclose(origendatos))
            {
                sprintf(mensaje, "[Main] El fichero '%s' no se ha podido cerrar", configuracion.ficherodatos);
                Notificar(mensaje, ERROR_SEGUIR, ECO_NO);
            }
            else
            {
                sprintf(mensaje, "[Main] El fichero '%s' ha sido cerrado con éxito", configuracion.ficherodatos);
                Notificar(mensaje, NO_ERROR, ECO_NO);
            }
        }
        else
        {
            sprintf(mensaje, "[Main] El fichero '%s' no se ha podido abrir", configuracion.ficherodatos);
            Notificar(mensaje, ERROR_SALIR, ECO_NO);
        }
    }

    else if(configuracion.origen == CADENAHEX)
    {
        instruccion = 1;
        ventana = 1;

        ConvertirHex2Bin(configuracion.cadenahex, secuencia, BYTES_POR_INSTRUCCION);

        AnalizarOperandosIA16(secuencia, &tarjetaoperandos);

        if(configuracion.cpi == SI) CalcularCiclosInstruccion(&tarjetaoperandos);

        /* if(configuracion.verinstruccion == SI) */
        /* muestro en la pantalla la información siempre */
        MostrarTarjeta(&tarjetaoperandos);
    }

    /* SALVAR RESULTADOS */
    /* salvo los resultados en un fichero de formato EXCEL */
    if(configuracion.origen != CADENAHEX) CrearFicheroResultados(configuracion.ficheroresultados);

    /* LIBERAR MEMORIA */
    /* al final hay que liberar toda la memoria reservada */
    LiberarMemoriaBasesDatos();
    if(configuracion.recuentos == SI) LiberarMemoriaContadores();
    if(configuracion.dependencias == SI) LiberarMemoriaAnalisisDependencias();
}

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>