SHARE
TWEET

Untitled

a guest Dec 8th, 2019 59 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <pthread.h>
  4. #include <semaphore.h>
  5. #include <sys/fcntl.h>
  6. #include <unistd.h>
  7. #include <sys/types.h>
  8. #include <sys/ipc.h>
  9. #include <sys/shm.h>
  10. #include <sys/wait.h>
  11. #include <string.h>
  12. #include <time.h>
  13. #include <assert.h>
  14. #include <sys/stat.h>
  15. #include <fcntl.h>
  16. #include <errno.h>
  17. #include <sys/msg.h>
  18. #include <signal.h>
  19.  
  20. #define DEBUG
  21. #define MAX 1024
  22. #define MAX2 50
  23. #define PIPE_NAME "input_pipe"
  24.  
  25. /****************************ESTRUTURAS********************/
  26.  
  27. typedef struct Voo_partida *lista_voo_partida;
  28. typedef struct Voo_chegada *lista_voo_chegada;
  29. typedef struct Voo_aux *lista_voos;
  30.  
  31.  
  32. typedef struct Voo{
  33.   char nome[MAX2];
  34.   int inicial;
  35.   int var;
  36. }voo;
  37.  
  38. typedef struct Voo_aux{
  39.   char nome[MAX2];
  40.   int inicial;
  41.   lista_voos next;
  42. }voo_aux;
  43.  
  44. typedef struct Mensagem{
  45.   long msgtyp;
  46.   char nome[MAX2];
  47.   int combustivel;
  48.   int instante_partida;
  49.   int eta;
  50.   int init;
  51.   int id_thread;
  52. } mensagem;
  53.  
  54. typedef struct Callback_id{
  55.   long msgtype;
  56.   int id_sh;
  57. } callback_id;
  58.  
  59. typedef struct Voo_partida{
  60.     voo dep;
  61.     int descolagem;
  62.     lista_voo_partida next;
  63. }voo_partida;
  64.  
  65. typedef struct Voo_chegada{
  66.     voo arr;
  67.     int eta;
  68.     int combustivel;
  69.     lista_voo_chegada next;
  70. }voo_chegada;
  71.  
  72. typedef struct Mutua_exc{
  73.     pthread_cond_t cond;
  74.     pthread_mutex_t mutex;
  75. }mutua;
  76.  
  77. typedef struct Estatistica{
  78.     int total_voos_criados;
  79.     int total_voos_aterraram;
  80.     time_t tempo_medio_espera_aterrar;
  81.     int total_voos_descolaram;
  82.     time_t tempo_medio_espera_descolar;
  83.     int media_manobras_aterragem;
  84.     int media_manobras_emergencia;
  85.     int voos_redirecionados;
  86.     int voos_rejeitados;
  87. }estatistica;
  88.  
  89. struct thread_info {
  90.     int id;
  91.     int flag;
  92. };
  93.  
  94. /*********************HEADER DE FUNCOES**********************/
  95.  
  96. void criar_processo_torre();
  97. char * horas();
  98. void escreve_log();
  99. void ler_config();
  100. void cria_semaforos();
  101. void cria_pipe();
  102. void cria_mq();
  103. void cria_shm_stats();
  104. void cria_shm_partida();
  105. void cria_shm_chegada();
  106. void *abre_pipe();
  107. void gestor();
  108. void *thread_manage();
  109. void *thread_gerir();
  110. void *thread_worker(void* a);
  111. int condition();
  112. void imprime_lista_chegada(lista_voo_chegada head);
  113. lista_voo_partida cria_lista_partida();
  114. lista_voo_chegada cria_lista_chegada();
  115. lista_voos cria_lista_voos();
  116. int check_shm(int id,int flag);
  117. void insere_lista_chegada(lista_voo_chegada head, char * n, int init, int eta, int fuel);
  118. void insere_fila_chegada(lista_voo_chegada head, char * n, int init, int eta, int fuel);
  119. void insere_lista_partida(lista_voo_partida head, char * n, int init, int desc);
  120. void insere_fila_partida(lista_voo_partida head, char * n, int init, int desc);
  121. void procura_lista_partida(lista_voo_partida lista, int chave, lista_voo_partida *ant, lista_voo_partida *atual);
  122. void procura_fila_partida(lista_voo_partida lista, int chave, lista_voo_partida *ant, lista_voo_partida *atual);
  123. void procura_lista_chegada(lista_voo_chegada lista, int chave, lista_voo_chegada *ant, lista_voo_chegada *atual);
  124. void procura_fila_chegada(lista_voo_chegada lista, int chave, lista_voo_chegada *ant, lista_voo_chegada *atual);
  125. void remove_lista_partida(lista_voo_partida partida, char *nome);
  126. void remove_lista_chegada(lista_voo_chegada chegada, char *nome);
  127. void imprime_lista_partida(lista_voo_partida teste);
  128. void insere_lista_voos(lista_voos head, char * n, int init);
  129. void procura_lista_voos(lista_voos lista, int chave, lista_voos *ant, lista_voos *atual);
  130. double hora_ut();
  131. int checkNome(lista_voos lista,char *nome);
  132. int checkLista(lista_voo_chegada chegadas, lista_voo_partida partidas,char *nome);
  133. double calcula_init(int init);
  134. void ms2ts( struct timespec *ts, unsigned long ms);
  135. void remove_lista_voo(lista_voos voo, char *nome);
  136. void termina_programa_processo_torre(int signum);
  137. void termina_thread_manage();
  138. void termina_programa(int signum);
  139. /***********************VARIAVEIS GLOBAIS********************/
  140.  
  141. int ut_inicial;     //variavel que guarda a hora inicial do sistema em segundos
  142. int ut_atual;
  143. pid_t pid_torre;        //pid do processo da Torre de Controle
  144. FILE* flog;             //ficheiro de log
  145. sem_t *log_mutex,*shared_sem, *sem_terminar;   //semaforos
  146. int shm_stats_id,shm_partida_id, shm_chegad_id, mq_id,pipe_id, shmid_mutex, shmid_mutex_torre; //variaveis de shm
  147. estatistica * stats;
  148. voo_chegada *shm_chegada;
  149. voo_partida *shm_partida;
  150.  
  151. pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  152. pthread_mutex_t mutex_thread = PTHREAD_MUTEX_INITIALIZER;
  153.  
  154. 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
  155. pthread_t thread_voo[MAX2],thread_pipe, thread_manage_id,thread_gerir_id;
  156.  
  157. lista_voo_chegada fila_espera_chegada;
  158. lista_voo_partida fila_espera_partida;
  159. lista_voo_chegada fila_espera_prioridade;
  160.  
  161. mutua *shared_mutex;
  162. mutua *shared_mutex_torre;
  163. pthread_mutexattr_t attrmutex;      //ATTR para o shared_mutex
  164. pthread_condattr_t attrcond;
  165.  
  166. pthread_mutexattr_t attrmutex_torre;        //ATTR para o shared_mutex
  167. pthread_condattr_t attrcond_torre;
  168.  
  169. lista_voo_chegada lista_chegada;
  170. lista_voo_partida lista_partida;
  171. lista_voos lista_voo_aux;
  172.  
  173. int pistas[4] = {0,0,0,0}; //ARRAY DE PISTAS
  174.  
  175. double time_to_wait;
  176. unsigned long value;
  177.  struct timespec ts;
  178. int ids = 1;
  179. int terminar = 0;
  180.  
  181. /****************************FUNCOES*****************************/
  182.  
  183. //funcao para debug print
  184. void debug_print(char * aux){
  185.   #ifdef DEBUG
  186.   printf("[DEBUG] %s\n",aux);
  187.   #endif
  188. }
  189.  
  190. int gere(){
  191.   if(fila_espera_chegada->next == NULL && fila_espera_partida->next == NULL && terminar == 1){
  192.     pthread_mutex_unlock(&shared_mutex_torre->cond);
  193.     pthread_exit(NULL);
  194.   }
  195.   else{
  196.   if(fila_espera_chegada->next == NULL && fila_espera_partida->next == NULL && fila_espera_prioridade ->next == NULL){
  197.     return 0;
  198.   }
  199.   else if(fila_espera_chegada->next != NULL && fila_espera_partida->next == NULL && fila_espera_prioridade ->next == NULL){
  200.     if(fila_espera_chegada->next->eta <= hora_ut()){
  201.       return 1;
  202.     }
  203.     else{
  204.       return 0;
  205.     }
  206.   }
  207.   else if(fila_espera_chegada->next == NULL && fila_espera_partida->next != NULL && fila_espera_prioridade ->next == NULL){
  208.     if(fila_espera_partida->next->descolagem <= hora_ut()){
  209.       return 2;
  210.     }
  211.     else{
  212.       return 0;
  213.     }
  214.   }
  215.   else if(fila_espera_chegada->next == NULL && fila_espera_partida->next == NULL && fila_espera_prioridade ->next != NULL){
  216.     if(fila_espera_prioridade->next->eta <= hora_ut()){
  217.       return 3;
  218.     }
  219.     else{
  220.       return 0;
  221.     }
  222.   }
  223.   else if(fila_espera_chegada->next != NULL && fila_espera_partida->next == NULL && fila_espera_prioridade ->next != NULL){
  224.     if(fila_espera_prioridade->next->eta <= hora_ut()){
  225.       return 3;
  226.     }
  227.     else{
  228.       return 0;
  229.     }
  230.   }
  231.   else if(fila_espera_chegada->next == NULL && fila_espera_partida->next != NULL && fila_espera_prioridade ->next != NULL){
  232.     if(fila_espera_prioridade->next->eta <= hora_ut()){
  233.       return 3;
  234.     }
  235.     else{
  236.       return 0;
  237.     }
  238.   }
  239.   else if(fila_espera_chegada->next != NULL && fila_espera_partida->next != NULL && fila_espera_prioridade ->next != NULL){
  240.     if(fila_espera_prioridade->next->eta <= hora_ut()){
  241.       return 3;
  242.     }
  243.     else{
  244.       return 0;
  245.     }
  246.   }
  247.   else if(fila_espera_chegada->next != NULL && fila_espera_partida->next != NULL && fila_espera_prioridade ->next == NULL){
  248.     if(fila_espera_partida->next->descolagem <= hora_ut() && fila_espera_chegada->next->eta > hora_ut()){
  249.       return 1;
  250.     }
  251.     else if(fila_espera_partida->next->descolagem > hora_ut() && fila_espera_chegada->next->eta <= hora_ut()){
  252.       return 2;
  253.     }
  254.     else if(fila_espera_partida->next->descolagem > hora_ut() && fila_espera_chegada->next->eta > hora_ut()){
  255.       return 0;
  256.     }
  257.     else if( hora_ut() >= fila_espera_partida->next->descolagem  && hora_ut() >=  fila_espera_chegada->next->eta){
  258.       if(fila_espera_partida->next->descolagem < fila_espera_chegada->next->eta){
  259.         return 2;
  260.       }
  261.       else if(fila_espera_partida->next->descolagem > fila_espera_chegada->next->eta ){
  262.         return 1;
  263.       }
  264.       if(fila_espera_partida->next->descolagem == fila_espera_chegada->next->eta){
  265.         return 1;
  266.       }
  267.     }
  268.   }
  269.   }
  270. }
  271.  
  272. int cond_pistas(){
  273.   int val = gere();
  274.   if(val == 0){
  275.     return 0;
  276.   }
  277.   else if( val == 1){
  278.     //PISTA 0 e 1 ->partida return 1;
  279.     //PISTA 2 e 3 -> chegada return 2;
  280.     if(pistas[0] == 0 && pistas[2] == 0 && pistas[3]==0){
  281.       return 1;
  282.     }
  283.     else if( pistas[1] == 0 && pistas[2] == 0 && pistas[3]==0 ){
  284.       return 1;
  285.     }
  286.     else{
  287.       return 0;
  288.     }
  289.   }
  290.  
  291.   else if(val == 2){
  292.  
  293.     if(pistas[2] == 0 && pistas[0] == 0 && pistas[1]==0){
  294.       return 2;
  295.     }
  296.     else if( pistas[3] == 0 && pistas[0] == 0 && pistas[1]==0 ){
  297.       return 2;
  298.     }
  299.     else{
  300.       return 0;
  301.     }
  302.   }
  303.   else if(val == 3){
  304.     if(pistas[2] == 0 && pistas[0] == 0 && pistas[1]==0){
  305.       return 2;
  306.     }
  307.     else if( pistas[3] == 0 && pistas[0] == 0 && pistas[1]==0 ){
  308.       return 2;
  309.     }
  310.     else{
  311.       return 0;
  312.     }
  313.   }
  314. }
  315.  
  316. void *thread_gerir(){
  317. int a;
  318.  
  319. sigset_t signal_set;
  320. sigemptyset(&signal_set);
  321. sigaddset(&signal_set,SIGINT);
  322. pthread_sigmask(SIG_BLOCK, &signal_set, NULL);
  323.  
  324. while(1){
  325.   pthread_mutex_lock(&shared_mutex_torre->mutex);
  326.   while((a = cond_pistas()) == 0){
  327.     if(fila_espera_prioridade->next != NULL){
  328.       clock_gettime(CLOCK_REALTIME, &ts);
  329.       double var;
  330.       var = calcula_init(fila_espera_prioridade->next->eta);
  331.       ts.tv_sec += var;
  332.       pthread_cond_timedwait(&shared_mutex_torre->cond,&shared_mutex_torre->mutex,&ts);
  333.     }
  334.     else if(fila_espera_chegada->next == NULL && fila_espera_partida->next == NULL && fila_espera_prioridade->next == NULL){
  335.       pthread_cond_wait(&shared_mutex_torre->cond,&shared_mutex_torre->mutex);
  336.     }
  337.     else if(fila_espera_chegada->next != NULL && fila_espera_partida->next == NULL){
  338.       clock_gettime(CLOCK_REALTIME, &ts);
  339.       double var;
  340.       var = calcula_init(fila_espera_chegada->next->eta);
  341.       ts.tv_sec += var;
  342.       pthread_cond_timedwait(&shared_mutex_torre->cond,&shared_mutex_torre->mutex,&ts);
  343.     }
  344.     else if(fila_espera_chegada->next == NULL && fila_espera_partida->next != NULL){
  345.       clock_gettime(CLOCK_REALTIME, &ts);
  346.       double var;
  347.       var = calcula_init(fila_espera_partida->next->descolagem);
  348.       ts.tv_sec += var;
  349.       pthread_cond_timedwait(&shared_mutex_torre->cond,&shared_mutex_torre->mutex,&ts);
  350.     }
  351.     else if(fila_espera_chegada->next != NULL && fila_espera_partida->next != NULL){
  352.       clock_gettime(CLOCK_REALTIME, &ts);
  353.       double var;
  354.       var = calcula_init(fila_espera_partida->next->descolagem);
  355.       ts.tv_sec += var;
  356.       pthread_cond_timedwait(&shared_mutex_torre->cond,&shared_mutex_torre->mutex,&ts);
  357.     }
  358.   }
  359.  
  360.   sem_wait(shared_sem);
  361.   if(a == 1){
  362.     int i,j;
  363.     i = 0;
  364.     j= 0;
  365.     while (strcmp(shm_chegada[i].arr.nome,fila_espera_chegada->next->arr.nome)!= 0){
  366.       i++;
  367.     }
  368.     shm_chegada[i].arr.var = 1;
  369.  
  370.     if(pistas[0] == 0 && pistas[1]!=0){
  371.       pistas[0] = 1;
  372.     }
  373.     else if(pistas[1]==0 && pistas[0]!=0){
  374.       pistas[1] = 1;
  375.     }
  376.     else if(pistas[0] == 0 && pistas[1] == 0){
  377.       pistas[0] = 1;
  378.     }
  379.    
  380.     remove_lista_chegada(fila_espera_chegada,fila_espera_chegada->next->arr.nome);
  381.  
  382.     if(fila_espera_chegada->next != NULL){
  383.       while (strcmp(shm_chegada[j].arr.nome,fila_espera_chegada->next->arr.nome)!= 0){
  384.         j++;
  385.       }
  386.       shm_chegada[j].arr.var = 1;
  387.    
  388.     if(pistas[0] == 0 && pistas[1]!=0){
  389.       pistas[0] = 1;
  390.     }
  391.     else if(pistas[1]==0 && pistas[0]!=0){
  392.       pistas[1] = 1;
  393.       remove_lista_chegada(fila_espera_chegada,fila_espera_chegada->next->arr.nome);
  394.     }
  395.     else if(pistas[0] == 0 && pistas[1] == 0){
  396.       pistas[0] = 1;
  397.     }
  398.     remove_lista_chegada(fila_espera_chegada,fila_espera_chegada->next->arr.nome);
  399.     pthread_mutex_unlock(&shared_mutex_torre->mutex);
  400.     sem_post(shared_sem);
  401.     pthread_cond_broadcast(&shared_mutex->cond);  
  402.     }
  403.     else{
  404.  
  405.       pthread_mutex_unlock(&shared_mutex_torre->mutex);
  406.       sem_post(shared_sem);
  407.       pthread_cond_broadcast(&shared_mutex->cond);  
  408.     }
  409.   }
  410.   else if(a == 2){
  411.     int i,j;
  412.     i = 0;
  413.     j= 0;
  414.     while (strcmp(shm_partida[i].dep.nome,fila_espera_partida->next->dep.nome)!= 0){
  415.       i++;
  416.     }
  417.     shm_partida[i].dep.var = 1;
  418.     remove_lista_partida(fila_espera_partida,fila_espera_partida->next->dep.nome);
  419.     printf("Removeu primeiro\n");
  420.     if(fila_espera_partida->next != NULL){
  421.       while (strcmp(shm_partida[j].dep.nome,fila_espera_partida->next->dep.nome)!= 0){
  422.         j++;
  423.       }
  424.       shm_partida[j].dep.var = 1;
  425.       sleep(calcula_init(fila_espera_partida->next->descolagem));
  426.       remove_lista_partida(fila_espera_partida,fila_espera_partida->next->dep.nome);
  427.       pthread_mutex_unlock(&shared_mutex_torre->mutex);
  428.       sem_post(shared_sem);
  429.       printf("Vai mandar broadcast 2 \n");
  430.       pthread_cond_broadcast(&shared_mutex->cond);
  431.     }
  432.     else{
  433.       pthread_mutex_unlock(&shared_mutex_torre->mutex);
  434.       sem_post(shared_sem);
  435.       printf("Vai mandar broadcast 1\n");
  436.       pthread_cond_broadcast(&shared_mutex->cond);  
  437.     }
  438.   }
  439.   else if(a == 3){
  440.     int i,j;
  441.     i = 0;
  442.     j= 0;
  443.     while (strcmp(shm_chegada[i].arr.nome,fila_espera_prioridade->next->arr.nome)!= 0){
  444.       i++;
  445.     }
  446.     shm_chegada[i].arr.var = 1;
  447.     remove_lista_chegada(fila_espera_prioridade,fila_espera_prioridade->next->arr.nome);
  448.     if(fila_espera_prioridade->next != NULL){
  449.       while (strcmp(shm_chegada[j].arr.nome,fila_espera_prioridade->next->arr.nome)!= 0){
  450.         j++;
  451.       }
  452.       shm_chegada[j].arr.var = 1;
  453.       sleep(calcula_init(fila_espera_prioridade->next->eta));
  454.       remove_lista_chegada(fila_espera_prioridade,fila_espera_prioridade->next->arr.nome);
  455.       pthread_mutex_unlock(&shared_mutex_torre->mutex);
  456.       sem_post(shared_sem);
  457.       pthread_cond_broadcast(&shared_mutex->cond);
  458.     }
  459.   }
  460. }
  461. }
  462.  
  463. void criar_processo_torre(){
  464.   signal(SIGINT, termina_programa_processo_torre);
  465.   debug_print("Processo Torre criado");
  466.   int i;
  467.  
  468.   fila_espera_partida = cria_lista_partida();
  469.   fila_espera_chegada = cria_lista_chegada();
  470.   fila_espera_prioridade = cria_lista_chegada();
  471.   mensagem msg;
  472.   callback_id index_number;
  473.  
  474.   if(pthread_create(&thread_gerir_id,NULL,thread_gerir,NULL)!=0){
  475.       perror("ERROR creating the thread pipe!\n");
  476.     }
  477.  
  478.     // fica à espera de mensagens das threads
  479.   while(1){
  480.  
  481.     if(msgrcv(mq_id, &msg, sizeof(mensagem)-sizeof(long), -3, 0) != -1) {
  482.  
  483.     // nº negativo funciona por prioridades ->  1º valor <= msgtype
  484.  
  485.     if(msg.msgtyp == 3){
  486.       printf("--------TORRE DE CONTROLO--------\n\n");
  487.  
  488.       printf("NAME: %s \n",msg.nome);
  489.       printf("TAKEOFF: %d \n",msg.instante_partida);
  490.       printf("----------------\n");
  491.       i = 0;
  492.       while(strcmp(shm_partida[i].dep.nome,"\0") != 0){
  493.         i++;
  494.       }
  495.       sem_wait(shared_sem);
  496.  
  497.       strcpy(shm_partida[i].dep.nome,msg.nome);
  498.       shm_partida[i].descolagem = msg.instante_partida;
  499.       shm_partida[i].dep.inicial = msg.init;
  500.       index_number.msgtype = msg.id_thread;
  501.       index_number.id_sh = i;
  502.  
  503.       insere_fila_partida(fila_espera_partida,msg.nome,msg.init,msg.instante_partida);
  504.       imprime_lista_partida(fila_espera_partida);
  505.       msgsnd(mq_id, &index_number, sizeof(index_number)-sizeof(long), 0);
  506.       sem_post(shared_sem);
  507.  
  508.       pthread_cond_signal(&shared_mutex_torre->cond);
  509.    
  510.     }
  511.     else if(msg.msgtyp == 2){
  512.       i=0;
  513.       printf("--------TORRE DE CONTROLO--------\n\n");
  514.      
  515.  
  516.       //adiciona o novo elemento à shm memory e envia o id para a thread
  517.        while (strcmp(shm_chegada[i].arr.nome,"\0") != 0)
  518.       {
  519.         i++;
  520.       }
  521.  
  522.       sem_wait(shared_sem);
  523.       strcpy(shm_chegada[i].arr.nome,msg.nome);
  524.       shm_chegada[i].arr.inicial = msg.init;
  525.       shm_chegada[i].eta = msg.eta;
  526.       shm_chegada[i].combustivel = msg.combustivel;
  527.       sem_post(shared_sem);
  528.       index_number.msgtype = msg.id_thread;
  529.       index_number.id_sh = i;
  530.       insere_fila_chegada(fila_espera_chegada,msg.nome,msg.init, msg.eta,msg.combustivel);
  531.       //falta o id
  532.       imprime_lista_chegada(fila_espera_chegada);
  533.       msgsnd(mq_id, &index_number, sizeof(index_number)-sizeof(long), 0);
  534.  
  535.       pthread_cond_signal(&shared_mutex_torre->cond);
  536.      
  537.         //adiciona o novo elemento a lista de espera  e ordena-o
  538.    
  539.     }
  540.     else if(msg.msgtyp == 1){
  541.       i=0;
  542.       printf("--------TORRE DE CONTROLO--------\n\n");
  543.  
  544.       printf("---PRIORITY FLIGHT---\n\n");
  545.      
  546.       //adiciona o novo elemento à shm memory e envia o id para a thread
  547.        while (strcmp(shm_chegada[i].arr.nome,"\0") != 0)
  548.       {
  549.         i++;
  550.       }
  551.       sem_wait(shared_sem);
  552.       strcpy(shm_chegada[i].arr.nome,msg.nome);
  553.       shm_chegada[i].arr.inicial = msg.init;
  554.       shm_chegada[i].eta = msg.eta;
  555.       shm_chegada[i].combustivel = msg.combustivel;
  556.       index_number.msgtype = msg.id_thread;
  557.       index_number.id_sh = i;
  558.       sem_post(shared_sem);
  559.       insere_fila_chegada(fila_espera_prioridade,msg.nome,msg.init, msg.eta,msg.combustivel);
  560.       //falta o id
  561.       imprime_lista_chegada(fila_espera_prioridade);
  562.       msgsnd(mq_id, &index_number, sizeof(index_number)-sizeof(long), 0);
  563.       pthread_cond_signal(&shared_mutex_torre->cond);
  564.       //adiciona o novo elemento a lista de espera  e ordena-o
  565.     }
  566.   }
  567. }
  568. }
  569.  
  570. void termina_thread_manage(){
  571.     for(int i=4; i<n_voos+4; i++){
  572.       pthread_join(thread_voo[i], NULL);
  573.     }
  574. }
  575.  
  576.  
  577.  
  578. void termina_programa_processo_torre(int signum){
  579.   signal(SIGINT,termina_programa_processo_torre);
  580.  
  581.   sem_wait(sem_terminar);
  582.   terminar = 1;
  583.   sem_post(sem_terminar);
  584.  
  585.   pthread_cond_signal(&shared_mutex_torre->cond);
  586.  
  587.   //Vai fazer join das treads
  588.   pthread_join(thread_gerir_id,NULL);
  589.  
  590.  
  591.   //elimina fila espera de chegada
  592.   lista_voo_chegada auxA = fila_espera_chegada->next;
  593.   lista_voo_chegada nextA;
  594.   while(auxA!=NULL){
  595.     nextA = auxA->next;
  596.     free(auxA);
  597.     auxA=nextA;
  598.     }
  599.  
  600.   //elimina fila espera de partida
  601.   lista_voo_partida auxB = fila_espera_partida->next;
  602.   lista_voo_partida nextB;
  603.   while(auxB!=NULL){
  604.     nextB = auxB->next;
  605.     free(auxB);
  606.     auxB=nextB;
  607.     }
  608.  
  609.   exit(0);
  610. }
  611.  
  612. void termina_programa(int signum){
  613.   signal(SIGINT, termina_programa);
  614.  
  615.   sem_wait(sem_terminar);
  616.   terminar = 1;
  617.   sem_post(sem_terminar);
  618.  
  619.   //fecha e da unlink ao named pipe
  620.   close(pipe_id);
  621.     unlink(PIPE_NAME);
  622.  
  623.  
  624.   //limpa lista de voos
  625.   lista_voos auxC = lista_voo_aux->next;
  626.   lista_voos nextC;
  627.   while(auxC!=NULL){
  628.     nextC = auxC->next;
  629.     free(auxC);
  630.     auxC=nextC;
  631.     }
  632.  
  633.   //manda um signal a thread manage
  634.   pthread_cond_signal(&cond);
  635.  
  636.   // join da thread_manage que esta a fazer join das threads voo
  637.   pthread_join(thread_manage_id,NULL);
  638.  
  639.   //limpa lista de voos chegada
  640.   lista_voo_chegada auxA = lista_chegada->next;
  641.   lista_voo_chegada nextA;
  642.   while(auxA!=NULL){
  643.     nextA = auxA->next;
  644.     free(auxA);
  645.     auxA=nextA;
  646.     }
  647.  
  648.   //limpa lista de voos partida
  649.   lista_voo_partida auxB = lista_partida->next;
  650.   lista_voo_partida nextB;
  651.   while(auxB!=NULL){
  652.     nextB = auxB->next;
  653.     free(auxB);
  654.     auxB=nextB;
  655.     }
  656.  
  657.   //espera que acabe o processo torre
  658.   waitpid(pid_torre,NULL,0);
  659.  
  660.   //eliminar msq
  661.   msgctl(mq_id, IPC_RMID, 0);
  662.  
  663.   //elimina mutexes pthread
  664.   pthread_mutex_destroy(&mutex_thread);
  665.   pthread_cond_destroy(&cond);
  666.  
  667.   pthread_condattr_destroy(&attrcond);
  668.   pthread_mutexattr_destroy(&attrmutex);
  669.  
  670.   pthread_mutex_destroy(&shared_mutex->mutex);
  671.   pthread_cond_destroy(&shared_mutex->cond);
  672.  
  673.   pthread_condattr_destroy(&attrcond_torre);
  674.   pthread_mutexattr_destroy(&attrmutex_torre);
  675.  
  676.   pthread_mutex_destroy(&shared_mutex_torre->mutex);
  677.   pthread_cond_destroy(&shared_mutex_torre->cond);
  678.   //elimina shm
  679.   shmdt(shm_chegada);
  680.     shmctl(shm_chegad_id,IPC_RMID,NULL);
  681.  
  682.     shmdt(shm_partida);
  683.     shmctl(shm_partida_id,IPC_RMID,NULL);
  684.  
  685.   shmdt(shared_mutex_torre);
  686.     shmctl(shmid_mutex_torre,IPC_RMID,NULL);
  687.  
  688.   shmdt(shared_mutex);
  689.     shmctl(shmid_mutex,IPC_RMID,NULL);
  690.  
  691.     shmdt(stats);
  692.     shmctl(shm_stats_id,IPC_RMID,NULL);
  693.  
  694.   shmdt(shared_sem);
  695.     shmctl(shmid_mutex,IPC_RMID,NULL);
  696.  
  697.   //termina ultimo processo e programa
  698.   exit(0);
  699. }
  700.  
  701. //funcao que calcula hora do sistema e returna string no formato 19:35:01
  702. char * horas(){
  703.     char * aux;
  704.     aux = malloc(sizeof(char*));
  705.     time_t atual;
  706.     time(&atual);
  707.     struct tm *hora_local = localtime(&atual);
  708.     sprintf(aux, "%02d:%02d:%02d", hora_local->tm_hour, hora_local->tm_min, hora_local->tm_sec);
  709.     return aux;
  710. }
  711.  
  712. //funcao que guarda hora de inicio do programa, em segundos
  713. void hora_inicio(){
  714.   int hora_incial,minutos_inicial,segundos_inicial;
  715.   time_t atual;
  716.   time(&atual);
  717.   struct tm *hora_local = localtime(&atual);
  718.   hora_incial= hora_local->tm_hour * 60 * 60;
  719.   minutos_inicial= hora_local->tm_min * 60;
  720.   segundos_inicial= hora_local->tm_sec;
  721.   ut_inicial = hora_incial + minutos_inicial + segundos_inicial;
  722. }
  723.  
  724. //funcao que devolve hora atual do programa em ut
  725. double hora_ut(){
  726.   double aux,aux2;
  727.   time_t atual;
  728.   time(&atual);
  729.   struct tm *hora_local = localtime(&atual);
  730.   aux = (((hora_local->tm_hour * 60 * 60) + (hora_local->tm_min * 60) + hora_local->tm_sec)-ut_inicial);
  731.   aux2 =  aux*ut/1000;
  732.   return(aux2);
  733. }
  734.  
  735. double calcula_init(int init){
  736.   double final,aux;
  737.   int var;
  738.   var = init;
  739.   aux = (double) ut;
  740.   var = init-hora_ut();
  741.   if(var <= 0){
  742.     final = 0;
  743.     return final;
  744.   }
  745.   else{
  746.   final = (aux/1000) * var;
  747.   return final;
  748.   }
  749. }
  750.  
  751.  
  752.  
  753. void imprime_lista_partida(lista_voo_partida head){
  754.     lista_voo_partida atual = head->next;
  755.     printf("LISTA DE ESPERA - VOOS PARTIDA\n");
  756.       while (atual != NULL) {
  757.         printf("----------------\n");
  758.         printf("NOME: %s \n", atual->dep.nome);
  759.         printf("Takeoff : %d\n ", atual->descolagem);
  760.         printf("----------------\n");
  761.         atual = atual->next;
  762.          
  763.       }
  764. }
  765.  
  766. void imprime_lista_voos(lista_voos head){
  767.     lista_voos atual = head->next;
  768.       printf("LISTA DE VOOS\n");
  769.       while (atual != NULL) {
  770.         printf("----------------\n");
  771.         printf("NAME: %s \n",atual->nome);
  772.         printf("INIT: %d \n",atual->inicial);
  773.         printf("----------------\n");
  774.         printf("\n\n");
  775.         atual = atual->next;
  776.       }
  777. }
  778.  
  779.  
  780. void imprime_lista_chegada(lista_voo_chegada head){
  781.     lista_voo_chegada atual = head->next;
  782.     printf("LISTA DE ESPERA - VOOS CHEGADA\n");
  783.     while (atual != NULL) {
  784.       printf("----------------\n");
  785.       printf("NOME:%s\n", atual->arr.nome);
  786.       printf("INIT :%d\n", atual->arr.inicial);
  787.       printf("FUEL: %d \n",atual->combustivel);
  788.       printf("ETA: %d\n",atual->eta);
  789.       printf("----------------\n");
  790.       atual = atual->next;
  791.     }
  792. }
  793.  
  794.  
  795. lista_voos cria_lista_voos(){
  796.   lista_voos head = NULL;
  797.   head = (lista_voos)malloc(sizeof(voo_aux));
  798.   if(head != NULL){
  799.     strcpy(head->nome," ");
  800.     head->inicial = 0;
  801.     head->next = NULL;
  802.   }
  803.   return(head);
  804. }
  805.  
  806.  
  807. lista_voo_partida cria_lista_partida(){
  808.   lista_voo_partida head = NULL;
  809.   head = (lista_voo_partida) malloc(sizeof(voo_partida));
  810.   if(head != NULL){
  811.     strcpy(head->dep.nome," ");
  812.     head->dep.inicial = 0;
  813.     head->descolagem = 0;
  814.     head->next = NULL;
  815.   }
  816.   return(head);
  817. }
  818.  
  819. lista_voo_chegada cria_lista_chegada(){
  820.   lista_voo_chegada head = NULL;
  821.   head = (lista_voo_chegada) malloc(sizeof(voo_chegada));
  822.   if(head != NULL){
  823.     strcpy(head->arr.nome," ");
  824.     head->arr.inicial = 0;
  825.     head->eta = 0;
  826.     head->combustivel = 0;
  827.     head->next = NULL;
  828.   }
  829.   return (head);
  830. }
  831.  
  832.  
  833. void insere_lista_voos(lista_voos head, char * n, int init){
  834.     lista_voos atual;
  835.     lista_voos ant, inutil;
  836.     atual = (lista_voos) malloc (sizeof (voo_aux));
  837.     if (atual != NULL)
  838.     {
  839.       strcpy(atual->nome,n);
  840.         atual->inicial = init;
  841.      
  842.         procura_lista_voos(head, init, &ant, &inutil);
  843.       atual->next = ant->next;
  844.       ant->next = atual;
  845.     }
  846. }
  847.  
  848. void insere_lista_partida(lista_voo_partida head, char * n, int init, int desc){
  849.     lista_voo_partida atual;
  850.     lista_voo_partida ant, inutil;
  851.     atual = (lista_voo_partida) malloc (sizeof (voo_partida));
  852.     if (atual != NULL)
  853.     {
  854.       strcpy(atual->dep.nome,n);
  855.         atual->dep.inicial = init;
  856.         atual->descolagem = desc;
  857.      
  858.         procura_lista_partida(head, init, &ant, &inutil);
  859.       atual->next = ant->next;
  860.       ant->next = atual;
  861.     }
  862. }
  863.  
  864.  
  865.  
  866. void insere_fila_partida(lista_voo_partida head, char * n, int init, int desc){
  867.    lista_voo_partida atual;
  868.     lista_voo_partida ant, inutil;
  869.     atual = (lista_voo_partida) malloc (sizeof (voo_partida));
  870.     if (atual != NULL)
  871.     {
  872.       strcpy(atual->dep.nome,n);
  873.         atual->dep.inicial = init;
  874.         atual->descolagem = desc;
  875.      
  876.         procura_fila_partida(head, desc, &ant, &inutil);
  877.       atual->next = ant->next;
  878.       ant->next = atual;
  879.     }
  880. }
  881.  
  882.  
  883. int checkNome(lista_voos lista,char *nome){
  884.   lista_voos atual;
  885.   atual = lista->next;
  886.   if(atual == NULL){
  887.     return 0;
  888.   }
  889.   else{
  890.     while(atual->next != NULL){
  891.       if(strcmp(atual->nome,nome) == 0){
  892.         return 1;
  893.       }
  894.       atual = atual->next;
  895.     }
  896.     return 0;
  897.     }
  898. }
  899.  
  900.  
  901. void procura_lista_voos(lista_voos lista, int chave, lista_voos *ant, lista_voos *atual)
  902. {
  903.     *ant = lista;
  904.     *atual = lista->next;
  905.     while ((*atual) != NULL &&( ((*atual)->inicial) < chave))
  906.     {
  907.         *ant = *atual;
  908.         *atual = (*atual) -> next;
  909.     }
  910. }
  911.  
  912.  
  913. void procura_lista_partida(lista_voo_partida lista, int chave, lista_voo_partida *ant, lista_voo_partida *atual)
  914. {
  915.     *ant = lista;
  916.     *atual = lista->next;
  917.     while ((*atual) != NULL &&( ((*atual)->dep.inicial) < chave))
  918.     {
  919.         *ant = *atual;
  920.         *atual = (*atual) -> next;
  921.     }
  922. }
  923.  
  924. void procura_fila_partida(lista_voo_partida lista, int chave, lista_voo_partida *ant, lista_voo_partida *atual)
  925. {
  926.     *ant = lista;
  927.     *atual = lista->next;
  928.     while ((*atual) != NULL &&( ((*atual)->descolagem) < chave))
  929.     {
  930.         *ant = *atual;
  931.         *atual = (*atual) -> next;
  932.     }
  933. }
  934.  
  935.  
  936. void insere_lista_chegada(lista_voo_chegada head, char * n, int init, int eta, int fuel){
  937.     lista_voo_chegada atual;
  938.     lista_voo_chegada ant, inutil;
  939.     atual = (lista_voo_chegada) malloc (sizeof (voo_chegada));
  940.     if (atual != NULL)
  941.     {
  942.       strcpy(atual->arr.nome,n);
  943.       atual->arr.inicial = init;
  944.       atual->eta = eta;
  945.       atual->combustivel = fuel;
  946.     }
  947.  
  948.       procura_lista_chegada(head, init, &ant, &inutil);
  949.     atual->next = ant->next;
  950.     ant->next = atual;
  951. }
  952.  
  953.  
  954. void insere_fila_chegada(lista_voo_chegada head, char * n, int init, int eta, int fuel){
  955.     lista_voo_chegada atual;
  956.     lista_voo_chegada ant, inutil;
  957.     atual = (lista_voo_chegada) malloc (sizeof (voo_chegada));
  958.     if (atual != NULL)
  959.     {
  960.       strcpy(atual->arr.nome,n);
  961.       atual->arr.inicial = init;
  962.       atual->eta = eta;
  963.       atual->combustivel = fuel;
  964.     }
  965.  
  966.       procura_fila_chegada(head, eta, &ant, &inutil);
  967.     atual->next = ant->next;
  968.     ant->next = atual;
  969. }
  970.  
  971. void procura_fila_chegada(lista_voo_chegada lista, int chave, lista_voo_chegada *ant, lista_voo_chegada *atual)
  972. {
  973.     *ant = lista;
  974.     *atual = lista->next;
  975.     while ((*atual) != NULL && ((*atual)->eta) < chave)
  976.     {
  977.         *ant = *atual;
  978.         *atual = (*atual) -> next;
  979.     }
  980. }
  981.  
  982.  
  983.  
  984. void procura_lista_chegada(lista_voo_chegada lista, int chave, lista_voo_chegada *ant, lista_voo_chegada *atual)
  985. {
  986.     *ant = lista;
  987.     *atual = lista->next;
  988.     while ((*atual) != NULL &&( ((*atual)->arr.inicial) < chave))
  989.     {
  990.         *ant = *atual;
  991.         *atual = (*atual) -> next;
  992.     }
  993. }
  994.  
  995.  
  996. //funcao de escrita no log
  997. void escreve_log(char *aux){
  998.   sem_wait(log_mutex);
  999.     fprintf(flog,"%s %s\n",horas(),aux);
  1000.   sem_post(log_mutex);
  1001.   fflush(0);
  1002. }
  1003.  
  1004. //Funcao de leitura da config inicial do programa
  1005. void ler_config(){
  1006.     FILE * fconfig;
  1007.     int linha=0;
  1008.     char buffer1[MAX2],buffer2[MAX2];
  1009.  
  1010.     if ((fconfig=fopen("config.txt", "r")) == NULL){
  1011.     perror("Erro ao abrir o ficheiro config\n");
  1012.     exit(1);
  1013.   }else{
  1014.     while (linha!=6){
  1015.       linha++;
  1016.       if(linha==1){
  1017.         fscanf(fconfig, "%s", buffer1);
  1018.         ut = atoi(buffer1);
  1019.       }else if(linha==2){
  1020.         fscanf(fconfig, "%[^,],%s", buffer1,buffer2);
  1021.         dur_descolagem = atoi(buffer1);
  1022.         int_descolagem = atoi(buffer2);
  1023.       }else if(linha==3){
  1024.         fscanf(fconfig, "%[^,],%s", buffer1,buffer2);
  1025.         dur_aterragem = atoi(buffer1);
  1026.         int_aterragem = atoi(buffer2);
  1027.       }else if(linha==4){
  1028.         fscanf(fconfig, "%[^,],%s", buffer1,buffer2);
  1029.         holding_min = atoi(buffer1);
  1030.         holding_max = atoi(buffer2);
  1031.       }else if(linha==5){
  1032.         fscanf(fconfig, "%s", buffer1);
  1033.         max_partidas = atoi(buffer1);
  1034.       }else if(linha==6){
  1035.         fscanf(fconfig, "%s", buffer1);
  1036.         max_chegadas = atoi(buffer1);
  1037.       }
  1038.     }
  1039.     fclose(fconfig);
  1040.     debug_print("Ficheiro cfg lido");
  1041.     }
  1042. }
  1043.  
  1044. //------------------Shared Memory Estatistica------------------------
  1045. void cria_shm_stats(){
  1046.   if((shm_stats_id = shmget(IPC_PRIVATE,(sizeof(estatistica)),IPC_CREAT | 0766)) < 0){
  1047.         perror("Erro ao criar a memoria partilhada para as estatisticas ( IPC_CREAT)");
  1048.     }else{
  1049.     if(( stats = (estatistica *) shmat(shm_stats_id,NULL,0)) == (estatistica *)-1){
  1050.       perror("Erro ao criar a memoria partilhada para as estatisticas ( IPC_CREAT)");
  1051.     }
  1052.     else{
  1053.       stats->total_voos_criados = 0;
  1054.       stats->media_manobras_aterragem = 0;
  1055.       stats->total_voos_descolaram = 0;
  1056.       stats->total_voos_aterraram = 0;
  1057.       stats->media_manobras_emergencia = 0;
  1058.       stats->voos_redirecionados = 0;
  1059.       stats->voos_rejeitados = 0;
  1060.       stats->tempo_medio_espera_aterrar = 0;
  1061.       stats->tempo_medio_espera_descolar = 0;
  1062.       debug_print("Memoria partilhada Estatistica criada");
  1063.     }
  1064.   }
  1065. }
  1066.  
  1067. //------------------Shared Memory Partidas------------------------
  1068.  
  1069. void cria_shm_partida(){
  1070.   if((shm_partida_id = shmget(IPC_PRIVATE,sizeof(voo_partida) * max_partidas,IPC_CREAT | 0766)) <0){
  1071.     perror("Erro a criar memoria partilhada para os voos de partida ");
  1072.   }
  1073.   if (( shm_partida = (voo_partida *) shmat(shm_partida_id,NULL,0)) == (voo_partida *)-1){
  1074.     perror("Erro a criar memoria partilhada para os voos de partida ");
  1075.   }
  1076.   else{
  1077.     debug_print("Memoria partilhada para os voos de partida criada com sucesso");
  1078.     int i;
  1079.     for(i = 0; i<max_partidas; i++){
  1080.  
  1081.       strcpy(shm_partida[i].dep.nome,"\0");
  1082.       shm_partida[i].dep.var = 0;
  1083.       shm_partida[i].dep.inicial = 0;
  1084.       shm_partida[i].descolagem = 0;
  1085.     }
  1086.   }
  1087.  
  1088. }
  1089. //------------------Shared Memory chegadas------------------------
  1090. void cria_shm_chegada(){
  1091.   if((shm_chegad_id = shmget(IPC_PRIVATE,sizeof(voo_chegada) * max_chegadas,IPC_CREAT | 0766)) <0){
  1092.     perror("Erro a criar memoria partilhada para os voos de chegada ");
  1093.   }
  1094.   if (( shm_chegada = (voo_chegada *) shmat(shm_chegad_id,NULL,0)) == (voo_chegada *)-1){
  1095.     perror("Erro a criar memoria partilhada para os voos de chegada ");
  1096.   }
  1097.   else{
  1098.     debug_print("Memoria partilhada para os voos de chegada criada com sucesso");
  1099.     int i;
  1100.     for(i = 0; i<max_chegadas; i++){
  1101.  
  1102.       strcpy(shm_chegada[i].arr.nome,"\0");
  1103.       shm_chegada[i].arr.var = 0;
  1104.       shm_chegada[i].arr.inicial = 0;
  1105.       shm_chegada[i].combustivel = 0;
  1106.       shm_chegada[i].eta = 0;
  1107.     }
  1108.   }
  1109. }
  1110.  
  1111. //funcao que cria pipe
  1112. void cria_pipe(){
  1113.   unlink(PIPE_NAME);
  1114.   if ((mkfifo(PIPE_NAME, O_CREAT|O_EXCL|0600)<0) && (errno!= EEXIST)){ // Cria o pipe
  1115.     perror("Erro ao inicializar PIPE");
  1116.   }else{
  1117.     if ((pipe_id=open(PIPE_NAME, O_RDWR)) < 0){
  1118.       perror("Impossivel abrir Pipe para leitura");
  1119.       exit(0);
  1120.     }else{
  1121.     debug_print("Named Pipe criado");
  1122.     }
  1123.   }
  1124. }
  1125.  
  1126. void *abre_pipe(){
  1127.   char aux[MAX],*buffer1;
  1128.   char auxNome[MAX2];
  1129.   int a,b,c;
  1130.   char original[MAX],erro[MAX],correto[MAX];
  1131.  
  1132.   while (1) {
  1133.     read(pipe_id, &aux, sizeof(char[MAX]));
  1134.     strcpy(original,aux);
  1135.     sprintf(correto,"%s%s","NEW COMMAND => ",original);
  1136.     sprintf(erro,"%s%s","WRONG COMMAND => ",original);
  1137.     buffer1 = strtok(aux," ");
  1138.  
  1139.     if(strcmp(buffer1,"ARRIVAL") == 0){
  1140.  
  1141.       //echo ARRIVAL TP437 init: 100 eta: 100 fuel: 1000 >> "input_pipe"
  1142.       //guarda nome
  1143.       buffer1 = strtok(NULL, " ");
  1144.       strcpy(auxNome, buffer1);
  1145.       //init:
  1146.       buffer1 = strtok(NULL, " ");
  1147.       if(strcmp(buffer1,"init:")!=0){
  1148.         escreve_log(erro);
  1149.         continue;
  1150.       }
  1151.       //init: 100
  1152.       buffer1 = strtok(NULL, " ");
  1153.       a = atoi(buffer1);
  1154.       if(a==0){
  1155.         escreve_log(erro);
  1156.         continue;
  1157.       }
  1158.       if(a<hora_ut()){
  1159.         escreve_log(erro);
  1160.         continue;
  1161.       }
  1162.       //eta:
  1163.       buffer1 = strtok(NULL, " ");
  1164.       if(strcmp(buffer1,"eta:")!=0){
  1165.         escreve_log(erro);
  1166.         continue;
  1167.       }
  1168.       //eta: 120
  1169.       buffer1 = strtok(NULL, " ");
  1170.       b = atoi(buffer1);
  1171.       if(b==0){
  1172.         escreve_log(erro);
  1173.         continue;
  1174.       }
  1175.       if(b<hora_ut() || b<a){
  1176.         escreve_log(erro);
  1177.         continue;
  1178.       }
  1179.       //fuel
  1180.       buffer1 = strtok(NULL, " ");
  1181.       if(strcmp(buffer1,"fuel:")!=0){
  1182.         escreve_log(erro);
  1183.         continue;
  1184.       }
  1185.       //fuel: 1000
  1186.       buffer1 = strtok(NULL, " ");
  1187.       c = atoi(buffer1);
  1188.       if(c==0){
  1189.         escreve_log(erro);
  1190.         continue;
  1191.       }
  1192.       if(c<b){
  1193.         escreve_log(erro);
  1194.         continue;
  1195.       }
  1196.       //pthread_mutex_unlock(&mutex_thread);
  1197.       pthread_mutex_lock(&mutex_thread);
  1198.       if((checkNome(lista_voo_aux,auxNome)== 0)){
  1199.         printf("O voo %s não existe no sistema, pode prosseguir\n",auxNome);
  1200.         insere_lista_chegada(lista_chegada,auxNome,a,b,c);
  1201.         insere_lista_voos(lista_voo_aux,auxNome,a);
  1202.         pthread_cond_signal(&cond);
  1203.       }
  1204.       else{
  1205.         printf("O voo %s já se encontra no sistema, acesso negado\n",auxNome);
  1206.       }
  1207.       pthread_mutex_unlock(&mutex_thread);
  1208.       escreve_log(correto);
  1209.  
  1210.     }else if(strcmp(buffer1,"DEPARTURE") == 0 ){
  1211.       int i;
  1212.       //nome
  1213.       buffer1 = strtok(NULL, " ");
  1214.       strcpy(auxNome, buffer1);
  1215.       //init:
  1216.       buffer1 = strtok(NULL, " ");
  1217.       if(strcmp(buffer1,"init:")!=0){
  1218.         escreve_log(erro);
  1219.         continue;
  1220.       }
  1221.       //init:100
  1222.       buffer1 = strtok(NULL, " ");
  1223.       a = atoi(buffer1);
  1224.       if(a==0){
  1225.         escreve_log(erro);
  1226.         continue;
  1227.       }
  1228.       if(a<hora_ut()){
  1229.         escreve_log(erro);
  1230.         continue;
  1231.       }
  1232.       //takeoff:
  1233.       buffer1 = strtok(NULL, " ");
  1234.       if(strcmp(buffer1,"takeoff:")!=0){
  1235.         escreve_log(erro);
  1236.         continue;
  1237.       }
  1238.       //takeoff: 100
  1239.       buffer1 = strtok(NULL, " ");
  1240.       b = atoi(buffer1);
  1241.       if(b==0){
  1242.         escreve_log(erro);
  1243.         continue;
  1244.       }
  1245.       if(b<hora_ut() || b<a){
  1246.         escreve_log(erro);
  1247.         continue;
  1248.       }
  1249.       i = 0;
  1250.       pthread_mutex_lock(&mutex_thread);
  1251.       if((checkNome(lista_voo_aux,auxNome)== 0)){
  1252.  
  1253.         printf("O voo %s não existe no sistema pode prosseguir\n",auxNome);
  1254.         //se o i = max_chegadas diz logo que nao dá e sai -> FAZER
  1255.         insere_lista_partida(lista_partida,auxNome,a,b);
  1256.         insere_lista_voos(lista_voo_aux,auxNome,a);
  1257.         pthread_cond_signal(&cond);
  1258.        
  1259.       }
  1260.       else{
  1261.         printf("O voo %s já se encontra no sistema, acesso negado\n",auxNome);
  1262.       }
  1263.       pthread_mutex_unlock(&mutex_thread);
  1264.       escreve_log(correto);
  1265.  
  1266.     }else{
  1267.         escreve_log(erro);
  1268.     }
  1269.   }
  1270. }
  1271.  
  1272. //DEPARTURE TP440 init: 0 takeoff: 100 >> "input_pipe"
  1273. //echo ARRIVAL TP437 init: 100 eta: 100 fuel: 1000 >> "input_pipe"
  1274.  
  1275. //mutex para o ficheiro de escrita no log
  1276. void cria_semaforos(){
  1277.     sem_unlink("LOG_MUTEX");
  1278.     if((log_mutex = sem_open("LOG_MUTEX",O_CREAT|O_EXCL,0766,1))==SEM_FAILED){
  1279.         perror("Impossivel incializar o Semaforo para o Log File\n");
  1280.         sem_unlink("LOG_MUTEX");
  1281.         exit(0);
  1282.     }
  1283.   sem_unlink("SHM_SEM");
  1284.   if((shared_sem = sem_open("SHM_SEM",O_CREAT|O_EXCL,0766,1))==SEM_FAILED){
  1285.     perror("Impossivel incializar o Semaforo para a Shared Memory\n");
  1286.         sem_unlink("SHM_SEM");
  1287.         exit(0);
  1288.   }
  1289.   sem_unlink("SEM_TERMINAR");
  1290.   if((sem_terminar = sem_open("SEM_TERMINAR",O_CREAT|O_EXCL,0766,1))==SEM_FAILED){
  1291.     perror("Impossivel incializar o Semaforo para a flag do control-c\n");
  1292.         sem_unlink("SEM_TERMINAR");
  1293.         exit(0);
  1294.   }
  1295.   else{
  1296.     debug_print("Semaforos criados");
  1297.   }
  1298.  
  1299.  
  1300.   if((shmid_mutex = shmget(IPC_PRIVATE,(sizeof(mutua)),IPC_CREAT | 0777)) <0){
  1301.         escreve_log("Erro ao criar shared_mutex\n");
  1302.    
  1303.     }
  1304.  
  1305.   if (( shared_mutex = (mutua *) shmat(shmid_mutex,NULL,0)) == (mutua *)-1){
  1306.         escreve_log("Erro ao criar shared_mutex\n");
  1307.     }
  1308.   pthread_mutexattr_init(&attrmutex);
  1309.   pthread_condattr_init(&attrcond);
  1310.  
  1311.    if((pthread_mutexattr_setpshared(&attrmutex, PTHREAD_PROCESS_SHARED))!=0){
  1312.     escreve_log("Deu erro\n");
  1313.   }
  1314.     if((pthread_condattr_setpshared(&attrcond, PTHREAD_PROCESS_SHARED))!=0){
  1315.     escreve_log(" Deu erro\n");
  1316.   }
  1317.  
  1318.     if((shmid_mutex_torre = shmget(IPC_PRIVATE,(sizeof(mutua)),IPC_CREAT | 0777)) <0){
  1319.         escreve_log("Erro ao criar shared_mutex\n");
  1320.    
  1321.     }
  1322.  
  1323.   if (( shared_mutex_torre = (mutua *) shmat(shmid_mutex_torre,NULL,0)) == (mutua *)-1){
  1324.         escreve_log("Erro ao criar shared_mutex\n");
  1325.     }
  1326.   pthread_mutexattr_init(&attrmutex_torre);
  1327.   pthread_condattr_init(&attrcond_torre);
  1328.  
  1329.    if((pthread_mutexattr_setpshared(&attrmutex_torre, PTHREAD_PROCESS_SHARED))!=0){
  1330.     escreve_log("Deu erro\n");
  1331.   }
  1332.     if((pthread_condattr_setpshared(&attrcond_torre, PTHREAD_PROCESS_SHARED))!=0){
  1333.     escreve_log(" Deu erro\n");
  1334.   }
  1335.  
  1336. }
  1337.  
  1338. //--------------Message Queue------------------
  1339. void cria_mq(){
  1340. mq_id = msgget(IPC_PRIVATE, IPC_CREAT|0777);
  1341.   if (mq_id < 0)
  1342.   {
  1343.     perror("Erro ao inicializar a message queue");
  1344.   }
  1345.   else{
  1346.     debug_print("Message queue criada");
  1347.   }
  1348. }
  1349.  
  1350. int check_shm(int id,int flag){
  1351.  
  1352.   sem_wait(shared_sem);
  1353.   if(flag == 2){
  1354.     if(shm_partida[id].dep.var == 1){
  1355.       printf("Voo %s partiu\n" ,shm_partida[id].dep.nome);
  1356.       sem_post(shared_sem);
  1357.       return 1;
  1358.     }
  1359.     else
  1360.     {
  1361.       sem_post(shared_sem);
  1362.       return 0;
  1363.     }
  1364.   }
  1365.   else if(flag == 1){
  1366.     if(shm_chegada[id].arr.var == 1){
  1367.     printf("Voo %s aterrou\n" ,shm_chegada[id].arr.nome);
  1368.     sem_post(shared_sem);
  1369.     return 1;
  1370.     }
  1371.     else
  1372.     {
  1373.       sem_post(shared_sem);
  1374.       return 0;
  1375.     }
  1376.   }
  1377.  
  1378. }
  1379.  
  1380. //thread voo
  1381. void *thread_worker(void* a){
  1382.  
  1383.   sigset_t signal_set;
  1384.   sigemptyset(&signal_set);
  1385.   sigaddset(&signal_set,SIGINT);
  1386.   pthread_sigmask(SIG_BLOCK, &signal_set,NULL);
  1387.  
  1388.   int id,flag,id_shared;
  1389.   mensagem msg;
  1390.   callback_id call;
  1391.   struct thread_info *args = a;
  1392.   flag = args->flag ;
  1393.   id = args->id;
  1394.   id_shared = 0;
  1395.   char nome[MAX2];
  1396.   char str[MAX2];
  1397.  
  1398.   pthread_mutex_lock(&mutex_thread);
  1399.  
  1400.   //vai buscar o ultimo elemento da lista de voos para enviar pela mq a info
  1401.  
  1402.   //procura na lista de voos de partida
  1403.  
  1404.  
  1405.   debug_print("Thread Voo Criada");
  1406.  
  1407.   if(flag == 2){
  1408.     strcpy(msg.nome,lista_partida->next->dep.nome);
  1409.     msg.eta = 0;
  1410.     strcpy(nome,lista_partida->next->dep.nome);
  1411.  
  1412.     sprintf(str,"FLIGHT %s IS ON  THE RADAR\n", nome);
  1413.     escreve_log(str);
  1414.     msg.combustivel = 0;
  1415.     msg.msgtyp = 3;
  1416.     msg.instante_partida = lista_partida->next->descolagem;
  1417.     msg.id_thread = id;
  1418.     msg.init = lista_partida->next->dep.inicial;
  1419.     msgsnd(mq_id, &msg, sizeof(msg)-sizeof(long), 0);
  1420.     msgrcv(mq_id, &call, sizeof(call)-sizeof(long), id, 0);
  1421.     id_shared = call.id_sh;
  1422.     printf("ID shared memory- %d\n", id_shared);
  1423.     remove_lista_partida(lista_partida,lista_partida->next->dep.nome);
  1424.  
  1425.   } //procura na lista de voos de chegada
  1426.   else if(flag == 1){
  1427.     if(lista_chegada->next->combustivel <= 4 * ut + lista_chegada->next->eta){
  1428.       msg.msgtyp = 1;
  1429.       printf("PRIORITY\n");
  1430.       strcpy(nome,lista_chegada->next->arr.nome);
  1431.       sprintf(str,"FLIGHT %s IS ON  THE RADAR\n", nome);
  1432.       escreve_log(str);
  1433.       strcpy(msg.nome,lista_chegada->next->arr.nome);
  1434.       msg.eta = lista_chegada->next->eta;
  1435.       msg.combustivel = lista_chegada->next->combustivel;
  1436.       msg.init = lista_chegada->next->arr.inicial;
  1437.       msg.id_thread = id;
  1438.       msg.instante_partida = 0;
  1439.      
  1440.       msgsnd(mq_id, &msg, sizeof(msg)-sizeof(long), 0);
  1441.      
  1442.       msgrcv(mq_id, &call, sizeof(call)-sizeof(long), id, 0);
  1443.       id_shared = call.id_sh;
  1444.       printf("ID shared memory- %d\n", id_shared);
  1445.     }
  1446.     else{
  1447.      
  1448.       printf("NOT PRIORITY\n");
  1449.       strcpy(nome,lista_chegada->next->arr.nome);
  1450.       msg.msgtyp = 2;
  1451.       sprintf(str,"FLIGHT %s IS ON  THE RADAR\n", nome);
  1452.       escreve_log(str);
  1453.       strcpy(msg.nome,lista_chegada->next->arr.nome);
  1454.       msg.eta = lista_chegada->next->eta;
  1455.       msg.combustivel = lista_chegada->next->combustivel;
  1456.       msg.init = lista_chegada->next->arr.inicial;
  1457.       msg.id_thread = id;
  1458.       msg.instante_partida = 0;
  1459.       //imprime_lista_chegada(lista_chegada);
  1460.       msgsnd(mq_id, &msg, sizeof(mensagem)-sizeof(long), 0);
  1461.       //pthread_mutex_unlock(&mutex_thread)
  1462.       msgrcv(mq_id, &call, sizeof(call)-sizeof(long), id, 0);
  1463.       id_shared = call.id_sh;
  1464.      
  1465.       printf("ID shared memory- %d\n", id_shared);
  1466.     }
  1467.     remove_lista_chegada(lista_chegada,lista_chegada->next->arr.nome);
  1468.   }
  1469.   pthread_mutex_unlock(&mutex_thread);
  1470.  
  1471.   pthread_mutex_lock(&shared_mutex->mutex);
  1472.   while(check_shm(id_shared,flag)==0){
  1473.     pthread_cond_wait(&shared_mutex->cond,&shared_mutex->mutex);
  1474.   }
  1475.  
  1476.   if(flag == 2){ // partida
  1477.     double intervalo_desc_seg, duracao_desc_seg;
  1478.     intervalo_desc_seg = ut/1000 * int_descolagem;
  1479.     duracao_desc_seg =ut/1000 * dur_descolagem;
  1480.     printf("CHEGOU AO SLEEP PARTIDA\n");
  1481.     pthread_mutex_unlock(&shared_mutex->mutex);
  1482.     sleep(intervalo_desc_seg + duracao_desc_seg);
  1483.     pthread_mutex_lock(&shared_mutex_torre->mutex);
  1484.     printf("PASSOU AO SLEEP PARTIDA\n");
  1485.     if(pistas[0] == 1 && pistas[1] == 1){
  1486.       pistas[0] = 0;
  1487.     }
  1488.     else if(pistas[0] == 1 && pistas[1] == 0){
  1489.       pistas[0] = 0;
  1490.     }
  1491.     else if(pistas[1] == 1 && pistas[0] == 0){
  1492.     pistas[1] = 0;
  1493.     }
  1494.   }
  1495.   if(flag == 1){ // partida
  1496.   double intervalo_at_seg, duracao_at_seg;
  1497.   intervalo_at_seg = ut/1000 * int_aterragem;
  1498.   duracao_at_seg =ut/1000 * dur_aterragem;
  1499.   printf("CHEGOU AO SLEEP ATERRAGEM\n");
  1500.   pthread_mutex_unlock(&shared_mutex->mutex);
  1501.   sleep(intervalo_at_seg + duracao_at_seg);
  1502.   pthread_mutex_lock(&shared_mutex_torre->mutex);
  1503.   printf("PASSOU AO SLEEP ATERRAGEM\n");
  1504.     if(pistas[2] == 1 && pistas[3] == 1){
  1505.       pistas[2] = 0;
  1506.     }
  1507.     else if(pistas[2] == 1 && pistas[3] == 0){
  1508.       pistas[2] = 0;
  1509.     }
  1510.     else if(pistas[2] == 1 && pistas[3] == 0){
  1511.       pistas[3] = 0;
  1512.     }
  1513.   }
  1514.  
  1515.   pthread_mutex_unlock(&shared_mutex_torre->mutex);
  1516.   pthread_cond_signal(&shared_mutex_torre->cond);
  1517.   //Por a zero na memoria partilhada
  1518.   sprintf(str,"FLIGHT %s CONCLUDED\n", nome);
  1519.   escreve_log(str);
  1520.   n_voos--;
  1521.   pthread_exit(NULL);
  1522. }
  1523. //funcao que chama as funcoes todas de criar
  1524. void gestor(){
  1525.   ler_config();
  1526.   hora_inicio();
  1527.   cria_shm_stats();
  1528.   cria_shm_chegada();
  1529.   cria_shm_partida();
  1530.   cria_semaforos();
  1531.   pthread_mutex_init(&mutex_thread,NULL);
  1532.   pthread_cond_init(&cond, NULL);
  1533.     pthread_mutex_init(&shared_mutex->mutex, &attrmutex);
  1534.     pthread_cond_init(&shared_mutex->cond, &attrcond);
  1535.     pthread_mutex_init(&shared_mutex_torre->mutex, &attrmutex_torre);
  1536.     pthread_cond_init(&shared_mutex_torre->cond, &attrcond_torre);
  1537.   lista_chegada = cria_lista_chegada();
  1538.   lista_partida = cria_lista_partida();
  1539.   lista_voo_aux = cria_lista_voos();
  1540.   cria_mq();
  1541.   cria_pipe();
  1542. }
  1543.  
  1544. void remove_lista_chegada(lista_voo_chegada chegada, char *nome){
  1545.   lista_voo_chegada atual,ant;
  1546.   atual = chegada->next;
  1547.   ant = chegada;
  1548.   if(atual!= NULL){
  1549.     while (strcmp(atual->arr.nome,nome)!=0)
  1550.     {
  1551.       atual = atual->next;
  1552.       ant = ant->next;
  1553.     }
  1554.     ant->next = atual->next;
  1555.     free(atual);
  1556.   }
  1557. }
  1558.  
  1559. void remove_lista_voo(lista_voos chegada, char *nome){
  1560.   lista_voos atual,ant;
  1561.   atual = chegada->next;
  1562.   ant = chegada;
  1563.   if(atual!= NULL){
  1564.     ant->next = atual->next;
  1565.     free(atual);
  1566.   }
  1567. }
  1568.  
  1569. void remove_lista_partida(lista_voo_partida partida, char *nome){
  1570.   lista_voo_partida atual,ant;
  1571.   atual = partida->next;
  1572.   ant = partida;
  1573.   if(atual!= NULL){
  1574.     while (strcmp(atual->dep.nome,nome)!=0)
  1575.     {
  1576.       atual = atual->next;
  1577.       ant = ant->next;
  1578.     }
  1579.     ant->next = atual->next;
  1580.     free(atual);
  1581.   }
  1582. }
  1583.  
  1584. int checkLista(lista_voo_chegada chegadas, lista_voo_partida partidas,char *nome){
  1585.   lista_voo_partida atual_partida;
  1586.   lista_voo_chegada atual_chegada;
  1587.   atual_chegada = chegadas;
  1588.   atual_partida = partidas;
  1589.  
  1590.   if(atual_chegada->next == NULL){
  1591.     while(atual_partida->next != NULL){
  1592.       if(strcmp(atual_partida->next->dep.nome,nome) == 0){
  1593.         return 2;
  1594.       }
  1595.       else{
  1596.         atual_partida = atual_partida->next;
  1597.       }
  1598.     }
  1599.   }
  1600.   else if(atual_partida->next == NULL){
  1601.     while(atual_chegada->next != NULL){
  1602.       if(strcmp(atual_chegada->next->arr.nome,nome) == 0){
  1603.         return 1;
  1604.       }
  1605.       else{
  1606.         atual_chegada = atual_chegada->next;
  1607.       }
  1608.     }
  1609.   }
  1610.   else if(atual_partida->next != NULL && atual_chegada->next != NULL){
  1611.     while(atual_chegada->next != NULL){
  1612.       if(strcmp(atual_chegada->next->arr.nome,nome) == 0){
  1613.         return 1;
  1614.       }
  1615.       else{
  1616.         atual_chegada = atual_chegada->next;
  1617.       }
  1618.     }
  1619.     while(atual_partida->next != NULL){
  1620.       if(strcmp(atual_partida->dep.nome,nome) == 0){
  1621.         return 2;
  1622.       }
  1623.       else{
  1624.         atual_partida = atual_partida->next;
  1625.       }
  1626.     }
  1627.   }
  1628. }
  1629. int condition(){
  1630.   if(terminar == 1 && lista_voo_aux->next == NULL){
  1631.     termina_thread_manage();
  1632.     pthread_mutex_unlock(&mutex_thread);
  1633.     pthread_exit(NULL);
  1634.   }else{
  1635.     if(lista_voo_aux->next != NULL){
  1636.       if(lista_voo_aux->next->inicial <= hora_ut()){
  1637.         return 1;
  1638.       }
  1639.       else{
  1640.         return 0;
  1641.       }
  1642.     }
  1643.     else{
  1644.       return 0;
  1645.     }
  1646.   }
  1647. }
  1648.  
  1649. void *thread_manage(){
  1650.  
  1651.   sigset_t signal_set;
  1652.   sigemptyset(&signal_set);
  1653.   sigaddset(&signal_set,SIGINT);
  1654.   pthread_sigmask(SIG_BLOCK, &signal_set,NULL);
  1655.   struct thread_info args;
  1656.   int k;
  1657.   k=3;
  1658.   while(1){
  1659.         pthread_mutex_lock(&mutex_thread);
  1660.         while(condition() == 0){
  1661.           if(lista_voo_aux->next != NULL){
  1662.             clock_gettime(CLOCK_REALTIME, &ts);
  1663.             double var;
  1664.             var = calcula_init(lista_voo_aux->next->inicial);
  1665.             ts.tv_sec += var;
  1666.             pthread_cond_timedwait(&cond,&mutex_thread,&ts);
  1667.           }
  1668.           else{
  1669.             clock_gettime(CLOCK_REALTIME, &ts);
  1670.             ts.tv_sec += 5;
  1671.             printf("ESPEROU + 5seg\n");
  1672.             pthread_cond_wait(&cond,&mutex_thread);
  1673.           }
  1674.         }
  1675.         args.flag = checkLista(lista_chegada,lista_partida,lista_voo_aux->next->nome);
  1676.        
  1677.         remove_lista_voo(lista_voo_aux,lista_voo_aux->next->nome);
  1678.         imprime_lista_voos(lista_voo_aux);
  1679.         pthread_mutex_unlock(&mutex_thread);
  1680.         k++;
  1681.         args.id = k;
  1682.  
  1683.         if(pthread_create(&thread_voo[k],NULL,thread_worker,(void *) &args) !=0){
  1684.             perror("ERROR creating the thread pipe!\n");
  1685.           }
  1686.         else{
  1687.           n_voos++;  
  1688.         }
  1689.         // pthread_mutex_unlock(&mutex_thread);
  1690.       }
  1691. }
  1692.  
  1693. int main(){
  1694.  
  1695.   signal(SIGINT, termina_programa);
  1696.   pthread_mutex_init(&mutex_thread,NULL);
  1697.   pthread_cond_init(&cond, NULL);
  1698.  
  1699.   debug_print("Programa iniciado");
  1700.  
  1701.   flog=fopen("log.txt","w");
  1702.   gestor();
  1703.  
  1704.   if ((pid_torre = fork()) == 0) {
  1705.     criar_processo_torre();
  1706.   }
  1707.   else if (pid_torre == -1) {
  1708.     perror("Erro a criar o processo torre de controlo");
  1709.   }
  1710.   else{
  1711.  
  1712.     if(pthread_create(&thread_manage_id,NULL,thread_manage,NULL)!=0){
  1713.       perror("ERROR creating the thread pipe!\n");
  1714.     }
  1715.     abre_pipe();
  1716.   }
  1717.   fclose(flog);
  1718.   return 0;
  1719. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top