Advertisement
Guest User

Untitled

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