CODIGO FUENTE

#include"rshmem.h"
#include<time.h>
#include<stdlib.h>

/*** Definicion de la matriz ***/

typedef struct{
int fila,
columna;
float **elem;
}matriz;

/********************************************
* Funcion para reservar memoria compartida *
*********************************************/

matriz* reservar_memoria(int fila,int columna)
{
int i,
j,
k;
matriz *m; /* Puntero correspondiente a cada matriz */
extern char * memoria ; /* Puntero a la zona de memoria reservada */

m = (matriz *) memoria; /* Inicializacion de la matriz */
memoria += sizeof(matriz)+fila*sizeof(float *) + fila*columna*sizeof(float)+sizeof(int);

/* Damos formato a la memoria */
m->fila = fila;
m->columna = columna;
m->elem = (float **)&m->elem + sizeof(float **);

for(i=0;i<fila;i++)
m->elem[i] = (float*)&m->elem[fila]+i*columna*sizeof(float);

return m;
}


/***************************************
* Funcion para generar las matrices *
***************************************/

matriz* generar_matriz(int fila,int columna)
{
int i,j,num;
float u;
matriz *m;
time_t t;

/* Cambiamos la semilla del generador */
srand((unsigned)time (&t));

m=reservar_memoria(fila,columna);

/* Generamos los elementos de la matriz aleatoriamente */
for(i=0;i<fila;i++){
for(j=0;j<columna;j++){
num=rand();
    u=(float)(num)/RAND_MAX;
    num=(int)(u*10);
    m->elem[i][j]=num;
}
}
return m;
}

/******************************************
* Funcion para multiplicar las matrices *
******************************************/

matriz * multiplicar_matrices(matriz *a,matriz *b,int n_lineas)
{
int p,
mutex, /* Semaforo */
n_proces; /* Numero de procesos */
matriz *c; /* Matriz producto */
key_t clavemutex; /* Clave del semaforo */
int *finProc ; /* Marcas de final de cada proceso */

/* Reservar memoria para la matriz producto */
c=reservar_memoria(a->fila,b->columna);

/*Obtenemos una clave cualquiera para el semaforo*/
if((key_t) -1 == (clavemutex = ftok ("practica", 's'))){
fprintf(stderr, "main: error al crear la clave \n");
exit(1);
}

/* Creamos 1 semaforo binario */
if( -1 ==( mutex=semCreate(clavemutex,1))){
fprintf(stderr,"main: error no pude crear el semaforo \n");
exit(1);
}

c->fila--;
n_proces=a->fila/n_lineas; /* Numero de procesos que creamos */

finProc = (int *) memoria ;
memoria += sizeof(int);
*finProc = 0;

for(p=0;p<n_proces;p++){
if(fork()==0){
/* Codigo para los procesos hijo */
int i,
j,
    k,
    z;

/* Asignacion de filas a cada proceso */
semWait(mutex);
    i=c->fila;
    c->fila-=n_lineas;
    semSignal(mutex);

/* Calculo de la fila i_esima */
    for(z=0;z<n_lineas;z++){
    for(j=0;j<c->columna;j++){
    c->elem[i][j]=0;
    for(k=0;k<a->columna;k++)
    c->elem[i][j]+=a->elem[i][k]*b->elem[k][j];
}
    i--;
}

/* Fin de los procesos hijo */
semWait(mutex);
*finProc+=1;
semSignal(mutex);
exit(0);

}/* fin if */
}/* fin for */

/* El proceso padre espera a que terminen los hijos */
while (*finProc!=n_proces) ;

/* borramos el semaforo */
semClose(mutex);
c->fila=a->fila;
return c;
}


/**************************
* Funcion imprimir_matriz *
**************************/

imprimir_matriz(matriz *m, FILE *fich)
{
int i,
j;
for(i=0;i<m->fila;i++){
for(j=0;j<m->columna;j++)
fprintf(fich,"%14.3e ",m->elem[i][j]);
fprintf(fich,"\n");
}
}

imprimir_resultados(matriz *a,matriz *b,matriz *c,FILE *fich)
{
fprintf(fich,"La primera matriz es:\n");
imprimir_matriz(a, fich);
fprintf(fich,"\n\n");
fprintf(fich,"La segunda matriz es:\n");
imprimir_matriz(b, fich);
fprintf(fich,"\n\n");
fprintf(fich,"La matriz producto es:\n");
imprimir_matriz(c, fich);

}
/************************
* Funcion principal *
************************/

main(int argc,char **argv)
{
int n_lineas, /* Numero de lineas de la matriz producto que genera cada proceso */
f_a, /* Numero de filas de la primera matriz */
c_a, /* Numero de columnas de la primera matiz */
f_b, /* Numero de filas de la segunda matriz */
c_b; /* Numero de columnas de la segunda matriz */
matriz *a,*b,*c; /* Matrices */
FILE *fich; /* Puntero al fichero de salida */

if(argc!=6)
fprintf(stderr,"Error en el numero de argumentos \n");
f_a=atoi(*(argv+1));
c_a=atoi(*(argv+2));
f_b=atoi(*(argv+3));
c_b=atoi(*(argv+4));
n_lineas=atoi(*(argv+5));

if(c_a!=f_b){
fprintf(stderr,"Las matrices no se pueden multiplicar.\n");
exit(1);
}

if((f_a%n_lineas)!=0){
fprintf(stderr,"Error en el numero de lineas de cada proceso.\n");
exit(1);
}

/* Peticion de memoria compartida */
if(!crearMemoria()) {
fprintf(stderr,"Error al crear memoria compartida \n");
exit(1);
}

/* Crear las matrices */
a=generar_matriz(f_a,c_a);
b=generar_matriz(f_b,c_b);

c=multiplicar_matrices(a,b,n_lineas);

if((fich=fopen("salida","w+"))==NULL){
fprintf(stderr,"Error, no se pudo abrir el fichero de salida");
exit(1);
}

imprimir_resultados(a,b,c,fich);   
fclose(fich);

/* eliminamos la memoria compartida */
if(!eliminarMemoria())
fprintf(stderr,"error al eliminar la memoria.\n");
exit(0);
}

Principio de la Página