Codice: Seleziona tutto
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <pthread.h>
/** charToInt: converte il carattere passato in un numero intero
@param u - carattere da trasformare in intero
@return a - l'intero ricavato dal carattere
*/
int charToInt(char u){
int a=u-'0';
return a;
}
/** numeroNodi: metodo che serve per prendere in ingresso il numero di nodi(processi) voluto
@return nodesNumber numero intero corrispondente al numero di nodi inseriti dall'utente
*/
int numeroNodi(){
char buffer[50];
int nodesNumber;
int check;
memset(buffer,'\0',50);
write(1,"inserisci i nodi da simulare: ",sizeof(char)*29);
if((check=read(0,buffer,50))==-1){
write(2,"READ: -1",sizeof(char)*8);
}
nodesNumber=atoi(buffer);
return nodesNumber;
}
struct thread_data{ // struct per il passaggio dei parametri alle thread
int id;
int invio[2];
int ricezione[2];
char istruzioni[50];
int fine;
pthread_mutex_t mutex;
pthread_mutex_t end;
};
void *esecuzione(void *thread_arg){
struct thread_data *my_data;
my_data=(struct thread_data*)thread_arg;
char stamp[50];
char operazione;
int j=0;
int flag=1;
operazione=my_data->istruzioni[j];
do{
switch(operazione){
case 'E':
memset(stamp,'\0',50);
sprintf(stamp,"\nesecuzione processo %i sleep[%i]\n",my_data->id,charToInt(my_data->istruzioni[j+2]));
write(1,stamp,strlen(stamp));
sleep(charToInt(my_data->istruzioni[j+2]));
j+=4;
operazione=my_data->istruzioni[j];
break;
case 'R':
if(my_data->ricezione[0]!=0 && my_data->ricezione[1]!=0){
memset(stamp,'\0',50);
sprintf(stamp,"ricezione processo %i fallita\n",my_data->id);
write(1,stamp,strlen(stamp));
}
else{
my_data->ricezione[0]=0;
my_data->ricezione[1]=0;
memset(stamp,'\0',50);
sprintf(stamp,"svuoto memoria ricezione del processo %i [%i][%i]\n",my_data->id,my_data->ricezione[0],my_data->ricezione[1]);
write(1,stamp,strlen(stamp));
}
j+=2;
operazione=my_data->istruzioni[j];
break;
case 'S':
if(my_data->invio[0]!=0 && my_data->invio[1]!=0){
memset(stamp,'\0',50);
sprintf(stamp,"impossibile scrivere in invio processo %i\n",my_data->id);
write(1,stamp,strlen(stamp));
}
else{
memset(stamp,'\0',50);
sprintf(stamp,"scrivo nella zona di invio di %i [%i][%i]\n",my_data->id,charToInt(my_data->istruzioni[j+2]),charToInt(my_data->istruzioni[j+4]));
write(1,stamp,strlen(stamp));
my_data->invio[0]=charToInt(my_data->istruzioni[j+2]);
my_data->invio[1]=charToInt(my_data->istruzioni[j+4]);
pthread_mutex_unlock(&(my_data->mutex)); //signal_sem(idSem,i-1); // incrementare mutex
}
j+=6;
operazione=my_data->istruzioni[j];
break;
case ' ':
j+=1;
operazione=my_data->istruzioni[j];
break;
case '-': // carattere che indica la fine delle operazioni di un processo
flag=0;
my_data->fine=1; // incremento la zona di memoria relativa al termine dei processi
break;
default:
write(1,"operazione non conosciuta\n",sizeof(char)*26);
pthread_exit(NULL); // termine figlio con errore
return 0; // termine programma (errore fatale)
break;
}
}while(flag!=0);
pthread_exit((void*)0);
}
int main(){
pthread_mutex_t mutex1=PTHREAD_MUTEX_INITIALIZER;
int nodesNumber=numeroNodi();
int fd_in=-1;
struct thread_data *thread_buf;
pthread_t *threads;//[nodesNumber];
int nread[nodesNumber];
char filename[9];
char operazioni[nodesNumber][256];
int maxRead=0;
int i;
int j;
int t;
int rc;
int cont;
int status;
int x=0;
thread_buf=malloc(sizeof(struct thread_data)*(nodesNumber));
threads=malloc(sizeof(struct thread_data)*(nodesNumber));
for(i=0;i<nodesNumber;i++){
for(j=0;j<256;j++){
operazioni[i][j]='-';
}
}
/////////////////////////////////////////// LETTURA DA FILE ////////////////////////////////////////////////////
for(i=0;i<nodesNumber;i++){ // leggo da file e memorizzo nella matrice
sprintf(filename,"file%d.txt",i+1); // e sostituisco gli a capo con spazi
if((fd_in=open(filename,O_RDONLY,0644))==-1)
write(2,"OPEN: -1\n",sizeof(char)*9);
nread[i]=read(fd_in,operazioni[i],256);
close(fd_in);
}
for(i=0;i<nodesNumber;i++){
if(nread[i]>=maxRead){
maxRead=nread[i];
}
}
maxRead++;
maxRead++;
for(j=0;j<nodesNumber;j++){
for(i=0;i<maxRead;i++){
if(operazioni[j][i]=='\n')
operazioni[j][i]=' ';
}
}
//////////////////////// ESECUZIONE //////////////////////////////////////////////////////////////////
for(t=0;t<nodesNumber;t++){
pthread_mutex_lock(&(thread_buf[t].mutex));
pthread_mutex_lock(&(thread_buf[t].end));
thread_buf[t].id=t+1;
thread_buf[t].invio[0]=0;
thread_buf[t].invio[1]=0;
thread_buf[t].ricezione[0]=0;
thread_buf[t].ricezione[1]=0;
thread_buf[t].fine=0;
for(i=0,j=i;i<maxRead;i++){
thread_buf[t].istruzioni[i]=operazioni[t][i];
}
rc=pthread_create(&threads[t],NULL,esecuzione,(void*)&thread_buf[t]);
if(rc){
write(1,"PTHREAD_CREATE: !=0",sizeof(char)*19);
exit (1);
}
}
for (x=0;x<nodesNumber;x++){
pthread_mutex_lock(&(thread_buf[x].mutex));
x=0;
}
for (x=0;x<nodesNumber;x++){
rc=pthread_join(threads[x],(void**)&status);
if(rc)
{
printf("ERROR return code from pthread_join() is %d\n", rc);
exit(-1);
}
printf("Join completato con il thread %d, status = %d\n",x, status);
}
pthread_exit(NULL);
}