Advertisement
Guest User

Untitled

a guest
Dec 8th, 2019
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 37.44 KB | None | 0 0
  1. #define _POSIX_C_SOURCE 1
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <pthread.h>
  6. #include <unistd.h>
  7. #include <semaphore.h>
  8. #include <sys/ipc.h>
  9. #include <sys/shm.h>
  10. #include <sys/fcntl.h>
  11. #include <sys/types.h>
  12. #include <sys/wait.h>
  13. #include <string.h>
  14. #include <sys/socket.h>
  15. #include <netinet/in.h>
  16. #include <arpa/inet.h>
  17. #include <ctype.h>
  18. #include <sys/stat.h>
  19. #include <signal.h>
  20. #include <fcntl.h>
  21. #include <errno.h>
  22. #include <sys/mman.h>
  23. #include <linux/mman.h>
  24. #include <pthread.h>
  25. #include <sys/ipc.h>
  26. #include <sys/msg.h>
  27. #include <signal.h>
  28. #include <sys/time.h>
  29. #include <sys/msg.h>
  30.  
  31. #include "headers/logger.h"
  32. #include "headers/config_utils.h"
  33. #include "headers/cmd_console.h"
  34. #include "headers/utils.h"
  35. #include "headers/main.h"
  36.  
  37. // Named Pipe
  38. #define PIPE_NAME "resourses/named_pipe"
  39. #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
  40.  
  41. #define ARRIVAL "ARRIVAL"
  42. #define DEPARTURE "DEPARTURE"
  43. #define DEBUG
  44. #define MAX_THREADS 2
  45. #define TYPE_VOO_P_TO_TORRE 1
  46. #define TYPE_VOO_C_TO_TORRE 2
  47. #define TYPE_TORRE_TO_V_P 3
  48. #define TYPE_TORRE_TO_V_C 4
  49.  
  50. //Array para as threads e suas variaveis
  51. pthread_t *threads_voo_partida, *threads_voo_chegada, thread_pipe, thread_tratar_voos_c, thread_tratar_voos_p, *threads_deslocacao;
  52.  
  53. //variaveis de inicializacao da memoria partilhada
  54. int shmid_estatistica, shmid_slots, shm_controlo_chegada, shm_controlo_partida, shm_size_mq, shm_voo_chegada, shm_voo_partida, shm_algoritmo;
  55. Voo_partida *voo_partida;
  56. Voo_chegada *voo_chegada;
  57. Slots *slots;
  58. Estatistica *estatisticas;
  59. Algoritmo *algoritmo;
  60. int *controlo_chegadas, *controlo_partidas;
  61. Mq_size *mq_size;
  62.  
  63. sigset_t block_clean;
  64. sigset_t block_stats;
  65.  
  66. pid_t my_pid;
  67.  
  68. int id_thread_pipe, id_thread_espera, id_tratar_voo_chegada, id_tratar_voo_partida;
  69.  
  70. //variaveis dos semaforos e mutexes
  71. pthread_mutex_t mutex_partidas = PTHREAD_MUTEX_INITIALIZER;
  72. pthread_mutex_t mutex_chegadas = PTHREAD_MUTEX_INITIALIZER;
  73. pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  74. pthread_mutex_t mutex_torre = PTHREAD_MUTEX_INITIALIZER;
  75. pthread_cond_t condicao_chegada, condicao_partida, condicao_t_c, condicao_t_p, condicao_criar;
  76. sem_t sem_partida, sem_chegada, sem_mq, sem_log, sem_controlos;
  77.  
  78. // VARIAVEIS DE ESTRUTURAS
  79. config *cfg;
  80. key_t key;
  81. cmd *received_cmd;
  82.  
  83. //message queue
  84. int msgid;
  85.  
  86. //contadores dos arrays
  87. int pos_partida, pos_chegada, contador_chegada, contador_partida, contador_chegadas, contador_partidas, n_holding, n_holding_u;
  88.  
  89. //pipe
  90. int fd;
  91.  
  92. //Variaveis de tempo
  93. struct timeval tp_incial;
  94. struct timespec ts_inicial;
  95. struct timeval tp_atual;
  96. struct timespec ts_atual;
  97. struct timeval tp_aux;
  98. struct timespec ts_aux;
  99.  
  100. //Controlos
  101. int controlo, controlo_p, controlo_c;
  102.  
  103. //filas de voos para a torre de controlo;
  104. Voo_chegada *fila_chegada;
  105. Voo_partida *fila_partida;
  106.  
  107. void desocupa_slot(Slot slot){
  108. if(slot.id==slots->slot1.id)
  109. slots->slot1.livre=1;
  110. else if(slot.id==slots->slot2.id)
  111. slots->slot2.livre=1;
  112. else if(slot.id==slots->slot3.id)
  113. slots->slot3.livre=1;
  114. else if(slot.id==slots->slot4.id)
  115. slots->slot4.livre=1;
  116. }
  117.  
  118. void *voos_chegada(){
  119. Msg_to_queue msg_e, msg_r;
  120. int holding=0;
  121. int pos=pos_chegada-1;
  122. time_t now, after;
  123. struct timeval tp_antes, tp_depois;
  124. struct timespec ts_antes, ts_depois;
  125. //Para escrever no ficheiro log
  126. char *message_log;
  127.  
  128. sem_wait(&sem_log);
  129. int size=snprintf(NULL, 0, "\nthread chegada [%s] criada com sucesso", voo_chegada[pos].id);
  130. message_log=malloc(size+1);
  131. sprintf(message_log, "thread chegada [%s] criada com sucesso", voo_chegada[pos].id);
  132. logger(message_log);
  133. sem_post(&sem_log);
  134.  
  135. free(message_log);
  136.  
  137. sem_wait(&estatisticas->sem_estatisticas);
  138. estatisticas->n_voos_criados++;
  139. sem_post(&estatisticas->sem_estatisticas);
  140.  
  141. printf("VOO_C: chegada ID %s\n", voo_chegada[pos].id);
  142.  
  143. //pthread_mutex_lock(&mutex);
  144.  
  145. msg_e.info.voo_c=voo_chegada[pos];
  146. msg_e.type=TYPE_VOO_C_TO_TORRE;
  147. if((msgsnd(msgid, &msg_e, sizeof(Msg_to_queue)-sizeof(long), 0))==-1){
  148. perror("msgsnd!");
  149. exit(1);
  150. }
  151. else{
  152. printf("VOO_C: %s enviou mensagem a torre de controlo da sua chegada\n", voo_chegada[pos].id);
  153. gettimeofday(&tp_antes, NULL);
  154. ts_antes.tv_sec=tp_antes.tv_sec;
  155. sem_wait(&mq_size->sem_mq);
  156. mq_size->tamanho++;
  157. sem_post(&mq_size->sem_mq);
  158.  
  159. //espera ate receber sinal da torre de controlo. Apos receber o sinal executa o resto da funcao
  160. pthread_mutex_lock(&mutex_chegadas);
  161. pthread_cond_wait(&condicao_chegada, &mutex_chegadas);
  162. pthread_mutex_unlock(&mutex_chegadas);
  163.  
  164. if((msgrcv(msgid, &msg_r, sizeof(Msg_to_queue), TYPE_TORRE_TO_V_C, 0)==-1)){
  165. perror("msgrcv");
  166. exit(1);
  167. }
  168. else{
  169. sem_wait(&sem_chegada);
  170. gettimeofday(&tp_depois, NULL);
  171. ts_depois.tv_sec=tp_depois.tv_sec;
  172. printf("VOO_C: %s Recebeu mensagem da torre de controlo. Vai aterrar no slot %d.\n", msg_r.info.slot.voo_c.id, msg_r.info.slot.id);
  173. //gettimeofday(&tp_incial, NULL);
  174. pthread_mutex_lock(&mutex_chegadas);
  175. pthread_cond_wait(&condicao_chegada, &mutex_chegadas);
  176. //recebeu o sinal e o slot informa o voo que e preciso fazer um devio para outro aeroporto
  177. printf("Recebeu o sinal\n");
  178. if(msg_r.info.slot.desvio==1){
  179. printf("Vai ser desviado para outro aeroporto\n");
  180. pthread_mutex_unlock(&mutex_chegadas);
  181. sem_post(&sem_chegada);
  182. pthread_exit(NULL);
  183. }
  184. //Caso o slot nao indique que e preciso fazer desvio
  185. gettimeofday(&tp_depois, NULL);
  186. ts_depois.tv_sec=tp_depois.tv_sec;
  187. sem_wait(&estatisticas->sem_estatisticas);
  188. estatisticas->tempo_medio_espera_aterrar=(estatisticas->tempo_medio_espera_aterrar*pos+(int)ts_depois.tv_sec-ts_antes.tv_sec*(cfg->time/1000))/estatisticas->n_voos_aterrados;
  189. estatisticas->n_voos_aterrados++;
  190. sem_post(&estatisticas->sem_estatisticas);
  191.  
  192. printf("VOO: voo %s vai aterrar no slot %d...\n", msg_r.info.slot.voo_p.id, msg_r.info.slot.id);
  193. sleep(cfg->landing_duration);
  194. printf("VOO: voo %s aterrou!\n", msg_r.info.slot.voo_p.id);
  195. sem_wait(&estatisticas->sem_estatisticas);
  196. estatisticas->n_voos_aterrados++;
  197. sem_post(&estatisticas->sem_estatisticas);
  198. sem_wait(&algoritmo->sem_controlo_algoritmo);
  199. algoritmo->n_chegadas--;
  200. if(algoritmo->n_chegadas==0)
  201. algoritmo->controlo_algoritmo=0;
  202. sem_post(&algoritmo->sem_controlo_algoritmo);
  203. sleep(cfg->landing_interval);
  204. pthread_mutex_unlock(&mutex_chegadas);
  205. sem_post(&sem_chegada);
  206. pthread_exit(NULL);
  207. }
  208. }
  209. }
  210.  
  211. /*void *controla_holding(){
  212. while(1){
  213.  
  214. }
  215. }*/
  216.  
  217. void *voos_partida(){
  218.  
  219. struct timeval tp_depois, tp_aux;
  220. struct timespec ts_depois, ts_aux;
  221. time_t now, after;
  222. Msg_to_queue msg_e, msg_r;
  223. int pos=pos_partida-1;
  224. char *message_log;
  225. //Vai escrever no log
  226. sem_wait(&sem_log);
  227. int size=snprintf(NULL, 0, "thread partida [%s] criada com sucesso", voo_partida[pos_partida-1].id);
  228. message_log=malloc(size+1);
  229. sprintf(message_log, "thread partida [%s] criada com sucesso", voo_partida[pos_partida-1].id);
  230. logger(message_log);
  231. sem_post(&sem_log);
  232. free(message_log);
  233.  
  234. //Vai adicionar as estatisticas o numero de voos criados
  235. sem_wait(&estatisticas->sem_estatisticas);
  236. estatisticas->n_voos_criados++;
  237. sem_post(&estatisticas->sem_estatisticas);
  238.  
  239. //vai enviar msg a torre de controlo
  240. msg_e.info.voo_p=voo_partida[pos];
  241. msg_e.type=TYPE_VOO_P_TO_TORRE;
  242.  
  243.  
  244. printf("VOO_P: chegada ID %s\n", voo_partida[pos].id);
  245.  
  246. if((msgsnd(msgid, &msg_e, sizeof(Msg_to_queue)-sizeof(long), 0))==-1){
  247. perror("msgsnd!");
  248. exit(1);
  249. }
  250. else{
  251. printf("VOO_P: %s enviou mensagem a torre de controlo da sua ida\n", voo_partida[pos].id);
  252. time(&now);
  253. sem_wait(&mq_size->sem_mq);
  254. mq_size->tamanho++;
  255. sem_post(&mq_size->sem_mq);
  256. //recebe voo partida da fila de espera
  257. if((msgrcv(msgid, &msg_r, sizeof(Msg_to_queue)-sizeof(long), TYPE_TORRE_TO_V_P, 0)==-1)){
  258. perror("msgrcv");
  259. exit(1);
  260. }
  261. else{
  262. sem_wait(&sem_partida);
  263. printf("VOO: Recebeu mensagem da torre, vai tratar do voo %s\n", msg_r.info.slot.voo_p.id);
  264. gettimeofday(&tp_depois, NULL);
  265. ts_depois.tv_sec=tp_depois.tv_sec;
  266. printf("voo %s vai partir as %d\n", msg_r.info.slot.voo_p.id, msg_r.info.slot.voo_p.takeoff);
  267. if(*controlo_partidas==1){
  268. //printf("ENTROU: %d\n", voo_partida[pos_partida].takeoff);
  269. ts_depois.tv_sec+=msg_r.info.slot.voo_p.takeoff;
  270. }
  271. else
  272. ts_depois.tv_sec+=10;
  273. pthread_mutex_lock(&mutex_partidas);
  274. pthread_cond_timedwait(&condicao_t_c, &mutex, &ts_depois);
  275. if (*controlo_partidas == 1) {
  276. //verifica o tempo de descolar é o correto
  277. do {
  278. gettimeofday(&tp_aux, NULL);
  279. ts_aux.tv_sec=tp_aux.tv_sec;
  280. } while(ts_aux.tv_sec-ts_inicial.tv_sec<=msg_r.info.slot.voo_p.takeoff);
  281. time(&after);
  282. printf("VOO: voo %s vai descolar do slot %d...\n", msg_r.info.slot.voo_p.id, msg_r.info.slot.id);
  283. sem_wait(&estatisticas->sem_estatisticas);
  284. estatisticas->tempo_medio_espera_descolar=(estatisticas->tempo_medio_espera_descolar*pos+(int)difftime(after, now)*(cfg->time/1000))/(pos+1);
  285. sem_post(&estatisticas->sem_estatisticas);
  286. sleep(cfg->depart_duration);
  287. printf("VOO: voo %s vai descolou!\n", msg_r.info.slot.voo_p.id);
  288. sleep(cfg->depart_interval);
  289. sem_wait(&estatisticas->sem_estatisticas);
  290. estatisticas->n_voos_descolaram++;
  291. sem_post(&estatisticas->sem_estatisticas);
  292. desocupa_slot(msg_r.info.slot);
  293. pthread_mutex_unlock(&mutex_partidas);
  294. sem_post(&sem_partida);
  295. sem_wait(&algoritmo->sem_controlo_algoritmo);
  296. algoritmo->n_partidas--;
  297. if(algoritmo->n_partidas==0)
  298. algoritmo->controlo_algoritmo=0;
  299. sem_post(&algoritmo->sem_controlo_algoritmo);
  300. pthread_exit(NULL);
  301. }
  302. }
  303. pthread_mutex_unlock(&mutex_partidas);
  304. }
  305. }
  306.  
  307. void ordenar_torre_chegadas(Voo_chegada voo_chegada[], int i){
  308. Voo_chegada aux_c;
  309. while(voo_chegada[i].eta<voo_chegada[i-1].eta && i<0){
  310. aux_c=voo_chegada[i];
  311. voo_chegada[i]=voo_chegada[i-1];
  312. voo_chegada[i-1]=aux_c;
  313. i--;
  314. }
  315. }
  316.  
  317. void ordenar_torre_partidas(Voo_partida voo_partida[], int i){
  318. Voo_partida aux_p;
  319. while(voo_partida[i].takeoff<voo_partida[i-1].takeoff && i<0){
  320. aux_p=voo_partida[i];
  321. voo_partida[i]=voo_partida[i-1];
  322. voo_partida[i-1]=aux_p;
  323. i--;
  324. }
  325. }
  326.  
  327. Slot choose_slot(char *tipo){
  328. int r;
  329. if(strcmp(tipo, "aterragem")==0){
  330. if(slots->slot1.livre==1){
  331. slots->slot1.livre=0;
  332. return slots->slot1;
  333. }
  334. if(slots->slot2.livre==1){
  335. slots->slot2.livre=0;
  336. return slots->slot2;
  337. }
  338. else{
  339. r=rand()%1+1;
  340. if(r==1){
  341. slots->slot1.holding=1;
  342. return slots->slot1;
  343. }
  344. else{
  345. slots->slot2.holding=1;
  346. return slots->slot2;
  347. }
  348. }
  349. }
  350. else{
  351. if(slots->slot3.livre==1){
  352. slots->slot3.livre=0;
  353. return slots->slot3;
  354. }
  355. if(slots->slot4.livre==1){
  356. slots->slot4.livre=0;
  357. return slots->slot4;
  358. }
  359. else{
  360. r=rand()%1+1;
  361. if(r==1)
  362. return slots->slot3;
  363. else
  364. return slots->slot4;
  365. }
  366. }
  367. }
  368.  
  369. Slot find_slot(Voo_chegada v){
  370. if(strcmp(slots->slot1.voo_c.id, v.id))
  371. return slots->slot1;
  372. else
  373. return slots->slot2;
  374. }
  375.  
  376. void *deslocacao(){
  377. int check_holding=0;
  378. Slot slot;
  379. slot=find_slot(fila_chegada[pos_chegada]);
  380. pthread_mutex_lock(&mutex_torre);
  381. pthread_cond_signal(&condicao_criar);
  382. pthread_mutex_lock(&mutex_chegadas);
  383. printf("Vai deslocar para a zona de aterragem\n");
  384. do{
  385. slot.voo_c.eta-=1*(cfg->time/1000);
  386. slot.voo_c.combustivel-=1*(cfg->time/1000);
  387. }while(slot.voo_c.eta<0);
  388. printf("Chegou a zona de aterragem\n");
  389. while(contador_chegadas-estatisticas->n_voos_aterrados>5){
  390. slot.voo_c.combustivel-=1*(cfg->time/1000);
  391. if(check_holding==0)
  392. check_holding=1;
  393. if(slot.voo_c.combustivel<=0){
  394. slot.desvio=1;
  395. pthread_cond_signal(&condicao_chegada);
  396. pthread_mutex_unlock(&mutex_chegadas);
  397. pthread_mutex_unlock(&mutex_torre);
  398. pthread_exit(NULL);
  399. }
  400. }
  401. if(check_holding==1){
  402. if(slot.voo_c.prioridade==1){
  403. n_holding_u++;
  404. sem_wait(&estatisticas->sem_estatisticas);
  405. estatisticas->n_medio_holding_urgencia=n_holding_u/estatisticas->n_voos_aterrados;
  406. sem_post(&estatisticas->sem_estatisticas);
  407. }
  408. else{
  409. n_holding++;
  410. sem_wait(&estatisticas->sem_estatisticas);
  411. estatisticas->n_medio_holding_aterragem=n_holding/estatisticas->n_voos_aterrados;
  412. sem_post(&estatisticas->sem_estatisticas);
  413. }
  414. }
  415. printf("Mandou sinal para thread chegada\n");
  416. pthread_cond_signal(&condicao_chegada);
  417. pthread_mutex_unlock(&mutex_chegadas);
  418. pthread_mutex_unlock(&mutex_torre);
  419. pthread_exit(NULL);
  420. }
  421.  
  422. void comunica_voo(long tipo_enviar, long tipo_receber, int pos){
  423. Msg_to_queue msg_e;
  424. //Slot slot;
  425. if(tipo_receber==TYPE_VOO_C_TO_TORRE){
  426. msg_e.info.slot=choose_slot("aterragem");
  427. msg_e.info.slot.voo_c=fila_chegada[pos];
  428. }
  429. else{
  430. msg_e.info.slot=choose_slot("descolagem");
  431. msg_e.info.slot.voo_p=fila_partida[pos];
  432.  
  433. }
  434. msg_e.type=tipo_enviar;
  435. if((msgsnd(msgid, &msg_e, sizeof(Msg_to_queue)-sizeof(long), 0))==-1){
  436. perror("msgsnd!");
  437. exit(1);
  438. }
  439. else{
  440. printf("TORRE: Mensagem enviada para voo chegada %s com sucesso, tipo enviar: %ld\n", msg_e.info.slot.voo_c.id, tipo_enviar);
  441. if(tipo_receber==TYPE_VOO_C_TO_TORRE){
  442. /*pthread_mutex_lock(&mutex_torre);
  443. pthread_cond_signal(&condicao_criar);
  444. pthread_mutex_unlock(&mutex_torre);*/
  445.  
  446. }
  447. else{
  448. printf("TORRE: Mensagem enviada para voo partida %s com sucesso, tipo enviar: %ld\n", msg_e.info.slot.voo_p.id, tipo_enviar);
  449. pthread_mutex_lock(&mutex_partidas);
  450. pthread_cond_signal(&condicao_partida);
  451. pthread_mutex_unlock(&mutex_partidas);
  452. }
  453. sem_wait(&sem_mq);
  454. mq_size->tamanho--;
  455. sem_post(&sem_mq);
  456. }
  457. }
  458.  
  459.  
  460. void *tratar_voos_p(){
  461. int contador=1;
  462. while (1) {
  463. if(*controlo_partidas==1){
  464. if(contador==contador_partidas){
  465. sem_wait(&algoritmo->sem_controlo_algoritmo);
  466. algoritmo->n_partidas++;
  467. printf("%d\n", algoritmo->n_partidas);
  468. sem_post(&algoritmo->sem_controlo_algoritmo);
  469. contador++;
  470. comunica_voo(TYPE_TORRE_TO_V_P, TYPE_VOO_P_TO_TORRE, contador_partidas-1);
  471. }
  472. }
  473. }
  474.  
  475. }
  476.  
  477. void *tratar_voos_c(){
  478. int contador=1;
  479. while(1){
  480. if(*controlo_chegadas==1){
  481. //so podem ocorrer dois voos de cada vez. SERA NA THREAD DO VOO??
  482. if(contador==contador_chegadas){
  483. sem_wait(&algoritmo->sem_controlo_algoritmo);
  484. algoritmo->n_chegadas++;
  485. printf("Incremenou: %d\n", algoritmo->n_chegadas);
  486. sem_post(&algoritmo->sem_controlo_algoritmo);
  487. contador++;
  488. comunica_voo(TYPE_TORRE_TO_V_C, TYPE_VOO_C_TO_TORRE, contador_chegadas-1);
  489. }
  490. }
  491. }
  492. }
  493.  
  494. void funcao_algoritmo(){
  495. if(fila_chegada[pos_chegada].eta<=fila_partida[pos_partida].takeoff && fila_chegada[pos_chegada].eta!=-1 && fila_partida[pos_partida].takeoff!=-1){
  496. printf("ENtour1\n");
  497. sem_wait(&algoritmo->sem_controlo_algoritmo);
  498. algoritmo->controlo_algoritmo=1;
  499. sem_post(&algoritmo->sem_controlo_algoritmo);
  500. sem_wait(&sem_controlos);
  501. *controlo_chegadas=1;
  502. *controlo_partidas=0;
  503. sem_post(&sem_controlos);
  504. }
  505. else if(fila_chegada[pos_chegada].eta>fila_partida[pos_partida].takeoff && fila_chegada[pos_chegada].eta!=-1 && fila_partida[pos_partida].takeoff!=-1){
  506. printf("ENtour2\n");
  507. sem_wait(&algoritmo->sem_controlo_algoritmo);
  508. algoritmo->controlo_algoritmo=1;
  509. sem_post(&algoritmo->sem_controlo_algoritmo);
  510. sem_wait(&sem_controlos);
  511. *controlo_chegadas=0;
  512. *controlo_partidas=1;
  513. sem_post(&sem_controlos);
  514.  
  515. }
  516. else if(fila_chegada[pos_chegada].eta!=-1){
  517. printf("ENtour3\n");
  518. sem_wait(&algoritmo->sem_controlo_algoritmo);
  519. algoritmo->controlo_algoritmo=1;
  520. sem_post(&algoritmo->sem_controlo_algoritmo);
  521. sem_wait(&sem_controlos);
  522. *controlo_chegadas=1;
  523. *controlo_partidas=0;
  524. sem_post(&sem_controlos);
  525. }
  526. else if(fila_partida[pos_partida].takeoff!=-1){
  527. printf("Entrou4\n");
  528. sem_wait(&algoritmo->sem_controlo_algoritmo);
  529. algoritmo->controlo_algoritmo=1;
  530. sem_post(&algoritmo->sem_controlo_algoritmo);
  531. sem_wait(&sem_controlos);
  532. *controlo_chegadas=0;
  533. *controlo_partidas=1;
  534. sem_post(&sem_controlos);
  535. }
  536.  
  537. }
  538.  
  539. void torre_controlo(){
  540. printf("------- BEM VINDO TORRE DE CONTROLO ------\n");
  541. //int aux_c=0, aux_p=0;
  542. Msg_to_queue msg_r;
  543. fila_chegada=malloc(sizeof(Voo_chegada)*cfg->min_depart);
  544. fila_partida=malloc(sizeof(Voo_partida)*cfg->max_depart);
  545.  
  546. threads_deslocacao=malloc(cfg->min_depart*sizeof(pthread_t*));
  547.  
  548. for (int i = 0; i < cfg->max_depart; ++i)
  549. {
  550. fila_partida[i].takeoff=-1;
  551. }
  552. for (int i = 0; i < cfg->min_depart; ++i)
  553. {
  554. fila_chegada[i].eta=-1;
  555. }
  556.  
  557. if(pthread_create(&thread_tratar_voos_c, NULL, tratar_voos_c, &id_tratar_voo_chegada)!=0){
  558. perror("Erro criacao das threads\n");
  559. }
  560.  
  561. if(pthread_create(&thread_tratar_voos_p, NULL, tratar_voos_p, &id_tratar_voo_partida)!=0){
  562. perror("Erro criacao das threads\n");
  563. }
  564.  
  565. while(1){
  566. if(algoritmo->controlo_algoritmo==0){
  567. funcao_algoritmo();
  568. }
  569. if(mq_size->tamanho!=0){
  570. if((msgrcv(msgid, &msg_r, sizeof(Msg_to_queue), TYPE_VOO_C_TO_TORRE, 0)==-1)){
  571. perror("msgrcv");
  572. exit(1);
  573. }
  574. else{
  575. printf("TORRE: Recebeu mensagem da chegada do voo %s\n", msg_r.info.voo_c.id);
  576. if(contador_chegadas>cfg->min_depart-1){
  577. printf("Vai rejeitar o voo %s\n", msg_r.info.voo_c.id);
  578. sem_wait(&estatisticas->sem_estatisticas);
  579. estatisticas->n_voos_rejeitados++;
  580. sem_post(&estatisticas->sem_estatisticas);
  581. }
  582. else{
  583. printf("Vai inserir voo %s na fila de chegadas %d\n", msg_r.info.voo_c.id, msg_r.info.voo_c.eta);
  584. fila_chegada[contador_chegadas]=msg_r.info.voo_c;
  585. printf("voo %s inserido na lista de espera.\n", fila_chegada[contador_chegadas].id);
  586. contador_chegadas++;
  587. //printf("Incrementou: %d\n", contador_chegadas);
  588. if(contador_chegadas>1)
  589. ordenar_torre_chegadas(fila_chegada, contador_chegadas);
  590. }
  591. }
  592. if((msgrcv(msgid, &msg_r, sizeof(Msg_to_queue), TYPE_VOO_P_TO_TORRE, 0)==-1)){
  593. perror("msgrcv");
  594. exit(1);
  595. }
  596. else{
  597. printf("TORRE: Recebeu mensagem da partida do voo %s\n", msg_r.info.voo_p.id);
  598. if(contador_partidas>cfg->max_depart-1){
  599. printf("Vai rejeitar o voo %s\n", msg_r.info.voo_p.id);
  600. sem_wait(&estatisticas->sem_estatisticas);
  601. estatisticas->n_voos_rejeitados++;
  602. sem_post(&estatisticas->sem_estatisticas);
  603. }
  604. else{
  605. printf("Vai inserir voo na fila de partidas\n");
  606. fila_partida[contador_partidas]=msg_r.info.voo_p;
  607. contador_partidas++;
  608. if(contador_partidas>1)
  609. ordenar_torre_partidas(fila_partida, contador_partidas);
  610. }
  611. }
  612. }
  613. }
  614. }
  615.  
  616. void ordenar_gestor_chegadas(Voo_chegada voo_chegada[], int i){
  617. Voo_chegada aux_c;
  618. while(voo_chegada[i].init<voo_chegada[i-1].init){
  619. printf("I: %d %d \n", voo_chegada[i].init, voo_chegada[i-1].init);
  620. aux_c=voo_chegada[i];
  621. voo_chegada[i]=voo_chegada[i-1];
  622. voo_chegada[i-1]=aux_c;
  623. printf("depois: %d %d\n", voo_chegada[i].init,voo_chegada[i-1].init);
  624. i--;
  625. }
  626. }
  627.  
  628. void ordenar_gestor_partidas(Voo_partida voo_partida[], int i){
  629. Voo_partida aux_p;
  630. while(voo_partida[i].init<voo_partida[i-1].init){
  631. //printf("I: %d %d\n",voo_partida[i].init, voo_partida[i-1].init);
  632. aux_p=voo_partida[i];
  633. voo_partida[i]=voo_partida[i-1];
  634. voo_partida[i-1]=aux_p;
  635. printf("depois: %d %d\n", voo_partida[i].init, voo_partida[i-1].init);
  636. i--;
  637. }
  638. }
  639.  
  640. /*void print_array(Voo_chegada v[]){
  641. for(int i=0; i<3; i++){
  642. printf("%s\n", v[i].id);
  643. }
  644. }*/
  645.  
  646. void *ler_do_pipe(){
  647. //ABRE O PIPE
  648. if ((mkfifo(PIPE_NAME, O_CREAT | O_EXCL | 0600) < 0) && (errno != EEXIST))
  649. {
  650. perror("Cannot create pipe: ");
  651. logger("Cannot create named pipe.");
  652. exit(0);
  653. }
  654. // Opens the pipe for reading
  655. if ((fd = open(PIPE_NAME, O_RDWR)) < 0)
  656. {
  657. perror("Cannot open pipe for reading:");
  658. logger("Cannot open pipe for reading");
  659. exit(0);
  660. }
  661.  
  662. contador_chegada=0;
  663. contador_partida=0;
  664. while (1){
  665. read(fd, received_cmd, sizeof(cmd));
  666. #ifdef DEBUG
  667. printf("\n[SERVER] Received (%s, %s, %d, %d, %d, %d) from Command Terminal\n", received_cmd->command, received_cmd->plane, received_cmd->init, received_cmd->takeoff, received_cmd->eta, received_cmd->fuel);
  668. #endif
  669.  
  670. if(received_cmd->command!=NULL){
  671. //printf("%d\n", pos);
  672. if(strcmp(received_cmd->command, "ARRIVAL")==0){
  673. //printf("%s | %d | %d | %d \n", received_cmd->plane, received_cmd->init, received_cmd->eta, received_cmd->fuel);
  674.  
  675. //printf("Pos inicio: %d\n", contador_chegada);
  676. strcpy(voo_chegada[contador_chegada].id, received_cmd->plane);
  677. voo_chegada[contador_chegada].init=received_cmd->init;
  678. //printf("VOO CHEGADA: %d %d\n", voo_chegada[contador_chegada].init, contador_chegada);
  679. voo_chegada[contador_chegada].eta=received_cmd->eta;
  680. voo_chegada[contador_chegada].combustivel=received_cmd->fuel;
  681. voo_chegada[contador_chegada].prioridade=0;
  682. //printf("Adicionou novo voo ao array\n");
  683. //printf("antes: %d %d\n", voo_chegada[contador_chegada].init, contador_chegada);
  684. if(contador_chegada>0){
  685. ordenar_gestor_chegadas(voo_chegada, contador_chegada);
  686. }
  687. //printf("INIT: %d %d %d %d\n", voo_chegada[contador_chegada].init, voo_chegada[pos_chegada].init, contador_chegada, pos_chegada);
  688. contador_chegada++;
  689. pthread_mutex_lock(&mutex);
  690. //printf("Vai enviar sinal...\n");
  691. controlo=1;
  692. //printf("ENVIEI CONTROLO %d\n", controlo);
  693. pthread_cond_signal(&condicao_t_c);
  694. pthread_mutex_unlock(&mutex);
  695. //printf("Enviou sinal chegada..\n");
  696. }
  697.  
  698. else if(strcmp(received_cmd->command, "DEPARTURE")==0){
  699. //printf("Pos inicio: %d\n", contador_partida);
  700. strcpy(voo_partida[contador_partida].id, received_cmd->plane);
  701. voo_partida[contador_partida].init=received_cmd->init;
  702. //printf("VOO PARTIDA: %d %d\n", voo_partida[contador_partidas].init, contador_partida);
  703. voo_partida[contador_partida].takeoff=received_cmd->takeoff;
  704. voo_partida[contador_partida].prioridade=0;
  705. //printf("Adicionou novo voo ao array\n");
  706. //printf("antes: %d %d\n", voo_partida[contador_partida].init, contador_partida);
  707. if(contador_partida>0){
  708. ordenar_gestor_partidas(voo_partida, contador_partida);
  709. }
  710. //printf("INIT: %d %d %d %d\n", voo_partida[contador_partida].init, voo_partida[pos_partida].init, contador_partida, pos_partida);
  711. contador_partida++;
  712. pthread_mutex_lock(&mutex);
  713. //printf("Vai enviar sinal...\n");
  714. controlo=2;
  715. //printf("ENVIEI CONTROLO %d\n", controlo);
  716. pthread_cond_signal(&condicao_t_c);
  717. pthread_mutex_unlock(&mutex);
  718. //printf("Enviou sinal..\n");
  719. }
  720. }
  721.  
  722. }
  723.  
  724. }
  725.  
  726. void stats_print(int sig) {
  727. (void) sig;
  728.  
  729. printf("\n----- Analise de Voos -----\n");
  730. printf("Numero de Voos criados: %d\n", estatisticas->n_voos_criados);
  731. printf("Numero de Voos aterrados: %d\n", estatisticas->n_voos_aterrados);
  732. printf("Numero de Voos que descolaram: %d\n", estatisticas->n_voos_descolaram);
  733. printf("Numero de Voos rejeitados: %d\n", estatisticas->n_voos_rejeitados);
  734. printf("Numero de Voos redirecionados: %d\n", estatisticas->n_voos_redirecionados);
  735. printf("----- Analise Temporal -----\n");
  736. printf("Tempo medio de espera (atterragem): %.2f\n", estatisticas->tempo_medio_espera_aterrar);
  737. printf("Tempo medio de espera (descolagem): %.2f\n", estatisticas->tempo_medio_espera_descolar);
  738. printf("----- Holding -----\n");
  739. printf("Numero medio de holding (urgencia): %.2f\n", estatisticas->n_medio_holding_urgencia);
  740. printf("Numero medio de holding (aterragem): %.2f\n\n", estatisticas->n_medio_holding_aterragem);
  741. }
  742.  
  743.  
  744.  
  745. void gestor_simulacao(){
  746. pos_partida=0;
  747. pos_chegada=0;
  748. contador_chegadas=0;
  749. contador_partidas=0;
  750. gettimeofday(&tp_incial, NULL);
  751. ts_inicial.tv_sec=tp_incial.tv_sec;
  752. controlo=0;
  753. n_holding=0;
  754. n_holding_u=0;
  755.  
  756. //criacao da Message Queue
  757. if((msgid=msgget(IPC_PRIVATE, IPC_CREAT|0666))==-1){
  758. perror("Erro na criacao da message queue");
  759. exit(1);
  760. }
  761. else
  762. printf("MESSAGE QUEUE CRIADA COM SUCESSO\n");
  763.  
  764. //alocar memoria para os comandos
  765. received_cmd = malloc(sizeof(cmd *));
  766.  
  767. //alocar espaco para as informacoes das threads
  768. voo_partida=malloc(cfg->max_depart*sizeof(Voo_partida));
  769. voo_chegada=malloc(cfg->min_depart*sizeof(Voo_chegada));
  770.  
  771. for (int i = 0; i < cfg->max_depart; ++i)
  772. {
  773. voo_partida[i].init=-1;
  774. }
  775. for (int i = 0; i < cfg->min_depart; ++i)
  776. {
  777. voo_chegada[i].init=-1;
  778. }
  779. //alocar espaco para as threads
  780. threads_voo_partida=malloc(cfg->max_depart*sizeof(pthread_t*));
  781. threads_voo_chegada=malloc(cfg->min_depart*sizeof(pthread_t*));
  782.  
  783. //Memoria partilhada para algoritmo
  784. shm_algoritmo = shmget(IPC_PRIVATE, sizeof(Algoritmo), IPC_CREAT | 0777);
  785.  
  786. if (shm_algoritmo < 0) {
  787. logger("Error shared memory creation");
  788. clean();
  789. }
  790.  
  791. algoritmo=(Algoritmo*)shmat(shm_algoritmo, NULL, 0);
  792. if(algoritmo==(Algoritmo*)-1)
  793. logger("Error in mapping variable.");
  794.  
  795. algoritmo->n_chegadas=0;
  796. algoritmo->n_partidas=0;
  797. algoritmo->controlo_algoritmo=0;
  798. sem_init(&algoritmo->sem_controlo_algoritmo, 0, 1);
  799.  
  800. //Memoria partilhada para estatisticas
  801. shmid_estatistica = shmget(IPC_PRIVATE, sizeof(Estatistica), IPC_CREAT | 0777);
  802.  
  803. if (shmid_estatistica < 0) {
  804. logger("Error shared memory creation");
  805. clean();
  806. }
  807.  
  808. estatisticas=(Estatistica*)shmat(shmid_estatistica, NULL, 0);
  809. if(estatisticas==(Estatistica*)-1)
  810. logger("Error in mapping variable.");
  811.  
  812. estatisticas->n_voos_criados=0;
  813. estatisticas->n_voos_aterrados=0;
  814. estatisticas->tempo_medio_espera_aterrar=0;
  815. estatisticas->n_voos_descolaram=0;
  816. estatisticas->tempo_medio_espera_descolar=0;
  817. estatisticas->n_medio_holding_aterragem=0;
  818. estatisticas->n_medio_holding_urgencia=0;
  819. estatisticas->n_voos_redirecionados=0;
  820. estatisticas->n_voos_rejeitados=0;
  821. sem_init(&estatisticas->sem_estatisticas, 0, 1);
  822.  
  823. //Memoria partilhada para os slots
  824. shmid_slots = shmget(IPC_PRIVATE, sizeof(Estatistica), IPC_CREAT | 0777);
  825.  
  826. if (shmid_slots < 0) {
  827. logger("Error shared memory creation");
  828. clean();
  829. }
  830.  
  831. slots = (Slots*)shmat(shmid_slots, NULL, 0);
  832.  
  833. if (slots == (Slots*)-1)
  834. logger("Error in mapping variable.");
  835.  
  836. slots->slot1.id=1;
  837. slots->slot1.tipo=1; //aterragem
  838. slots->slot1.holding=0;
  839. slots->slot1.desvio=0;
  840. slots->slot1.livre=1;
  841. sem_init(&slots->slot1.sem_slot, 0, 1);
  842.  
  843. slots->slot2.id=2;
  844. slots->slot2.tipo=1; //aterragem
  845. slots->slot2.holding=0;
  846. slots->slot2.desvio=0;
  847. slots->slot2.livre=1;
  848. sem_init(&slots->slot2.sem_slot, 0, 1);
  849.  
  850. slots->slot3.id=3;
  851. slots->slot3.tipo=0; //descolagem
  852. slots->slot3.holding=0;
  853. slots->slot3.desvio=0;
  854. slots->slot3.livre=1;
  855. sem_init(&slots->slot3.sem_slot, 0, 1);
  856.  
  857. slots->slot4.id=4;
  858. slots->slot4.tipo=0; //descolagem
  859. slots->slot4.holding=0;
  860. slots->slot4.desvio=0;
  861. slots->slot4.livre=1;
  862. sem_init(&slots->slot4.sem_slot, 0, 1);
  863.  
  864. //Memoria partilhada para o tamanho da MQ e seu semaforo
  865. shm_size_mq = shmget(IPC_PRIVATE, sizeof(Mq_size*), IPC_CREAT | 0777);
  866.  
  867. if (shm_size_mq < 0) {
  868. logger("Error shared memory creation");
  869. clean();
  870. }
  871.  
  872. mq_size=(Mq_size*)shmat(shm_size_mq, NULL, 0);
  873. if(mq_size==(Mq_size*)-1)
  874. logger("Error in mapping variable.");
  875. mq_size->tamanho=0;
  876. sem_init(&mq_size->sem_mq, 0, 1);
  877.  
  878. //Memoria partilhada para controlar chegadas
  879. shm_controlo_chegada = shmget(IPC_PRIVATE, sizeof(int*), IPC_CREAT | 0777);
  880.  
  881. if (shm_size_mq < 0) {
  882. logger("Error shared memory creation");
  883. clean();
  884. }
  885.  
  886. controlo_chegadas = (int*)shmat(shm_controlo_chegada, NULL, 0);
  887.  
  888. if (controlo_chegadas == (int*)-1 )
  889. logger("Error in mapping variable.");
  890.  
  891.  
  892. //Memoria partilhada para controlar partidas
  893. shm_controlo_partida = shmget(IPC_PRIVATE, sizeof(int*), IPC_CREAT | 0777);
  894.  
  895. if (shm_size_mq < 0) {
  896. logger("Error shared memory creation");
  897. clean();
  898. }
  899.  
  900. controlo_partidas = (int*)shmat(shm_controlo_partida, NULL, 0);
  901.  
  902. if (controlo_partidas == (int*)-1) {
  903. logger("Error in mapping variable.");
  904.  
  905. }
  906.  
  907. *controlo_partidas=0;
  908. *controlo_chegadas=0;
  909.  
  910. //Variaveis de condicao
  911. pthread_cond_init(&condicao_partida, NULL);
  912. pthread_cond_init(&condicao_chegada, NULL);
  913. pthread_cond_init(&condicao_t_c, NULL);
  914. pthread_cond_init(&condicao_t_p, NULL);
  915.  
  916. sem_init(&sem_partida,0,MAX_THREADS);
  917. sem_init(&sem_partida,0,MAX_THREADS);
  918. if(sem_init(&sem_log, 0, 1)==-1){
  919. perror("Erro a criar semaforo log\n");
  920. exit(1);
  921. }
  922. if(sem_init(&sem_controlos, 0, 1)==-1){
  923. perror("Erro a criar semaforo slots\n");
  924. exit(1);
  925. }
  926. if(sem_init(&sem_mq, 0, 1)==-1){
  927. perror("Erro a criar semaforo slots\n");
  928. exit(1);
  929. }
  930.  
  931. //cria a thread do pipe
  932. if(pthread_create(&thread_pipe, NULL, ler_do_pipe, &id_thread_pipe)!=0){
  933. perror("Erro criacao das threads\n");
  934. }
  935.  
  936. my_pid = fork();
  937.  
  938. if(my_pid == 0){
  939. torre_controlo();
  940. exit(0);
  941. }
  942.  
  943. while(1){
  944. gettimeofday(&tp_atual, NULL);
  945. ts_atual.tv_sec=tp_atual.tv_sec;
  946. ts_atual.tv_nsec=tp_atual.tv_usec*1000;
  947. if(controlo==1){
  948. ts_atual.tv_sec+=voo_chegada[pos_chegada].init*((cfg->time)/1000);
  949. }
  950. else if(controlo==2)
  951. ts_atual.tv_sec+=voo_partida[pos_partida].init*((cfg->time)/1000);
  952. else{
  953. ts_atual.tv_sec+=10;
  954. }
  955. //printf("tempo: %ld\n", ts.tv_sec);
  956. pthread_mutex_lock(&mutex);
  957. pthread_cond_timedwait(&condicao_t_c, &mutex, &ts_atual);
  958. if(controlo==1){
  959. gettimeofday(&tp_aux, NULL);
  960. ts_aux.tv_sec=tp_aux.tv_sec;
  961. if(ts_aux.tv_sec-ts_inicial.tv_sec>=voo_chegada[pos_chegada].init){
  962. if(pthread_create(&threads_voo_chegada[pos_chegada], NULL, voos_chegada, &voo_chegada[pos_chegada])!=0){
  963. perror("Erro criacao das threads\n");
  964. }
  965. else{
  966. pos_chegada++;
  967. if(voo_partida[pos_partida].init<voo_chegada[pos_chegada].init && voo_chegada[pos_chegada].init!=-1 && voo_partida[pos_partida].init!=-1){
  968. controlo=2;
  969. }
  970. if(voo_partida[pos_partida].init>voo_chegada[pos_chegada].init && voo_chegada[pos_chegada].init!=-1 && voo_partida[pos_partida].init!=-1){
  971. controlo=1;
  972. }
  973. else if(voo_partida[pos_partida].init!=-1){
  974. controlo=2;
  975. }
  976. else if(pos_chegada==contador_chegada)
  977. controlo=0;
  978. }
  979.  
  980. }
  981. }
  982. else if(controlo==2){
  983. gettimeofday(&tp_aux, NULL);
  984. ts_aux.tv_sec=tp_aux.tv_sec;
  985. if(ts_aux.tv_sec-ts_inicial.tv_sec>=voo_partida[pos_partida].init){
  986. if(pthread_create(&threads_voo_partida[pos_partida], NULL, voos_partida, &voo_partida[pos_partida])!=0){
  987. perror("Erro criacao das threads\n");
  988. }
  989. else{
  990. pos_partida++;
  991. //printf("%d %d \n", voo_partida[pos_partida].init, voo_chegada[pos_chegada].init);
  992. if(voo_partida[pos_partida].init>voo_chegada[pos_chegada].init && voo_chegada[pos_chegada].init!=-1 && voo_partida[pos_partida].init!=-1)
  993. controlo=1;
  994. else if(voo_partida[pos_partida].init<voo_chegada[pos_chegada].init && voo_chegada[pos_chegada].init!=-1 && voo_partida[pos_partida].init!=-1)
  995. controlo=2;
  996. else if(voo_chegada[pos_chegada].init!=-1)
  997. controlo=1;
  998. else if(pos_partida==contador_partida)
  999. controlo=0;
  1000. }
  1001. }
  1002. }
  1003. pthread_mutex_unlock(&mutex);
  1004. }
  1005. }
  1006.  
  1007. void clean()
  1008. {
  1009. while (wait(NULL) != -1);
  1010.  
  1011. if (shmid_estatistica >= 0) {
  1012. shmctl(shmid_estatistica, IPC_RMID, NULL);
  1013. }
  1014. if (shmid_slots >= 0) {
  1015. shmctl(shmid_slots, IPC_RMID, NULL);
  1016. }
  1017. if (shm_controlo_chegada >= 0) {
  1018. shmctl(shm_controlo_chegada, IPC_RMID, NULL);
  1019. }
  1020. if (shm_controlo_partida >= 0) {
  1021. shmctl(shm_controlo_partida, IPC_RMID, NULL);
  1022. }
  1023. if (shm_size_mq >= 0) {
  1024. shmctl(shm_size_mq, IPC_RMID, NULL);
  1025. }
  1026. if (shm_voo_chegada >= 0) {
  1027. shmctl(shm_voo_chegada, IPC_RMID, NULL);
  1028. }
  1029. if (shm_voo_partida >= 0) {
  1030. shmctl(shm_voo_partida, IPC_RMID, NULL);
  1031. }
  1032.  
  1033. sem_destroy(&sem_partida);
  1034. sem_destroy(&sem_chegada);
  1035. sem_destroy(&sem_mq);
  1036. sem_destroy(&sem_log);
  1037. sem_destroy(&sem_controlos);
  1038.  
  1039. exit(1);
  1040. }
  1041.  
  1042.  
  1043. void catch_ctrlc(int sig)
  1044. {
  1045. (void)sig;
  1046. logger("Signal SIGINT received - Server terminating ...");
  1047.  
  1048. logger("Printing statistics...");
  1049. kill(my_pid, SIGUSR1);
  1050. sigprocmask (SIG_BLOCK, &block_stats, NULL);
  1051.  
  1052. logger("Cleaning resources...");
  1053. clean();
  1054.  
  1055. logger("Program ended.");
  1056.  
  1057. exit(0);
  1058. }
  1059.  
  1060. void init()
  1061. {
  1062. key = ftok("progfile", 65);
  1063.  
  1064. cfg = (config *)malloc(sizeof(config));
  1065.  
  1066. read_config(cfg);
  1067.  
  1068. }
  1069.  
  1070. int main()
  1071. {
  1072. logger("## Program Started ##");
  1073.  
  1074. init();
  1075.  
  1076. gestor_simulacao();
  1077.  
  1078. return 0;
  1079. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement