Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <pthread.h>
- #include <semaphore.h>
- #include <sys/fcntl.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/shm.h>
- #include <sys/wait.h>
- #include <string.h>
- #include <time.h>
- #include <assert.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <sys/msg.h>
- #include <signal.h>
- #define DEBUG
- #define MAX 1024
- #define MAX2 50
- #define PIPE_NAME "input_pipe"
- /****************************ESTRUTURAS********************/
- typedef struct Voo_partida *lista_voo_partida;
- typedef struct Voo_chegada *lista_voo_chegada;
- typedef struct Voo_aux *lista_voos;
- typedef struct Voo{
- char nome[MAX2];
- int inicial;
- int var;
- }voo;
- typedef struct Voo_aux{
- char nome[MAX2];
- int inicial;
- lista_voos next;
- }voo_aux;
- typedef struct Mensagem{
- long msgtyp;
- char nome[MAX2];
- int combustivel;
- int instante_partida;
- int eta;
- int init;
- int id_thread;
- } mensagem;
- typedef struct Callback_id{
- long msgtype;
- int id_sh;
- } callback_id;
- typedef struct Voo_partida{
- voo dep;
- int descolagem;
- lista_voo_partida next;
- }voo_partida;
- typedef struct Voo_chegada{
- voo arr;
- int eta;
- int combustivel;
- lista_voo_chegada next;
- }voo_chegada;
- typedef struct Mutua_exc{
- pthread_cond_t cond;
- pthread_mutex_t mutex;
- }mutua;
- typedef struct Estatistica{
- int total_voos_criados;
- int total_voos_aterraram;
- time_t tempo_medio_espera_aterrar;
- int total_voos_descolaram;
- time_t tempo_medio_espera_descolar;
- int media_manobras_aterragem;
- int media_manobras_emergencia;
- int voos_redirecionados;
- int voos_rejeitados;
- }estatistica;
- struct thread_info {
- int id;
- int flag;
- };
- /*********************HEADER DE FUNCOES**********************/
- void criar_processo_torre();
- char * horas();
- void escreve_log();
- void ler_config();
- void cria_semaforos();
- void cria_pipe();
- void cria_mq();
- void cria_shm_stats();
- void cria_shm_partida();
- void cria_shm_chegada();
- void *abre_pipe();
- void gestor();
- void *thread_manage();
- void *thread_gerir();
- void *thread_worker(void* a);
- int condition();
- void imprime_lista_chegada(lista_voo_chegada head);
- lista_voo_partida cria_lista_partida();
- lista_voo_chegada cria_lista_chegada();
- lista_voos cria_lista_voos();
- int check_shm(int id,int flag);
- void insere_lista_chegada(lista_voo_chegada head, char * n, int init, int eta, int fuel);
- void insere_fila_chegada(lista_voo_chegada head, char * n, int init, int eta, int fuel);
- void insere_lista_partida(lista_voo_partida head, char * n, int init, int desc);
- void insere_fila_partida(lista_voo_partida head, char * n, int init, int desc);
- void procura_lista_partida(lista_voo_partida lista, int chave, lista_voo_partida *ant, lista_voo_partida *atual);
- void procura_fila_partida(lista_voo_partida lista, int chave, lista_voo_partida *ant, lista_voo_partida *atual);
- void procura_lista_chegada(lista_voo_chegada lista, int chave, lista_voo_chegada *ant, lista_voo_chegada *atual);
- void procura_fila_chegada(lista_voo_chegada lista, int chave, lista_voo_chegada *ant, lista_voo_chegada *atual);
- void remove_lista_partida(lista_voo_partida partida, char *nome);
- void remove_lista_chegada(lista_voo_chegada chegada, char *nome);
- void imprime_lista_partida(lista_voo_partida teste);
- void insere_lista_voos(lista_voos head, char * n, int init);
- void procura_lista_voos(lista_voos lista, int chave, lista_voos *ant, lista_voos *atual);
- double hora_ut();
- int checkNome(lista_voos lista,char *nome);
- int checkLista(lista_voo_chegada chegadas, lista_voo_partida partidas,char *nome);
- double calcula_init(int init);
- void ms2ts( struct timespec *ts, unsigned long ms);
- void termina_programa(int signum);
- void remove_lista_voo(lista_voos voo, char *nome);
- void termina_programa_processo_torre(int signum);
- void termina_thread_manage();
- /***********************VARIAVEIS GLOBAIS********************/
- int ut_inicial; //variavel que guarda a hora inicial do sistema em segundos
- int ut_atual;
- pid_t pid_torre; //pid do processo da Torre de Controle
- FILE* flog; //ficheiro de log
- sem_t *log_mutex,*shared_sem,*sem_terminar; //mutex do log
- int shm_stats_id,shm_partida_id, shm_chegad_id, mq_id,pipe_id, shmid_mutex,mutexid_torre; //variaveis de shm
- estatistica * stats;
- voo_chegada *shm_chegada;
- voo_partida *shm_partida;
- pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
- pthread_mutex_t mutex_thread = PTHREAD_MUTEX_INITIALIZER;
- pthread_cond_t cond_torre = PTHREAD_COND_INITIALIZER;
- pthread_mutex_t mutex_torre = PTHREAD_MUTEX_INITIALIZER;
- int ut,dur_descolagem,dur_aterragem,int_descolagem,int_aterragem, holding_min, holding_max, max_partidas, max_chegadas,n_voos; //variaveis de leitura da config
- pthread_t thread_voo[MAX2],thread_pipe, thread_manage_id,thread_gerir_id;
- lista_voo_chegada fila_espera_chegada;
- lista_voo_partida fila_espera_partida;
- mutua *shared_mutex;
- pthread_mutexattr_t attrmutex; //ATTR para o shared_mutex
- pthread_condattr_t attrcond;
- lista_voo_chegada lista_chegada;
- lista_voo_partida lista_partida;
- lista_voos lista_voo_aux;
- double time_to_wait;
- unsigned long value;
- struct timespec ts;
- int ids = 1;
- int terminar = 0;
- /****************************FUNCOES*****************************/
- //funcao para debug print
- void debug_print(char * aux){
- #ifdef DEBUG
- printf("[DEBUG] %s\n",aux);
- #endif
- }
- int gere(){
- if(fila_espera_chegada->next == NULL && fila_espera_partida->next == NULL && terminar == 1){
- pthread_mutex_unlock(&mutex_torre);
- pthread_exit(NULL);
- }
- if(fila_espera_chegada->next == NULL && fila_espera_partida->next == NULL){
- return 0;
- }
- else if(fila_espera_chegada->next != NULL && fila_espera_partida->next == NULL){
- if(fila_espera_chegada->next->eta <= hora_ut()){
- return 1;
- }
- else{
- return 0;
- }
- }
- else if(fila_espera_chegada->next == NULL && fila_espera_partida->next != NULL){
- if(fila_espera_partida->next->descolagem <= hora_ut()){
- return 2;
- }
- else{
- return 0;
- }
- }
- else if(fila_espera_chegada->next != NULL && fila_espera_partida->next != NULL){
- if(fila_espera_partida->next->descolagem <= hora_ut() && fila_espera_chegada->next->eta > hora_ut()){
- return 1;
- }
- else if(fila_espera_partida->next->descolagem > hora_ut() && fila_espera_chegada->next->eta <= hora_ut()){
- return 2;
- }
- else if(fila_espera_partida->next->descolagem > hora_ut() && fila_espera_chegada->next->eta > hora_ut()){
- return 0;
- }
- else if( hora_ut() >= fila_espera_partida->next->descolagem && hora_ut() >= fila_espera_chegada->next->eta){
- if(fila_espera_partida->next->descolagem < fila_espera_chegada->next->eta){
- return 2;
- }
- else if(fila_espera_partida->next->descolagem > fila_espera_chegada->next->eta ){
- return 1;
- }
- if(fila_espera_partida->next->descolagem == fila_espera_chegada->next->eta){
- return 1;
- }
- }
- }
- }
- void *thread_gerir(){
- sigset_t signal_set;
- sigemptyset(&signal_set);
- sigaddset(&signal_set,SIGINT);
- pthread_sigmask(SIG_BLOCK, &signal_set, NULL);
- int a,num;
- while(1){
- pthread_mutex_lock(&mutex_torre);
- while((a = gere()) == 0){
- if(fila_espera_chegada->next == NULL && fila_espera_partida->next == NULL){
- pthread_cond_wait(&cond_torre,&mutex_torre);
- }
- else if(fila_espera_chegada->next != NULL && fila_espera_partida->next == NULL){
- clock_gettime(CLOCK_REALTIME, &ts);
- double var;
- var = calcula_init(fila_espera_chegada->next->eta);
- ts.tv_sec += var;
- pthread_cond_timedwait(&cond_torre,&mutex_torre,&ts);
- }
- else if(fila_espera_chegada->next == NULL && fila_espera_partida->next != NULL){
- clock_gettime(CLOCK_REALTIME, &ts);
- double var;
- var = calcula_init(fila_espera_partida->next->descolagem);
- ts.tv_sec += var;
- pthread_cond_timedwait(&cond_torre,&mutex_torre,&ts);
- }
- else if(fila_espera_chegada->next != NULL && fila_espera_partida->next != NULL){
- clock_gettime(CLOCK_REALTIME, &ts);
- double var;
- var = calcula_init(fila_espera_partida->next->descolagem);
- ts.tv_sec += var;
- pthread_cond_timedwait(&cond_torre,&mutex_torre,&ts);
- }
- }
- sem_wait(shared_sem);
- if(a == 1){
- int i,j;
- i = 0;
- j= 0;
- while (strcmp(shm_chegada[i].arr.nome,fila_espera_chegada->next->arr.nome)!= 0){
- i++;
- }
- shm_chegada[i].arr.var = 1;
- remove_lista_chegada(fila_espera_chegada,fila_espera_chegada->next->arr.nome);
- if(fila_espera_chegada->next != NULL){
- while (strcmp(shm_chegada[j].arr.nome,fila_espera_chegada->next->arr.nome)!= 0){
- j++;
- }
- shm_chegada[j].arr.var = 1;
- sleep(calcula_init(fila_espera_chegada->next->eta));
- remove_lista_chegada(fila_espera_chegada,fila_espera_chegada->next->arr.nome);
- pthread_mutex_unlock(&mutex_torre);
- sem_post(shared_sem);
- pthread_cond_broadcast(&shared_mutex->cond);
- }
- else{
- pthread_mutex_unlock(&mutex_torre);
- sem_post(shared_sem);
- pthread_cond_broadcast(&shared_mutex->cond);
- }
- //manda sinal para as threads;
- }
- if(a == 2){
- int i,j;
- i = 0;
- j= 0;
- while (strcmp(shm_partida[i].dep.nome,fila_espera_partida->next->dep.nome)!= 0){
- i++;
- }
- shm_partida[i].dep.var = 1;
- remove_lista_partida(fila_espera_partida,fila_espera_partida->next->dep.nome);
- printf("Removeu primeiro\n");
- if(fila_espera_partida->next != NULL){
- while (strcmp(shm_partida[j].dep.nome,fila_espera_partida->next->dep.nome)!= 0){
- j++;
- }
- shm_partida[j].dep.var = 1;
- sleep(calcula_init(fila_espera_partida->next->descolagem));
- remove_lista_partida(fila_espera_partida,fila_espera_partida->next->dep.nome);
- pthread_mutex_unlock(&mutex_torre);
- sem_post(shared_sem);
- printf("Vai mandar broadcast 2 \n");
- pthread_cond_broadcast(&shared_mutex->cond);
- }
- else{
- pthread_mutex_unlock(&mutex_torre);
- sem_post(shared_sem);
- printf("Vai mandar broadcast 1\n");
- pthread_cond_broadcast(&shared_mutex->cond);
- }
- }
- }
- }
- void criar_processo_torre(){
- signal(SIGINT, termina_programa_processo_torre);
- debug_print("Processo Torre criado");
- int i;
- fila_espera_partida = cria_lista_partida();
- fila_espera_chegada = cria_lista_chegada();
- mensagem msg;
- callback_id index_number;
- if(pthread_create(&thread_gerir_id,NULL,thread_gerir,NULL)!=0){
- perror("ERROR creating the thread pipe!\n");
- }
- // fica à espera de mensagens das threads
- while(1){
- if(msgrcv(mq_id, &msg, sizeof(mensagem)-sizeof(long), -3, 0) != -1) {
- // nº negativo funciona por prioridades -> 1º valor <= msgtype
- if(msg.msgtyp == 3){
- printf("--------TORRE DE CONTROLO--------\n\n");
- printf("NAME: %s \n",msg.nome);
- printf("TAKEOFF: %d \n",msg.instante_partida);
- printf("----------------\n");
- i = 0;
- while(strcmp(shm_partida[i].dep.nome,"\0") != 0){
- i++;
- }
- sem_wait(shared_sem);
- strcpy(shm_partida[i].dep.nome,msg.nome);
- shm_partida[i].descolagem = msg.instante_partida;
- shm_partida[i].dep.inicial = msg.init;
- index_number.msgtype = msg.id_thread;
- index_number.id_sh = i;
- insere_fila_partida(fila_espera_partida,msg.nome,msg.init,msg.instante_partida);
- imprime_lista_partida(fila_espera_partida);
- msgsnd(mq_id, &index_number, sizeof(index_number)-sizeof(long), 0);
- sem_post(shared_sem);
- pthread_cond_signal(&cond_torre);
- }
- else if(msg.msgtyp == 2){
- i=0;
- printf("--------TORRE DE CONTROLO--------\n\n");
- //adiciona o novo elemento à shm memory e envia o id para a thread
- while (strcmp(shm_chegada[i].arr.nome,"\0") != 0)
- {
- i++;
- }
- sem_wait(shared_sem);
- strcpy(shm_chegada[i].arr.nome,msg.nome);
- shm_chegada[i].arr.inicial = msg.init;
- shm_chegada[i].eta = msg.eta;
- shm_chegada[i].combustivel = msg.combustivel;
- sem_post(shared_sem);
- index_number.msgtype = msg.id_thread;
- index_number.id_sh = i;
- insere_fila_chegada(fila_espera_chegada,msg.nome,msg.init, msg.eta,msg.combustivel);
- //falta o id
- imprime_lista_chegada(fila_espera_chegada);
- msgsnd(mq_id, &index_number, sizeof(index_number)-sizeof(long), 0);
- pthread_cond_signal(&cond_torre);
- }
- else if(msg.msgtyp == 1){
- i=0;
- printf("--------TORRE DE CONTROLO--------\n\n");
- printf("---PRIORITY FLIGHT---\n\n");
- //adiciona o novo elemento à shm memory e envia o id para a thread
- while (strcmp(shm_chegada[i].arr.nome,"\0") != 0)
- {
- i++;
- }
- sem_wait(shared_sem);
- strcpy(shm_chegada[i].arr.nome,msg.nome);
- shm_chegada[i].arr.inicial = msg.init;
- shm_chegada[i].eta = msg.eta;
- shm_chegada[i].combustivel = msg.combustivel;
- index_number.msgtype = msg.id_thread;
- index_number.id_sh = i;
- sem_post(shared_sem);
- insere_fila_chegada(fila_espera_chegada,msg.nome,msg.init, msg.eta,msg.combustivel);
- //falta o id
- imprime_lista_chegada(fila_espera_chegada);
- msgsnd(mq_id, &index_number, sizeof(index_number)-sizeof(long), 0);
- pthread_cond_signal(&cond_torre);
- //adiciona o novo elemento a lista de espera e ordena-o
- }
- }
- }
- }
- void termina_thread_manage(){
- for(int i=4; i<n_voos+4; i++){
- pthread_join(thread_voo[i], NULL);
- }
- }
- void termina_programa_processo_torre(int signum){
- signal(SIGINT,termina_programa_processo_torre);
- sem_wait(sem_terminar);
- terminar = 1;
- sem_post(sem_terminar);
- pthread_cond_signal(&cond_torre);
- //Vai fazer join das treads
- pthread_join(thread_gerir_id,NULL);
- //elimina fila espera de chegada
- lista_voo_chegada auxA = fila_espera_chegada->next;
- lista_voo_chegada nextA;
- while(auxA!=NULL){
- nextA = auxA->next;
- free(auxA);
- auxA=nextA;
- }
- //elimina fila espera de partida
- lista_voo_partida auxB = fila_espera_partida->next;
- lista_voo_partida nextB;
- while(auxB!=NULL){
- nextB = auxB->next;
- free(auxB);
- auxB=nextB;
- }
- exit(0);
- }
- void termina_programa(int signum){
- signal(SIGINT, termina_programa);
- sem_wait(sem_terminar);
- terminar = 1;
- sem_post(sem_terminar);
- //fecha e da unlink ao named pipe
- close(pipe_id);
- unlink(PIPE_NAME);
- //limpa lista de voos
- lista_voos auxC = lista_voo_aux->next;
- lista_voos nextC;
- while(auxC!=NULL){
- nextC = auxC->next;
- free(auxC);
- auxC=nextC;
- }
- //manda um signal a thread manage
- pthread_cond_signal(&cond);
- // join da thread_manage que esta a fazer join das threads voo
- pthread_join(thread_manage_id,NULL);
- //limpa lista de voos chegada
- lista_voo_chegada auxA = lista_chegada->next;
- lista_voo_chegada nextA;
- while(auxA!=NULL){
- nextA = auxA->next;
- free(auxA);
- auxA=nextA;
- }
- //limpa lista de voos partida
- lista_voo_partida auxB = lista_partida->next;
- lista_voo_partida nextB;
- while(auxB!=NULL){
- nextB = auxB->next;
- free(auxB);
- auxB=nextB;
- }
- //espera que acabe o processo torre
- waitpid(pid_torre,NULL,0);
- //eliminar msq
- msgctl(mq_id, IPC_RMID, 0);
- //elimina mutexes pthread
- pthread_mutex_destroy(&mutex_thread);
- pthread_cond_destroy(&cond);
- pthread_mutex_destroy(&mutex_torre);
- pthread_cond_destroy(&cond_torre);
- //elimina shm
- shmdt(shm_chegada);
- shmctl(shm_chegad_id,IPC_RMID,NULL);
- shmdt(shm_partida);
- shmctl(shm_partida_id,IPC_RMID,NULL);
- shmdt(stats);
- shmctl(shm_stats_id,IPC_RMID,NULL);
- shmdt(shared_sem);
- shmctl(shmid_mutex,IPC_RMID,NULL);
- //termina ultimo processo e programa
- exit(0);
- }
- //funcao que calcula hora do sistema e returna string no formato 19:35:01
- char * horas(){
- char * aux;
- aux = malloc(sizeof(char*));
- time_t atual;
- time(&atual);
- struct tm *hora_local = localtime(&atual);
- sprintf(aux, "%02d:%02d:%02d", hora_local->tm_hour, hora_local->tm_min, hora_local->tm_sec);
- return aux;
- }
- //funcao que guarda hora de inicio do programa, em segundos
- void hora_inicio(){
- int hora_incial,minutos_inicial,segundos_inicial;
- time_t atual;
- time(&atual);
- struct tm *hora_local = localtime(&atual);
- hora_incial= hora_local->tm_hour * 60 * 60;
- minutos_inicial= hora_local->tm_min * 60;
- segundos_inicial= hora_local->tm_sec;
- ut_inicial = hora_incial + minutos_inicial + segundos_inicial;
- }
- //funcao que devolve hora atual do programa em ut
- double hora_ut(){
- double aux,aux2;
- time_t atual;
- time(&atual);
- struct tm *hora_local = localtime(&atual);
- aux = (((hora_local->tm_hour * 60 * 60) + (hora_local->tm_min * 60) + hora_local->tm_sec)-ut_inicial);
- aux2 = aux*ut/1000;
- return(aux2);
- }
- double calcula_init(int init){
- double final,aux;
- int var;
- var = init;
- aux = (double) ut;
- var = init-hora_ut();
- if(var <= 0){
- final = 0;
- return final;
- }
- else{
- final = (aux/1000) * var;
- return final;
- }
- }
- void imprime_lista_partida(lista_voo_partida head){
- lista_voo_partida atual = head->next;
- printf("LISTA DE ESPERA - VOOS PARTIDA\n");
- while (atual != NULL) {
- printf("----------------\n");
- printf("NOME: %s \n", atual->dep.nome);
- printf("Takeoff : %d\n ", atual->descolagem);
- printf("----------------\n");
- atual = atual->next;
- }
- }
- void imprime_lista_voos(lista_voos head){
- lista_voos atual = head->next;
- printf("LISTA DE VOOS\n");
- while (atual != NULL) {
- printf("----------------\n");
- printf("NAME: %s \n",atual->nome);
- printf("INIT: %d \n",atual->inicial);
- printf("----------------\n");
- printf("\n\n");
- atual = atual->next;
- }
- }
- void imprime_lista_chegada(lista_voo_chegada head){
- lista_voo_chegada atual = head->next;
- printf("LISTA DE ESPERA - VOOS CHEGADA\n");
- while (atual != NULL) {
- printf("----------------\n");
- printf("NOME:%s\n", atual->arr.nome);
- printf("INIT :%d\n", atual->arr.inicial);
- printf("FUEL: %d \n",atual->combustivel);
- printf("ETA: %d\n",atual->eta);
- printf("----------------\n");
- atual = atual->next;
- }
- }
- lista_voos cria_lista_voos(){
- lista_voos head = NULL;
- head = (lista_voos)malloc(sizeof(voo_aux));
- if(head != NULL){
- strcpy(head->nome," ");
- head->inicial = 0;
- head->next = NULL;
- }
- return(head);
- }
- lista_voo_partida cria_lista_partida(){
- lista_voo_partida head = NULL;
- head = (lista_voo_partida) malloc(sizeof(voo_partida));
- if(head != NULL){
- strcpy(head->dep.nome," ");
- head->dep.inicial = 0;
- head->descolagem = 0;
- head->next = NULL;
- }
- return(head);
- }
- lista_voo_chegada cria_lista_chegada(){
- lista_voo_chegada head = NULL;
- head = (lista_voo_chegada) malloc(sizeof(voo_chegada));
- if(head != NULL){
- strcpy(head->arr.nome," ");
- head->arr.inicial = 0;
- head->eta = 0;
- head->combustivel = 0;
- head->next = NULL;
- }
- return (head);
- }
- void insere_lista_voos(lista_voos head, char * n, int init){
- lista_voos atual;
- lista_voos ant, inutil;
- atual = (lista_voos) malloc (sizeof (voo_aux));
- if (atual != NULL)
- {
- strcpy(atual->nome,n);
- atual->inicial = init;
- procura_lista_voos(head, init, &ant, &inutil);
- atual->next = ant->next;
- ant->next = atual;
- }
- }
- void insere_lista_partida(lista_voo_partida head, char * n, int init, int desc){
- lista_voo_partida atual;
- lista_voo_partida ant, inutil;
- atual = (lista_voo_partida) malloc (sizeof (voo_partida));
- if (atual != NULL)
- {
- strcpy(atual->dep.nome,n);
- atual->dep.inicial = init;
- atual->descolagem = desc;
- procura_lista_partida(head, init, &ant, &inutil);
- atual->next = ant->next;
- ant->next = atual;
- }
- }
- void insere_fila_partida(lista_voo_partida head, char * n, int init, int desc){
- lista_voo_partida atual;
- lista_voo_partida ant, inutil;
- atual = (lista_voo_partida) malloc (sizeof (voo_partida));
- if (atual != NULL)
- {
- strcpy(atual->dep.nome,n);
- atual->dep.inicial = init;
- atual->descolagem = desc;
- procura_fila_partida(head, desc, &ant, &inutil);
- atual->next = ant->next;
- ant->next = atual;
- }
- }
- int checkNome(lista_voos lista,char *nome){
- lista_voos atual;
- atual = lista->next;
- if(atual == NULL){
- return 0;
- }
- else{
- while(atual->next != NULL){
- if(strcmp(atual->nome,nome) == 0){
- return 1;
- }
- atual = atual->next;
- }
- return 0;
- }
- }
- void procura_lista_voos(lista_voos lista, int chave, lista_voos *ant, lista_voos *atual)
- {
- *ant = lista;
- *atual = lista->next;
- while ((*atual) != NULL &&( ((*atual)->inicial) < chave))
- {
- *ant = *atual;
- *atual = (*atual) -> next;
- }
- }
- void procura_lista_partida(lista_voo_partida lista, int chave, lista_voo_partida *ant, lista_voo_partida *atual)
- {
- *ant = lista;
- *atual = lista->next;
- while ((*atual) != NULL &&( ((*atual)->dep.inicial) < chave))
- {
- *ant = *atual;
- *atual = (*atual) -> next;
- }
- }
- void procura_fila_partida(lista_voo_partida lista, int chave, lista_voo_partida *ant, lista_voo_partida *atual)
- {
- *ant = lista;
- *atual = lista->next;
- while ((*atual) != NULL &&( ((*atual)->descolagem) < chave))
- {
- *ant = *atual;
- *atual = (*atual) -> next;
- }
- }
- void insere_lista_chegada(lista_voo_chegada head, char * n, int init, int eta, int fuel){
- lista_voo_chegada atual;
- lista_voo_chegada ant, inutil;
- atual = (lista_voo_chegada) malloc (sizeof (voo_chegada));
- if (atual != NULL)
- {
- strcpy(atual->arr.nome,n);
- atual->arr.inicial = init;
- atual->eta = eta;
- atual->combustivel = fuel;
- }
- procura_lista_chegada(head, init, &ant, &inutil);
- atual->next = ant->next;
- ant->next = atual;
- }
- void insere_fila_chegada(lista_voo_chegada head, char * n, int init, int eta, int fuel){
- lista_voo_chegada atual;
- lista_voo_chegada ant, inutil;
- atual = (lista_voo_chegada) malloc (sizeof (voo_chegada));
- if (atual != NULL)
- {
- strcpy(atual->arr.nome,n);
- atual->arr.inicial = init;
- atual->eta = eta;
- atual->combustivel = fuel;
- }
- procura_fila_chegada(head, eta, &ant, &inutil);
- atual->next = ant->next;
- ant->next = atual;
- }
- void procura_fila_chegada(lista_voo_chegada lista, int chave, lista_voo_chegada *ant, lista_voo_chegada *atual)
- {
- *ant = lista;
- *atual = lista->next;
- while ((*atual) != NULL && ((*atual)->eta) < chave)
- {
- *ant = *atual;
- *atual = (*atual) -> next;
- }
- }
- void procura_lista_chegada(lista_voo_chegada lista, int chave, lista_voo_chegada *ant, lista_voo_chegada *atual)
- {
- *ant = lista;
- *atual = lista->next;
- while ((*atual) != NULL &&( ((*atual)->arr.inicial) < chave))
- {
- *ant = *atual;
- *atual = (*atual) -> next;
- }
- }
- //funcao de escrita no log
- void escreve_log(char *aux){
- sem_wait(log_mutex);
- fprintf(flog,"%s %s\n",horas(),aux);
- sem_post(log_mutex);
- fflush(0);
- }
- //Funcao de leitura da config inicial do programa
- void ler_config(){
- FILE * fconfig;
- int linha=0;
- char buffer1[MAX2],buffer2[MAX2];
- if ((fconfig=fopen("config.txt", "r")) == NULL){
- perror("Erro ao abrir o ficheiro config\n");
- exit(1);
- }else{
- while (linha!=6){
- linha++;
- if(linha==1){
- fscanf(fconfig, "%s", buffer1);
- ut = atoi(buffer1);
- }else if(linha==2){
- fscanf(fconfig, "%[^,],%s", buffer1,buffer2);
- dur_descolagem = atoi(buffer1);
- int_descolagem = atoi(buffer2);
- }else if(linha==3){
- fscanf(fconfig, "%[^,],%s", buffer1,buffer2);
- dur_aterragem = atoi(buffer1);
- int_aterragem = atoi(buffer2);
- }else if(linha==4){
- fscanf(fconfig, "%[^,],%s", buffer1,buffer2);
- holding_min = atoi(buffer1);
- holding_max = atoi(buffer2);
- }else if(linha==5){
- fscanf(fconfig, "%s", buffer1);
- max_partidas = atoi(buffer1);
- }else if(linha==6){
- fscanf(fconfig, "%s", buffer1);
- max_chegadas = atoi(buffer1);
- }
- }
- fclose(fconfig);
- debug_print("Ficheiro cfg lido");
- }
- }
- //------------------Shared Memory Estatistica------------------------
- void cria_shm_stats(){
- if((shm_stats_id = shmget(IPC_PRIVATE,(sizeof(estatistica)),IPC_CREAT | 0766)) < 0){
- perror("Erro ao criar a memoria partilhada para as estatisticas ( IPC_CREAT)");
- }else{
- if(( stats = (estatistica *) shmat(shm_stats_id,NULL,0)) == (estatistica *)-1){
- perror("Erro ao criar a memoria partilhada para as estatisticas ( IPC_CREAT)");
- }
- else{
- stats->total_voos_criados = 0;
- stats->media_manobras_aterragem = 0;
- stats->total_voos_descolaram = 0;
- stats->total_voos_aterraram = 0;
- stats->media_manobras_emergencia = 0;
- stats->voos_redirecionados = 0;
- stats->voos_rejeitados = 0;
- stats->tempo_medio_espera_aterrar = 0;
- stats->tempo_medio_espera_descolar = 0;
- debug_print("Memoria partilhada Estatistica criada");
- }
- }
- }
- //------------------Shared Memory Partidas------------------------
- void cria_shm_partida(){
- if((shm_partida_id = shmget(IPC_PRIVATE,sizeof(voo_partida) * max_partidas,IPC_CREAT | 0766)) <0){
- perror("Erro a criar memoria partilhada para os voos de partida ");
- }
- if (( shm_partida = (voo_partida *) shmat(shm_partida_id,NULL,0)) == (voo_partida *)-1){
- perror("Erro a criar memoria partilhada para os voos de partida ");
- }
- else{
- debug_print("Memoria partilhada para os voos de partida criada com sucesso");
- int i;
- for(i = 0; i<max_partidas; i++){
- strcpy(shm_partida[i].dep.nome,"\0");
- shm_partida[i].dep.var = 0;
- shm_partida[i].dep.inicial = 0;
- shm_partida[i].descolagem = 0;
- }
- }
- }
- //------------------Shared Memory chegadas------------------------
- void cria_shm_chegada(){
- if((shm_chegad_id = shmget(IPC_PRIVATE,sizeof(voo_chegada) * max_chegadas,IPC_CREAT | 0766)) <0){
- perror("Erro a criar memoria partilhada para os voos de chegada ");
- }
- if (( shm_chegada = (voo_chegada *) shmat(shm_chegad_id,NULL,0)) == (voo_chegada *)-1){
- perror("Erro a criar memoria partilhada para os voos de chegada ");
- }
- else{
- debug_print("Memoria partilhada para os voos de chegada criada com sucesso");
- int i;
- for(i = 0; i<max_chegadas; i++){
- strcpy(shm_chegada[i].arr.nome,"\0");
- shm_chegada[i].arr.var = 0;
- shm_chegada[i].arr.inicial = 0;
- shm_chegada[i].combustivel = 0;
- shm_chegada[i].eta = 0;
- }
- }
- }
- //funcao que cria pipe
- void cria_pipe(){
- unlink(PIPE_NAME);
- if ((mkfifo(PIPE_NAME, O_CREAT|O_EXCL|0600)<0) && (errno!= EEXIST)){ // Cria o pipe
- perror("Erro ao inicializar PIPE");
- }else{
- if ((pipe_id=open(PIPE_NAME, O_RDWR)) < 0){
- perror("Impossivel abrir Pipe para leitura");
- exit(0);
- }else{
- debug_print("Named Pipe criado");
- }
- }
- }
- void *abre_pipe(){
- char aux[MAX],*buffer1;
- char auxNome[MAX2];
- int a,b,c;
- char original[MAX],erro[MAX],correto[MAX];
- while (1) {
- read(pipe_id, &aux, sizeof(char[MAX]));
- strcpy(original,aux);
- sprintf(correto,"%s%s","NEW COMMAND => ",original);
- sprintf(erro,"%s%s","WRONG COMMAND => ",original);
- buffer1 = strtok(aux," ");
- if(strcmp(buffer1,"ARRIVAL") == 0){
- //echo ARRIVAL TP437 init: 100 eta: 100 fuel: 1000 >> "input_pipe"
- //guarda nome
- buffer1 = strtok(NULL, " ");
- strcpy(auxNome, buffer1);
- //init:
- buffer1 = strtok(NULL, " ");
- if(strcmp(buffer1,"init:")!=0){
- escreve_log(erro);
- continue;
- }
- //init: 100
- buffer1 = strtok(NULL, " ");
- a = atoi(buffer1);
- if(a==0){
- escreve_log(erro);
- continue;
- }
- if(a<hora_ut()){
- escreve_log(erro);
- continue;
- }
- //eta:
- buffer1 = strtok(NULL, " ");
- if(strcmp(buffer1,"eta:")!=0){
- escreve_log(erro);
- continue;
- }
- //eta: 120
- buffer1 = strtok(NULL, " ");
- b = atoi(buffer1);
- if(b==0){
- escreve_log(erro);
- continue;
- }
- if(b<hora_ut() || b<a){
- escreve_log(erro);
- continue;
- }
- //fuel
- buffer1 = strtok(NULL, " ");
- if(strcmp(buffer1,"fuel:")!=0){
- escreve_log(erro);
- continue;
- }
- //fuel: 1000
- buffer1 = strtok(NULL, " ");
- c = atoi(buffer1);
- if(c==0){
- escreve_log(erro);
- continue;
- }
- if(c<b){
- escreve_log(erro);
- continue;
- }
- //pthread_mutex_unlock(&mutex_thread);
- pthread_mutex_lock(&mutex_thread);
- if((checkNome(lista_voo_aux,auxNome)== 0)){
- printf("O voo %s não existe no sistema, pode prosseguir\n",auxNome);
- insere_lista_chegada(lista_chegada,auxNome,a,b,c);
- insere_lista_voos(lista_voo_aux,auxNome,a);
- pthread_cond_signal(&cond);
- }
- else{
- printf("O voo %s já se encontra no sistema, acesso negado\n",auxNome);
- }
- pthread_mutex_unlock(&mutex_thread);
- escreve_log(correto);
- }else if(strcmp(buffer1,"DEPARTURE") == 0 ){
- int i;
- //nome
- buffer1 = strtok(NULL, " ");
- strcpy(auxNome, buffer1);
- //init:
- buffer1 = strtok(NULL, " ");
- if(strcmp(buffer1,"init:")!=0){
- escreve_log(erro);
- continue;
- }
- //init:100
- buffer1 = strtok(NULL, " ");
- a = atoi(buffer1);
- if(a==0){
- escreve_log(erro);
- continue;
- }
- if(a<hora_ut()){
- escreve_log(erro);
- continue;
- }
- //takeoff:
- buffer1 = strtok(NULL, " ");
- if(strcmp(buffer1,"takeoff:")!=0){
- escreve_log(erro);
- continue;
- }
- //takeoff: 100
- buffer1 = strtok(NULL, " ");
- b = atoi(buffer1);
- if(b==0){
- escreve_log(erro);
- continue;
- }
- if(b<hora_ut() || b<a){
- escreve_log(erro);
- continue;
- }
- i = 0;
- pthread_mutex_lock(&mutex_thread);
- if((checkNome(lista_voo_aux,auxNome)== 0)){
- printf("O voo %s não existe no sistema pode prosseguir\n",auxNome);
- //se o i = max_chegadas diz logo que nao dá e sai -> FAZER
- insere_lista_partida(lista_partida,auxNome,a,b);
- insere_lista_voos(lista_voo_aux,auxNome,a);
- pthread_cond_signal(&cond);
- }
- else{
- printf("O voo %s já se encontra no sistema, acesso negado\n",auxNome);
- }
- pthread_mutex_unlock(&mutex_thread);
- escreve_log(correto);
- }else{
- escreve_log(erro);
- }
- }
- }
- //DEPARTURE TP440 init: 0 takeoff: 100 >> "input_pipe"
- //echo ARRIVAL TP437 init: 100 eta: 100 fuel: 1000 >> "input_pipe"
- //mutex para o ficheiro de escrita no log
- void cria_semaforos(){
- sem_unlink("LOG_MUTEX");
- if((log_mutex = sem_open("LOG_MUTEX",O_CREAT|O_EXCL,0766,1))==SEM_FAILED){
- perror("Impossivel incializar o Semaforo para o Log File\n");
- sem_unlink("LOG_MUTEX");
- exit(0);
- }
- sem_unlink("SHM_SEM");
- if((shared_sem = sem_open("SHM_SEM",O_CREAT|O_EXCL,0766,1))==SEM_FAILED){
- perror("Impossivel incializar o Semaforo para a Shared Memory\n");
- sem_unlink("SHM_SEM");
- exit(0);
- }
- sem_unlink("SEM_TERMINAR");
- if((sem_terminar = sem_open("SEM_TERMINAR",O_CREAT|O_EXCL,0766,1))==SEM_FAILED){
- perror("Impossivel incializar o Semaforo para a flag do control-c\n");
- sem_unlink("SEM_TERMINAR");
- exit(0);
- }
- else{
- debug_print("Semaforos criados");
- }
- if((shmid_mutex = shmget(IPC_PRIVATE,(sizeof(mutua)),IPC_CREAT | 0777)) <0){
- escreve_log("Erro ao criar shared_mutex\n");
- }
- if (( shared_mutex = (mutua *) shmat(shmid_mutex,NULL,0)) == (mutua *)-1){
- escreve_log("Erro ao criar shared_mutex\n");
- }
- pthread_mutexattr_init(&attrmutex);
- pthread_condattr_init(&attrcond);
- if((pthread_mutexattr_setpshared(&attrmutex, PTHREAD_PROCESS_SHARED))!=0){
- printf("Deu erro\n");
- }
- if((pthread_condattr_setpshared(&attrcond, PTHREAD_PROCESS_SHARED))!=0){
- printf(" aababba\n");
- }
- }
- //--------------Message Queue------------------
- void cria_mq(){
- mq_id = msgget(IPC_PRIVATE, IPC_CREAT|0777);
- if (mq_id < 0)
- {
- perror("Erro ao inicializar a message queue");
- }
- else{
- debug_print("Message queue criada");
- }
- }
- int check_shm(int id,int flag){
- sem_wait(shared_sem);
- if(flag == 2){
- if(shm_partida[id].dep.var == 1){
- printf("Voo %s partiu\n" ,shm_partida[id].dep.nome);
- sem_post(shared_sem);
- return 1;
- }
- else
- {
- sem_post(shared_sem);
- return 0;
- }
- }
- else if(flag == 1){
- if(shm_chegada[id].arr.var == 1){
- printf("Voo %s aterrou\n" ,shm_chegada[id].arr.nome);
- sem_post(shared_sem);
- return 1;
- }
- else
- {
- sem_post(shared_sem);
- return 0;
- }
- }
- }
- //thread voo
- void *thread_worker(void* a){
- sigset_t signal_set;
- sigemptyset(&signal_set);
- sigaddset(&signal_set,SIGINT);
- pthread_sigmask(SIG_BLOCK, &signal_set,NULL);
- int id,flag,id_shared;
- mensagem msg;
- callback_id call;
- struct thread_info *args = a;
- flag = args->flag ;
- id = args->id;
- id_shared = 0;
- char nome[MAX2];
- char str[MAX2];
- pthread_mutex_lock(&mutex_thread);
- //vai buscar o ultimo elemento da lista de voos para enviar pela mq a info
- //procura na lista de voos de partida
- debug_print("Thread Voo Criada");
- if(flag == 2){
- strcpy(msg.nome,lista_partida->next->dep.nome);
- msg.eta = 0;
- strcpy(nome,lista_partida->next->dep.nome);
- sprintf(str,"FLIGHT %s IS ON THE RADAR\n", nome);
- escreve_log(str);
- msg.combustivel = 0;
- msg.msgtyp = 3;
- msg.instante_partida = lista_partida->next->descolagem;
- msg.id_thread = id;
- msg.init = lista_partida->next->dep.inicial;
- msgsnd(mq_id, &msg, sizeof(msg)-sizeof(long), 0);
- msgrcv(mq_id, &call, sizeof(call)-sizeof(long), id, 0);
- id_shared = call.id_sh;
- printf("ID shared memory- %d\n", id_shared);
- remove_lista_partida(lista_partida,lista_partida->next->dep.nome);
- } //procura na lista de voos de chegada
- else if(flag == 1){
- if(lista_chegada->next->combustivel <= 4 * ut + lista_chegada->next->eta){
- msg.msgtyp = 1;
- printf("PRIORITY\n");
- strcpy(nome,lista_chegada->next->arr.nome);
- sprintf(str,"FLIGHT %s IS ON THE RADAR\n", nome);
- escreve_log(str);
- strcpy(msg.nome,lista_chegada->next->arr.nome);
- msg.eta = lista_chegada->next->eta;
- msg.combustivel = lista_chegada->next->combustivel;
- msg.init = lista_chegada->next->arr.inicial;
- msg.id_thread = id;
- msg.instante_partida = 0;
- msgsnd(mq_id, &msg, sizeof(msg)-sizeof(long), 0);
- msgrcv(mq_id, &call, sizeof(call)-sizeof(long), id, 0);
- id_shared = call.id_sh;
- printf("ID shared memory- %d\n", id_shared);
- }
- else{
- printf("NOT PRIORITY\n");
- strcpy(nome,lista_chegada->next->arr.nome);
- msg.msgtyp = 2;
- sprintf(str,"FLIGHT %s IS ON THE RADAR\n", nome);
- escreve_log(str);
- strcpy(msg.nome,lista_chegada->next->arr.nome);
- msg.eta = lista_chegada->next->eta;
- msg.combustivel = lista_chegada->next->combustivel;
- msg.init = lista_chegada->next->arr.inicial;
- msg.id_thread = id;
- msg.instante_partida = 0;
- //imprime_lista_chegada(lista_chegada);
- msgsnd(mq_id, &msg, sizeof(mensagem)-sizeof(long), 0);
- //pthread_mutex_unlock(&mutex_thread)
- msgrcv(mq_id, &call, sizeof(call)-sizeof(long), id, 0);
- id_shared = call.id_sh;
- printf("ID shared memory- %d\n", id_shared);
- }
- remove_lista_chegada(lista_chegada,lista_chegada->next->arr.nome);
- }
- pthread_mutex_unlock(&mutex_thread);
- pthread_mutex_lock(&shared_mutex->mutex);
- while(check_shm(id_shared,flag)==0){
- pthread_cond_wait(&shared_mutex->cond,&shared_mutex->mutex);
- }
- pthread_mutex_unlock(&shared_mutex->mutex);
- //Por a zero na memoria partilhada
- sprintf(str,"FLIGHT %s CONCLUDED\n", nome);
- escreve_log(str);
- n_voos--;
- pthread_exit(0);
- }
- //funcao que chama as funcoes todas de criar
- void gestor(){
- ler_config();
- hora_inicio();
- cria_shm_stats();
- cria_shm_chegada();
- cria_shm_partida();
- cria_semaforos();
- pthread_mutex_init(&mutex_thread,NULL);
- pthread_cond_init(&cond, NULL);
- pthread_mutex_init(&mutex_torre,NULL);
- pthread_cond_init(&cond_torre, NULL);
- pthread_mutex_init(&shared_mutex->mutex, &attrmutex);
- pthread_cond_init(&shared_mutex->cond, &attrcond);
- lista_chegada = cria_lista_chegada();
- lista_partida = cria_lista_partida();
- lista_voo_aux = cria_lista_voos();
- cria_mq();
- cria_pipe();
- }
- void remove_lista_chegada(lista_voo_chegada chegada, char *nome){
- lista_voo_chegada atual,ant;
- atual = chegada->next;
- ant = chegada;
- if(atual!= NULL){
- while (strcmp(atual->arr.nome,nome)!=0)
- {
- atual = atual->next;
- ant = ant->next;
- }
- ant->next = atual->next;
- free(atual);
- }
- }
- void remove_lista_voo(lista_voos chegada, char *nome){
- lista_voos atual,ant;
- atual = chegada->next;
- ant = chegada;
- if(atual!= NULL){
- ant->next = atual->next;
- free(atual);
- }
- }
- void remove_lista_partida(lista_voo_partida partida, char *nome){
- lista_voo_partida atual,ant;
- atual = partida->next;
- ant = partida;
- if(atual!= NULL){
- while (strcmp(atual->dep.nome,nome)!=0)
- {
- atual = atual->next;
- ant = ant->next;
- }
- ant->next = atual->next;
- free(atual);
- }
- }
- int checkLista(lista_voo_chegada chegadas, lista_voo_partida partidas,char *nome){
- lista_voo_partida atual_partida;
- lista_voo_chegada atual_chegada;
- atual_chegada = chegadas;
- atual_partida = partidas;
- if(atual_chegada->next == NULL){
- while(atual_partida->next != NULL){
- if(strcmp(atual_partida->next->dep.nome,nome) == 0){
- return 2;
- }
- else{
- atual_partida = atual_partida->next;
- }
- }
- }
- else if(atual_partida->next == NULL){
- while(atual_chegada->next != NULL){
- if(strcmp(atual_chegada->next->arr.nome,nome) == 0){
- return 1;
- }
- else{
- atual_chegada = atual_chegada->next;
- }
- }
- }
- else if(atual_partida->next != NULL && atual_chegada->next != NULL){
- while(atual_chegada->next != NULL){
- if(strcmp(atual_chegada->next->arr.nome,nome) == 0){
- return 1;
- }
- else{
- atual_chegada = atual_chegada->next;
- }
- }
- while(atual_partida->next != NULL){
- if(strcmp(atual_partida->dep.nome,nome) == 0){
- return 2;
- }
- else{
- atual_partida = atual_partida->next;
- }
- }
- }
- }
- int condition(){
- if(terminar == 1 && lista_voo_aux->next == NULL){
- termina_thread_manage();
- pthread_mutex_unlock(&mutex_thread);
- pthread_exit(NULL);
- }else{
- if(lista_voo_aux->next != NULL){
- if(lista_voo_aux->next->inicial <= hora_ut()){
- return 1;
- }
- else{
- return 0;
- }
- }
- else{
- return 0;
- }
- }
- }
- void *thread_manage(){
- sigset_t signal_set;
- sigemptyset(&signal_set);
- sigaddset(&signal_set,SIGINT);
- pthread_sigmask(SIG_BLOCK, &signal_set,NULL);
- struct thread_info args;
- int k;
- k=3;
- while(1){
- pthread_mutex_lock(&mutex_thread);
- while(condition() == 0){
- if(lista_voo_aux->next != NULL){
- clock_gettime(CLOCK_REALTIME, &ts);
- double var;
- var = calcula_init(lista_voo_aux->next->inicial);
- ts.tv_sec += var;
- pthread_cond_timedwait(&cond,&mutex_thread,&ts);
- }
- else{
- clock_gettime(CLOCK_REALTIME, &ts);
- ts.tv_sec += 5;
- printf("ESPEROU + 5seg\n");
- pthread_cond_wait(&cond,&mutex_thread);
- }
- }
- args.flag = checkLista(lista_chegada,lista_partida,lista_voo_aux->next->nome);
- remove_lista_voo(lista_voo_aux,lista_voo_aux->next->nome);
- imprime_lista_voos(lista_voo_aux);
- pthread_mutex_unlock(&mutex_thread);
- k++;
- args.id = k;
- if(pthread_create(&thread_voo[k],NULL,thread_worker,(void *) &args) !=0){
- perror("ERROR creating the thread pipe!\n");
- }else{
- n_voos++;
- }
- // pthread_mutex_unlock(&mutex_thread);
- }
- }
- int main(){
- signal(SIGINT, termina_programa);
- pthread_mutex_init(&mutex_thread,NULL);
- pthread_cond_init(&cond, NULL);
- debug_print("Programa iniciado");
- flog=fopen("log.txt","w");
- gestor();
- if ((pid_torre = fork()) == 0) {
- criar_processo_torre();
- }
- else if (pid_torre == -1) {
- perror("Erro a criar o processo torre de controlo");
- }
- else{
- if(pthread_create(&thread_manage_id,NULL,thread_manage,NULL)!=0){
- perror("ERROR creating the thread pipe!\n");
- }
- abre_pipe();
- }
- fclose(flog);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement