SHARE
TWEET

Untitled

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