File:  [Repository ATC2] / ADD_ver_10 / Attic / Main.c
Revision 1.1: download - view: text, annotated - select for diffs
Thu Jan 19 17:16:29 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)   */
/*                                                                  */
/*  This file is part of ADD version 5.10.                          */
/*                                                                  */
/*  ADD is free software; you can redistribute it and/or modify     */
/*  it under the terms of the GNU General Public License as         */
/*  published by the Free Software Foundation; either version 2 of  */
/*  the License, or (at your option) any later version.             */
/*                                                                  */
/*  ADD is distributed in the hope that it will be useful,          */
/*  but WITHOUT ANY WARRANTY; without even the implied warranty of  */
/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   */
/*  GNU General Public License for more details.                    */
/*                                                                  */
/*  You should have received a copy of the GNU General Public       */
/*  License along with ADD; if not, write to the Free Software      */
/*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA        */
/*  02111-1307  USA                                                 */
/*                                                                  */
/*  --------------------------- History --------------------------- */
/*                                                                  */
/*  Revision 1.2. 01/2006                                           */
/*  Added GPL License and JavaDoc style documentation               */
/*                                                                  */
/*  Revision 1.1. 09/2005                                           */
/*  Initial Revision                                                */
/*                                                                  */
/********************************************************************/


/******************************************************************************/
/* 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();

	/* 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++;
				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++;
				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>