diff --git a/mp2.pdf b/mp2.pdf new file mode 100644 index 0000000..b2d223d Binary files /dev/null and b/mp2.pdf differ diff --git a/removefifo.bash b/removefifo.bash index 6fc965b..0cec3a2 100755 --- a/removefifo.bash +++ b/removefifo.bash @@ -1,3 +1,3 @@ #!/bin/bash -cd src/tmp +cd src2/tmp rm fifoname diff --git a/run.bash b/run.bash index 405db40..f2bf416 100755 --- a/run.bash +++ b/run.bash @@ -4,14 +4,14 @@ echo "║ CHANGE FLAGS IN BASH ║" echo "╚══════════════════════════╝" cd src2/tmp -# rm *.* & +rm *.* & cd .. # $? = 0 se compilou bem # $? = 2 otherwise make -s if [ $? -eq 0 ] ; then - ./Q2 -t 5 fifoname & # Un <-t nsecs> fifoname + ./Q2 -t 5 -l 4 -n 1 fifoname & # Un <-t nsecs> fifoname P1=$! ./U2 -t 10 fifoname & # Qn <-t nsecs> [-l nplaces] [-n nthreads] fifoname P2=$! diff --git a/src2/Q2.c b/src2/Q2.c index bf871ec..57065ab 100644 --- a/src2/Q2.c +++ b/src2/Q2.c @@ -20,17 +20,27 @@ #define ClearBit(A,k) ( A[(k/32)] &= ~(1 << (k%32)) ) #define TestBit(A,k) ( A[(k/32)] & (1 << (k%32)) ) +double nsecs; /**< numbers of seconds the program will be running */ +int nplaces; /**< size of array places */ +int nThreadsActive; /**< nº of active threads at the moment*/ + //com o intervalo entre pedidos 10 ms e valor maximo de uso 1000 ms, o valor maximo de lugares em uso //ao mesmo tempo é 100. 100/32 =3.125 faz com que seja preciso tamanho 4 -int places[4]; /**< array of bits to store used places */ +int *places; /**< array of bits to store used places */ bit closed; /**< bit to store if Server is open or closed */ + pthread_mutex_t mut=PTHREAD_MUTEX_INITIALIZER; /**< mutex to access places[] */ pthread_mutex_t mut2=PTHREAD_MUTEX_INITIALIZER; /**< mutex to enable closed bit */ +pthread_mutex_t mut3=PTHREAD_MUTEX_INITIALIZER; /**< mutex to access nThreadsActive */ + -double nsecs; /**< numbers of seconds the program will be running */ void * thread_func(void *arg){ + if(pthread_mutex_lock(&mut3)!=0){perror("Server-MutexLock");} + nThreadsActive++; + if(pthread_mutex_unlock(&mut3)!=0){perror("Server-MutexUnLock");} + char * request = (char *) arg; /**< Request string received from public fifo*/ int threadi, pid, dur, place; /**< Component of request*/ long tid; /**< thread id of client */ @@ -40,14 +50,14 @@ void * thread_func(void *arg){ printRegister(time(NULL), threadi, getpid(), pthread_self(), dur, -1, RECVD); // make private fifo pathname - char privateFifo[BUFSIZE]="/tmp/"; + char privateFifo[BUFSIZE]="tmp/"; char temp[BUFSIZE]; if(sprintf(temp,"%d",pid)<0){perror("Server-sprintf");} strcat(privateFifo,temp); strcat(privateFifo,"."); if(sprintf(temp,"%ld",tid)<0){perror("Server-sprintf");} strcat(privateFifo,temp); - + // open private fifo int fd_priv; /**< private fifo file descriptor */ float startt = elapsedTime(); @@ -104,30 +114,82 @@ void * thread_func(void *arg){ // cleanup ClearBit(places, place); if(close(fd_priv)==-1){perror("Server-closePrivateFifo");} + if(pthread_mutex_lock(&mut3)!=0){perror("Server-MutexLock");} + nThreadsActive--; + if(pthread_mutex_unlock(&mut3)!=0){perror("Server-MutexUnLock");} pthread_exit(NULL); } +void argumentsReader(int argc, char* argv[], int *nplaces, int *nthreads, char fifoname[]){ + /* 1 - ler valor de -t + * 2 - ler valor de -l + * 3 - ler valor de -n */ + int flag = 0; + for (int i = 1; i < argc; i++) + { + if (flag == 1) + { + nsecs=atoi(argv[i])*1000; + flag = 0; + continue; + } + else if (flag == 2) + { + *nplaces = atoi(argv[i]); + flag = 0; + continue; + } + else if (flag == 3) + { + *nthreads = atoi(argv[i]); + flag = 0; + continue; + } + else if (strcmp(argv[i], "-t") == 0) + { + flag = 1; + continue; + } + else if (strcmp(argv[i], "-l") == 0) + { + flag = 2; + continue; + } + else if (strcmp(argv[i], "-n") == 0) + { + flag = 3; + continue; + } + else + strcpy(fifoname,argv[i]); + } +} + int main(int argc, char* argv[]) { char fifoname[BUFSIZE]; /**< public fifo file name */ - char fifopath[BUFSIZE]="/tmp/"; /**< public fifo path */ + char fifopath[BUFSIZE]="tmp/"; /**< public fifo path */ char clientRequest[BUFSIZE]; /**< string read from public fifo */ pthread_t tid; /**< array to store thread id's */ closed.x=0; /**< 1-server closed | 0-server open */ - - // initialize available places at 0 - for (int i = 0; i < 4; i++) - places[i] = 0; - + nplaces = 0; + nThreadsActive = 0; + int nthreads=INT_MAX; // check arguments - if (argc!=4) { + if (argc!=4 && argc!=6 && argc!=8){ printf("Usage: U1 <-t secs> fifoname\n"); exit(1); } //read arguments - strcpy(fifoname,argv[3]); - nsecs=atoi(argv[2])*1000; + argumentsReader(argc, argv, &nplaces, &nthreads, fifoname); + //printf("argc:%d\nargv:smth\nnsecs:%f\nnplaces:%d\nnthreads:%d\nfifoname:%s\n", argc, nsecs, nplaces, nthreads, fifoname); strcat(fifopath,fifoname); + places = (int*) malloc(nplaces * sizeof(int)); + int* places_copy = places; + + // initialize available places at 0 + for (int i = 0; i < nplaces; i++) + places[i] = 0; //create public fifo if(mkfifo(fifopath,0660)==-1){perror("Error creating public FIFO"); exit(1);} @@ -144,29 +206,35 @@ int main(int argc, char* argv[]) { // while loop to check public fifo if(read(fd_pub,&clientRequest,BUFSIZE)<=0){ continue;} // create thread with contents of public fifo - if(pthread_create(&tid, NULL, thread_func, &clientRequest)!=0){perror("Server-pthread_Create");} - if(pthread_detach(tid)!=0){perror("Server-pthread_detach");} + if (nThreadsActive < nthreads) + { + if(pthread_create(&tid, NULL, thread_func, &clientRequest)!=0){perror("Server-pthread_Create");} + if(pthread_detach(tid)!=0){perror("Server-pthread_detach");} + } + else + { + // o que é suposto fazer aqui? + } + } - // closing sequence + if(unlink(fifopath)==-1){perror("Error destroying public fifo:");} if(pthread_mutex_lock(&mut2)!=0){perror("Server-MutexLock");} closed.x = 1; if(pthread_mutex_unlock(&mut2)!=0){perror("Server-MutexUnLock");} - float starttime; - int readreturn; - - // notifies client threads that server is closed - starttime = elapsedTime(); - do{ - readreturn = read(fd_pub, &clientRequest, BUFSIZE); - } while (readreturn == 0 && elapsedTime() - starttime < MSATTEMPT); - if (readreturn > 0){ - if(pthread_create(&tid, NULL, thread_func, &clientRequest)!=0){perror("Server-pthread_Create");} - if(pthread_detach(tid)!=0){perror("Server-pthread_detach");} + //float starttime; + int readreturn = read(fd_pub, &clientRequest, BUFSIZE); + while (readreturn != 0) + { + printf("Dentro de while\n"); + if(readreturn <0 ){perror("Server-read error");} + if(pthread_create(&tid, NULL, thread_func, &clientRequest)!=0){perror("Server-pthread_Create");} + if(pthread_detach(tid)!=0){perror("Server-pthread_detach");} + readreturn = read(fd_pub, &clientRequest, BUFSIZE); } // cleanup if(close(fd_pub)==-1){perror("Server-closePublicFifo");} - if(unlink(fifopath)==-1){perror("Error destroying public fifo:");} + free(places_copy); pthread_exit((void*)0); } diff --git a/src2/U2.c b/src2/U2.c index 5c562dd..086d4fa 100644 --- a/src2/U2.c +++ b/src2/U2.c @@ -33,8 +33,9 @@ pthread_mutex_t mut2=PTHREAD_MUTEX_INITIALIZER; /**< mutex para aceder a i*/ */ void * thread_func(void *arg){ // updating i with mutex's + int threadn;/**< thread number */ if(pthread_mutex_lock(&mut2)!=0){perror("Client-MutexLock");} - i++; + threadn = i++; if(pthread_mutex_unlock(&mut2)!=0){perror("Client-MutexUnLock");} int fd_pub; /**< file descriptor of public fifo */ @@ -44,16 +45,22 @@ void * thread_func(void *arg){ // opening Public fifo to be able to write float startt = elapsedTime(); + int attempt = 0; do{ - fd_pub = open(fifopath,O_WRONLY); - } while (fd_pub==-1 && elapsedTime() - startt < MSATTEMPT); - if (fd_pub < 0) { - fprintf(stderr, "%d-%s\n", i, "Client - Error Opening Public Fifo"); + fd_pub = open(fifopath,O_WRONLY, O_NONBLOCK); + attempt++; + } while (fd_pub==-1 && attempt < 5); + if (fd_pub == -1) { + printRegister(time(NULL), threadn, getpid(), pthread_self(), useTime, -1, CLOSD); + + if(pthread_mutex_lock(&mut)!=0){perror("Client-MutexLock");} + serverOpen.x = 0; + if(pthread_mutex_unlock(&mut)!=0){perror("Client-MutexUnLock");} pthread_exit(NULL); } // Making of message to send, writing of message and closing of fifo - if(sprintf(request,"[ %d, %d, %lu, %d, -1 ]", i, getpid(), pthread_self(), useTime)<0){perror("Client-sprintf");} + if(sprintf(request,"[ %d, %d, %lu, %d, -1 ]", threadn, getpid(), pthread_self(), useTime)<0){perror("Client-sprintf");} if (write(fd_pub, &request, BUFSIZE)<0){ perror("Error writing request: "); @@ -61,11 +68,11 @@ void * thread_func(void *arg){ pthread_exit(NULL); } - printRegister(time(NULL), i, getpid(), pthread_self(), useTime, -1, IWANT); + printRegister(time(NULL), threadn, getpid(), pthread_self(), useTime, -1, IWANT); if(close(fd_pub)==-1){perror("Client-closePublicFifo");} // Making of pathname of private fifo - char privateFifo[BUFSIZE]="/tmp/"; + char privateFifo[BUFSIZE]="tmp/"; char temp[BUFSIZE]; if(sprintf(temp,"%d",(int)getpid())<0){perror("Client-sprintf");} strcat(privateFifo,temp); @@ -80,11 +87,10 @@ void * thread_func(void *arg){ int fd_priv; startt = elapsedTime(); do{ - fd_priv = open(privateFifo, O_RDONLY); + fd_priv = open(privateFifo, O_RDONLY | O_NONBLOCK); } while (fd_priv==-1 && elapsedTime() - startt < MSATTEMPT); - if (fd_priv < 0) { - if(fprintf(stderr, "%d.%s\n", i, "Client - Error Opening Private Fifo")<0){perror("Client-fprintf");} + if(fprintf(stderr, "%d.%s\n", threadn, "Client - Error Opening Private Fifo")<0){perror("Client-fprintf");} if(close(fd_priv)==-1){perror("Client-closePrivateFifo");} pthread_exit(NULL); } @@ -94,8 +100,20 @@ void * thread_func(void *arg){ int tmpresult = read(fd_priv,&receivedMessage,BUFSIZE); // Attempts to read from private fifo until there's a response - while(tmpresult==0){tmpresult = read(fd_priv,&receivedMessage,BUFSIZE);} - if(tmpresult<0) {printRegister(time(NULL), i, getpid(), pthread_self(), useTime, -1, FAILD);} + int try = 0; + while(tmpresult<=0 && try < 5){ + if (try != 0) + usleep(100*1000); + tmpresult = read(fd_priv,&receivedMessage,BUFSIZE); + try++; + } + if(tmpresult<=0) { + printRegister(time(NULL), threadn, getpid(), pthread_self(), useTime, -1, FAILD); + + if(close(fd_priv)==-1){perror("Client-closePrivateFifo");} + if (unlink(privateFifo)==-1){perror("Error destroying private fifo:");} + pthread_exit(0); + } // If there's a response, parse the response to different variables int threadi, pid, dur, place; @@ -120,7 +138,7 @@ void * thread_func(void *arg){ int main(int argc, char* argv[], char *envp[]) { char fifoname[BUFSIZE]; /**< public fifo file name */ - char fifopath[BUFSIZE]="/tmp/"; /**< public fifo path */ + char fifopath[BUFSIZE]="tmp/"; /**< public fifo path */ double nsecs; /**< numbers of seconds the program will be running */ pthread_t tid; /**< array to store thread id's */ serverOpen.x = 1;