Guest User

Untitled

a guest
Dec 8th, 2019
77
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