Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _POSIX_C_SOURCE 1
- #include <stdio.h>
- #include <stdlib.h>
- #include <pthread.h>
- #include <unistd.h>
- #include <semaphore.h>
- #include <sys/ipc.h>
- #include <sys/shm.h>
- #include <sys/fcntl.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <ctype.h>
- #include <sys/stat.h>
- #include <signal.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <sys/mman.h>
- #include <linux/mman.h>
- #include <pthread.h>
- #include <sys/ipc.h>
- #include <sys/msg.h>
- #include <signal.h>
- #include <sys/time.h>
- #include <sys/msg.h>
- #include "headers/logger.h"
- #include "headers/config_utils.h"
- #include "headers/cmd_console.h"
- #include "headers/utils.h"
- #include "headers/main.h"
- // Named Pipe
- #define PIPE_NAME "resourses/named_pipe"
- #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
- #define ARRIVAL "ARRIVAL"
- #define DEPARTURE "DEPARTURE"
- #define DEBUG
- #define MAX_THREADS 2
- #define TYPE_VOO_P_TO_TORRE 1
- #define TYPE_VOO_C_TO_TORRE 2
- #define TYPE_TORRE_TO_V_P 3
- #define TYPE_TORRE_TO_V_C 4
- //Array para as threads e suas variaveis
- pthread_t *threads_voo_partida, *threads_voo_chegada, thread_pipe, thread_tratar_voos_c, thread_tratar_voos_p, *threads_deslocacao;
- //variaveis de inicializacao da memoria partilhada
- int shmid_estatistica, shmid_slots, shm_controlo_chegada, shm_controlo_partida, shm_size_mq, shm_voo_chegada, shm_voo_partida, shm_algoritmo;
- Voo_partida *voo_partida;
- Voo_chegada *voo_chegada;
- Slots *slots;
- Estatistica *estatisticas;
- Algoritmo *algoritmo;
- int *controlo_chegadas, *controlo_partidas;
- Mq_size *mq_size;
- sigset_t block_clean;
- sigset_t block_stats;
- pid_t my_pid;
- int id_thread_pipe, id_thread_espera, id_tratar_voo_chegada, id_tratar_voo_partida;
- //variaveis dos semaforos e mutexes
- pthread_mutex_t mutex_partidas = PTHREAD_MUTEX_INITIALIZER;
- pthread_mutex_t mutex_chegadas = PTHREAD_MUTEX_INITIALIZER;
- pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
- pthread_mutex_t mutex_torre = PTHREAD_MUTEX_INITIALIZER;
- pthread_cond_t condicao_chegada, condicao_partida, condicao_t_c, condicao_t_p, condicao_criar;
- sem_t sem_partida, sem_chegada, sem_mq, sem_log, sem_controlos;
- // VARIAVEIS DE ESTRUTURAS
- config *cfg;
- key_t key;
- cmd *received_cmd;
- //message queue
- int msgid;
- //contadores dos arrays
- int pos_partida, pos_chegada, contador_chegada, contador_partida, contador_chegadas, contador_partidas, n_holding, n_holding_u;
- //pipe
- int fd;
- //Variaveis de tempo
- struct timeval tp_incial;
- struct timespec ts_inicial;
- struct timeval tp_atual;
- struct timespec ts_atual;
- struct timeval tp_aux;
- struct timespec ts_aux;
- //Controlos
- int controlo, controlo_p, controlo_c;
- //filas de voos para a torre de controlo;
- Voo_chegada *fila_chegada;
- Voo_partida *fila_partida;
- void desocupa_slot(Slot slot){
- if(slot.id==slots->slot1.id)
- slots->slot1.livre=1;
- else if(slot.id==slots->slot2.id)
- slots->slot2.livre=1;
- else if(slot.id==slots->slot3.id)
- slots->slot3.livre=1;
- else if(slot.id==slots->slot4.id)
- slots->slot4.livre=1;
- }
- void *voos_chegada(){
- Msg_to_queue msg_e, msg_r;
- int holding=0;
- int pos=pos_chegada-1;
- time_t now, after;
- struct timeval tp_antes, tp_depois;
- struct timespec ts_antes, ts_depois;
- //Para escrever no ficheiro log
- char *message_log;
- sem_wait(&sem_log);
- int size=snprintf(NULL, 0, "\nthread chegada [%s] criada com sucesso", voo_chegada[pos].id);
- message_log=malloc(size+1);
- sprintf(message_log, "thread chegada [%s] criada com sucesso", voo_chegada[pos].id);
- logger(message_log);
- sem_post(&sem_log);
- free(message_log);
- sem_wait(&estatisticas->sem_estatisticas);
- estatisticas->n_voos_criados++;
- sem_post(&estatisticas->sem_estatisticas);
- printf("VOO_C: chegada ID %s\n", voo_chegada[pos].id);
- //pthread_mutex_lock(&mutex);
- msg_e.info.voo_c=voo_chegada[pos];
- msg_e.type=TYPE_VOO_C_TO_TORRE;
- if((msgsnd(msgid, &msg_e, sizeof(Msg_to_queue)-sizeof(long), 0))==-1){
- perror("msgsnd!");
- exit(1);
- }
- else{
- printf("VOO_C: %s enviou mensagem a torre de controlo da sua chegada\n", voo_chegada[pos].id);
- gettimeofday(&tp_antes, NULL);
- ts_antes.tv_sec=tp_antes.tv_sec;
- sem_wait(&mq_size->sem_mq);
- mq_size->tamanho++;
- sem_post(&mq_size->sem_mq);
- //espera ate receber sinal da torre de controlo. Apos receber o sinal executa o resto da funcao
- pthread_mutex_lock(&mutex_chegadas);
- pthread_cond_wait(&condicao_chegada, &mutex_chegadas);
- pthread_mutex_unlock(&mutex_chegadas);
- if((msgrcv(msgid, &msg_r, sizeof(Msg_to_queue), TYPE_TORRE_TO_V_C, 0)==-1)){
- perror("msgrcv");
- exit(1);
- }
- else{
- sem_wait(&sem_chegada);
- gettimeofday(&tp_depois, NULL);
- ts_depois.tv_sec=tp_depois.tv_sec;
- 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);
- //gettimeofday(&tp_incial, NULL);
- pthread_mutex_lock(&mutex_chegadas);
- pthread_cond_wait(&condicao_chegada, &mutex_chegadas);
- //recebeu o sinal e o slot informa o voo que e preciso fazer um devio para outro aeroporto
- printf("Recebeu o sinal\n");
- if(msg_r.info.slot.desvio==1){
- printf("Vai ser desviado para outro aeroporto\n");
- pthread_mutex_unlock(&mutex_chegadas);
- sem_post(&sem_chegada);
- pthread_exit(NULL);
- }
- //Caso o slot nao indique que e preciso fazer desvio
- gettimeofday(&tp_depois, NULL);
- ts_depois.tv_sec=tp_depois.tv_sec;
- sem_wait(&estatisticas->sem_estatisticas);
- 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;
- estatisticas->n_voos_aterrados++;
- sem_post(&estatisticas->sem_estatisticas);
- printf("VOO: voo %s vai aterrar no slot %d...\n", msg_r.info.slot.voo_p.id, msg_r.info.slot.id);
- sleep(cfg->landing_duration);
- printf("VOO: voo %s aterrou!\n", msg_r.info.slot.voo_p.id);
- sem_wait(&estatisticas->sem_estatisticas);
- estatisticas->n_voos_aterrados++;
- sem_post(&estatisticas->sem_estatisticas);
- sem_wait(&algoritmo->sem_controlo_algoritmo);
- algoritmo->n_chegadas--;
- if(algoritmo->n_chegadas==0)
- algoritmo->controlo_algoritmo=0;
- sem_post(&algoritmo->sem_controlo_algoritmo);
- sleep(cfg->landing_interval);
- pthread_mutex_unlock(&mutex_chegadas);
- sem_post(&sem_chegada);
- pthread_exit(NULL);
- }
- }
- }
- /*void *controla_holding(){
- while(1){
- }
- }*/
- void *voos_partida(){
- struct timeval tp_depois, tp_aux;
- struct timespec ts_depois, ts_aux;
- time_t now, after;
- Msg_to_queue msg_e, msg_r;
- int pos=pos_partida-1;
- char *message_log;
- //Vai escrever no log
- sem_wait(&sem_log);
- int size=snprintf(NULL, 0, "thread partida [%s] criada com sucesso", voo_partida[pos_partida-1].id);
- message_log=malloc(size+1);
- sprintf(message_log, "thread partida [%s] criada com sucesso", voo_partida[pos_partida-1].id);
- logger(message_log);
- sem_post(&sem_log);
- free(message_log);
- //Vai adicionar as estatisticas o numero de voos criados
- sem_wait(&estatisticas->sem_estatisticas);
- estatisticas->n_voos_criados++;
- sem_post(&estatisticas->sem_estatisticas);
- //vai enviar msg a torre de controlo
- msg_e.info.voo_p=voo_partida[pos];
- msg_e.type=TYPE_VOO_P_TO_TORRE;
- printf("VOO_P: chegada ID %s\n", voo_partida[pos].id);
- if((msgsnd(msgid, &msg_e, sizeof(Msg_to_queue)-sizeof(long), 0))==-1){
- perror("msgsnd!");
- exit(1);
- }
- else{
- printf("VOO_P: %s enviou mensagem a torre de controlo da sua ida\n", voo_partida[pos].id);
- time(&now);
- sem_wait(&mq_size->sem_mq);
- mq_size->tamanho++;
- sem_post(&mq_size->sem_mq);
- //recebe voo partida da fila de espera
- if((msgrcv(msgid, &msg_r, sizeof(Msg_to_queue)-sizeof(long), TYPE_TORRE_TO_V_P, 0)==-1)){
- perror("msgrcv");
- exit(1);
- }
- else{
- sem_wait(&sem_partida);
- printf("VOO: Recebeu mensagem da torre, vai tratar do voo %s\n", msg_r.info.slot.voo_p.id);
- gettimeofday(&tp_depois, NULL);
- ts_depois.tv_sec=tp_depois.tv_sec;
- printf("voo %s vai partir as %d\n", msg_r.info.slot.voo_p.id, msg_r.info.slot.voo_p.takeoff);
- if(*controlo_partidas==1){
- //printf("ENTROU: %d\n", voo_partida[pos_partida].takeoff);
- ts_depois.tv_sec+=msg_r.info.slot.voo_p.takeoff;
- }
- else
- ts_depois.tv_sec+=10;
- pthread_mutex_lock(&mutex_partidas);
- pthread_cond_timedwait(&condicao_t_c, &mutex, &ts_depois);
- if (*controlo_partidas == 1) {
- //verifica o tempo de descolar é o correto
- do {
- gettimeofday(&tp_aux, NULL);
- ts_aux.tv_sec=tp_aux.tv_sec;
- } while(ts_aux.tv_sec-ts_inicial.tv_sec<=msg_r.info.slot.voo_p.takeoff);
- time(&after);
- printf("VOO: voo %s vai descolar do slot %d...\n", msg_r.info.slot.voo_p.id, msg_r.info.slot.id);
- sem_wait(&estatisticas->sem_estatisticas);
- estatisticas->tempo_medio_espera_descolar=(estatisticas->tempo_medio_espera_descolar*pos+(int)difftime(after, now)*(cfg->time/1000))/(pos+1);
- sem_post(&estatisticas->sem_estatisticas);
- sleep(cfg->depart_duration);
- printf("VOO: voo %s vai descolou!\n", msg_r.info.slot.voo_p.id);
- sleep(cfg->depart_interval);
- sem_wait(&estatisticas->sem_estatisticas);
- estatisticas->n_voos_descolaram++;
- sem_post(&estatisticas->sem_estatisticas);
- desocupa_slot(msg_r.info.slot);
- pthread_mutex_unlock(&mutex_partidas);
- sem_post(&sem_partida);
- sem_wait(&algoritmo->sem_controlo_algoritmo);
- algoritmo->n_partidas--;
- if(algoritmo->n_partidas==0)
- algoritmo->controlo_algoritmo=0;
- sem_post(&algoritmo->sem_controlo_algoritmo);
- pthread_exit(NULL);
- }
- }
- pthread_mutex_unlock(&mutex_partidas);
- }
- }
- void ordenar_torre_chegadas(Voo_chegada voo_chegada[], int i){
- Voo_chegada aux_c;
- while(voo_chegada[i].eta<voo_chegada[i-1].eta && i<0){
- aux_c=voo_chegada[i];
- voo_chegada[i]=voo_chegada[i-1];
- voo_chegada[i-1]=aux_c;
- i--;
- }
- }
- void ordenar_torre_partidas(Voo_partida voo_partida[], int i){
- Voo_partida aux_p;
- while(voo_partida[i].takeoff<voo_partida[i-1].takeoff && i<0){
- aux_p=voo_partida[i];
- voo_partida[i]=voo_partida[i-1];
- voo_partida[i-1]=aux_p;
- i--;
- }
- }
- Slot choose_slot(char *tipo){
- int r;
- if(strcmp(tipo, "aterragem")==0){
- if(slots->slot1.livre==1){
- slots->slot1.livre=0;
- return slots->slot1;
- }
- if(slots->slot2.livre==1){
- slots->slot2.livre=0;
- return slots->slot2;
- }
- else{
- r=rand()%1+1;
- if(r==1){
- slots->slot1.holding=1;
- return slots->slot1;
- }
- else{
- slots->slot2.holding=1;
- return slots->slot2;
- }
- }
- }
- else{
- if(slots->slot3.livre==1){
- slots->slot3.livre=0;
- return slots->slot3;
- }
- if(slots->slot4.livre==1){
- slots->slot4.livre=0;
- return slots->slot4;
- }
- else{
- r=rand()%1+1;
- if(r==1)
- return slots->slot3;
- else
- return slots->slot4;
- }
- }
- }
- Slot find_slot(Voo_chegada v){
- if(strcmp(slots->slot1.voo_c.id, v.id))
- return slots->slot1;
- else
- return slots->slot2;
- }
- void *deslocacao(){
- int check_holding=0;
- Slot slot;
- slot=find_slot(fila_chegada[pos_chegada]);
- pthread_mutex_lock(&mutex_torre);
- pthread_cond_signal(&condicao_criar);
- pthread_mutex_lock(&mutex_chegadas);
- printf("Vai deslocar para a zona de aterragem\n");
- do{
- slot.voo_c.eta-=1*(cfg->time/1000);
- slot.voo_c.combustivel-=1*(cfg->time/1000);
- }while(slot.voo_c.eta<0);
- printf("Chegou a zona de aterragem\n");
- while(contador_chegadas-estatisticas->n_voos_aterrados>5){
- slot.voo_c.combustivel-=1*(cfg->time/1000);
- if(check_holding==0)
- check_holding=1;
- if(slot.voo_c.combustivel<=0){
- slot.desvio=1;
- pthread_cond_signal(&condicao_chegada);
- pthread_mutex_unlock(&mutex_chegadas);
- pthread_mutex_unlock(&mutex_torre);
- pthread_exit(NULL);
- }
- }
- if(check_holding==1){
- if(slot.voo_c.prioridade==1){
- n_holding_u++;
- sem_wait(&estatisticas->sem_estatisticas);
- estatisticas->n_medio_holding_urgencia=n_holding_u/estatisticas->n_voos_aterrados;
- sem_post(&estatisticas->sem_estatisticas);
- }
- else{
- n_holding++;
- sem_wait(&estatisticas->sem_estatisticas);
- estatisticas->n_medio_holding_aterragem=n_holding/estatisticas->n_voos_aterrados;
- sem_post(&estatisticas->sem_estatisticas);
- }
- }
- printf("Mandou sinal para thread chegada\n");
- pthread_cond_signal(&condicao_chegada);
- pthread_mutex_unlock(&mutex_chegadas);
- pthread_mutex_unlock(&mutex_torre);
- pthread_exit(NULL);
- }
- void comunica_voo(long tipo_enviar, long tipo_receber, int pos){
- Msg_to_queue msg_e;
- //Slot slot;
- if(tipo_receber==TYPE_VOO_C_TO_TORRE){
- msg_e.info.slot=choose_slot("aterragem");
- msg_e.info.slot.voo_c=fila_chegada[pos];
- }
- else{
- msg_e.info.slot=choose_slot("descolagem");
- msg_e.info.slot.voo_p=fila_partida[pos];
- }
- msg_e.type=tipo_enviar;
- if((msgsnd(msgid, &msg_e, sizeof(Msg_to_queue)-sizeof(long), 0))==-1){
- perror("msgsnd!");
- exit(1);
- }
- else{
- printf("TORRE: Mensagem enviada para voo chegada %s com sucesso, tipo enviar: %ld\n", msg_e.info.slot.voo_c.id, tipo_enviar);
- if(tipo_receber==TYPE_VOO_C_TO_TORRE){
- /*pthread_mutex_lock(&mutex_torre);
- pthread_cond_signal(&condicao_criar);
- pthread_mutex_unlock(&mutex_torre);*/
- }
- else{
- printf("TORRE: Mensagem enviada para voo partida %s com sucesso, tipo enviar: %ld\n", msg_e.info.slot.voo_p.id, tipo_enviar);
- pthread_mutex_lock(&mutex_partidas);
- pthread_cond_signal(&condicao_partida);
- pthread_mutex_unlock(&mutex_partidas);
- }
- sem_wait(&sem_mq);
- mq_size->tamanho--;
- sem_post(&sem_mq);
- }
- }
- void *tratar_voos_p(){
- int contador=1;
- while (1) {
- if(*controlo_partidas==1){
- if(contador==contador_partidas){
- sem_wait(&algoritmo->sem_controlo_algoritmo);
- algoritmo->n_partidas++;
- printf("%d\n", algoritmo->n_partidas);
- sem_post(&algoritmo->sem_controlo_algoritmo);
- contador++;
- comunica_voo(TYPE_TORRE_TO_V_P, TYPE_VOO_P_TO_TORRE, contador_partidas-1);
- }
- }
- }
- }
- void *tratar_voos_c(){
- int contador=1;
- while(1){
- if(*controlo_chegadas==1){
- //so podem ocorrer dois voos de cada vez. SERA NA THREAD DO VOO??
- if(contador==contador_chegadas){
- sem_wait(&algoritmo->sem_controlo_algoritmo);
- algoritmo->n_chegadas++;
- printf("Incremenou: %d\n", algoritmo->n_chegadas);
- sem_post(&algoritmo->sem_controlo_algoritmo);
- contador++;
- comunica_voo(TYPE_TORRE_TO_V_C, TYPE_VOO_C_TO_TORRE, contador_chegadas-1);
- }
- }
- }
- }
- void funcao_algoritmo(){
- if(fila_chegada[pos_chegada].eta<=fila_partida[pos_partida].takeoff && fila_chegada[pos_chegada].eta!=-1 && fila_partida[pos_partida].takeoff!=-1){
- printf("ENtour1\n");
- sem_wait(&algoritmo->sem_controlo_algoritmo);
- algoritmo->controlo_algoritmo=1;
- sem_post(&algoritmo->sem_controlo_algoritmo);
- sem_wait(&sem_controlos);
- *controlo_chegadas=1;
- *controlo_partidas=0;
- sem_post(&sem_controlos);
- }
- else if(fila_chegada[pos_chegada].eta>fila_partida[pos_partida].takeoff && fila_chegada[pos_chegada].eta!=-1 && fila_partida[pos_partida].takeoff!=-1){
- printf("ENtour2\n");
- sem_wait(&algoritmo->sem_controlo_algoritmo);
- algoritmo->controlo_algoritmo=1;
- sem_post(&algoritmo->sem_controlo_algoritmo);
- sem_wait(&sem_controlos);
- *controlo_chegadas=0;
- *controlo_partidas=1;
- sem_post(&sem_controlos);
- }
- else if(fila_chegada[pos_chegada].eta!=-1){
- printf("ENtour3\n");
- sem_wait(&algoritmo->sem_controlo_algoritmo);
- algoritmo->controlo_algoritmo=1;
- sem_post(&algoritmo->sem_controlo_algoritmo);
- sem_wait(&sem_controlos);
- *controlo_chegadas=1;
- *controlo_partidas=0;
- sem_post(&sem_controlos);
- }
- else if(fila_partida[pos_partida].takeoff!=-1){
- printf("Entrou4\n");
- sem_wait(&algoritmo->sem_controlo_algoritmo);
- algoritmo->controlo_algoritmo=1;
- sem_post(&algoritmo->sem_controlo_algoritmo);
- sem_wait(&sem_controlos);
- *controlo_chegadas=0;
- *controlo_partidas=1;
- sem_post(&sem_controlos);
- }
- }
- void torre_controlo(){
- printf("------- BEM VINDO TORRE DE CONTROLO ------\n");
- //int aux_c=0, aux_p=0;
- Msg_to_queue msg_r;
- fila_chegada=malloc(sizeof(Voo_chegada)*cfg->min_depart);
- fila_partida=malloc(sizeof(Voo_partida)*cfg->max_depart);
- threads_deslocacao=malloc(cfg->min_depart*sizeof(pthread_t*));
- for (int i = 0; i < cfg->max_depart; ++i)
- {
- fila_partida[i].takeoff=-1;
- }
- for (int i = 0; i < cfg->min_depart; ++i)
- {
- fila_chegada[i].eta=-1;
- }
- if(pthread_create(&thread_tratar_voos_c, NULL, tratar_voos_c, &id_tratar_voo_chegada)!=0){
- perror("Erro criacao das threads\n");
- }
- if(pthread_create(&thread_tratar_voos_p, NULL, tratar_voos_p, &id_tratar_voo_partida)!=0){
- perror("Erro criacao das threads\n");
- }
- while(1){
- if(algoritmo->controlo_algoritmo==0){
- funcao_algoritmo();
- }
- if(mq_size->tamanho!=0){
- if((msgrcv(msgid, &msg_r, sizeof(Msg_to_queue), TYPE_VOO_C_TO_TORRE, 0)==-1)){
- perror("msgrcv");
- exit(1);
- }
- else{
- printf("TORRE: Recebeu mensagem da chegada do voo %s\n", msg_r.info.voo_c.id);
- if(contador_chegadas>cfg->min_depart-1){
- printf("Vai rejeitar o voo %s\n", msg_r.info.voo_c.id);
- sem_wait(&estatisticas->sem_estatisticas);
- estatisticas->n_voos_rejeitados++;
- sem_post(&estatisticas->sem_estatisticas);
- }
- else{
- printf("Vai inserir voo %s na fila de chegadas %d\n", msg_r.info.voo_c.id, msg_r.info.voo_c.eta);
- fila_chegada[contador_chegadas]=msg_r.info.voo_c;
- printf("voo %s inserido na lista de espera.\n", fila_chegada[contador_chegadas].id);
- contador_chegadas++;
- //printf("Incrementou: %d\n", contador_chegadas);
- if(contador_chegadas>1)
- ordenar_torre_chegadas(fila_chegada, contador_chegadas);
- }
- }
- if((msgrcv(msgid, &msg_r, sizeof(Msg_to_queue), TYPE_VOO_P_TO_TORRE, 0)==-1)){
- perror("msgrcv");
- exit(1);
- }
- else{
- printf("TORRE: Recebeu mensagem da partida do voo %s\n", msg_r.info.voo_p.id);
- if(contador_partidas>cfg->max_depart-1){
- printf("Vai rejeitar o voo %s\n", msg_r.info.voo_p.id);
- sem_wait(&estatisticas->sem_estatisticas);
- estatisticas->n_voos_rejeitados++;
- sem_post(&estatisticas->sem_estatisticas);
- }
- else{
- printf("Vai inserir voo na fila de partidas\n");
- fila_partida[contador_partidas]=msg_r.info.voo_p;
- contador_partidas++;
- if(contador_partidas>1)
- ordenar_torre_partidas(fila_partida, contador_partidas);
- }
- }
- }
- }
- }
- void ordenar_gestor_chegadas(Voo_chegada voo_chegada[], int i){
- Voo_chegada aux_c;
- while(voo_chegada[i].init<voo_chegada[i-1].init){
- printf("I: %d %d \n", voo_chegada[i].init, voo_chegada[i-1].init);
- aux_c=voo_chegada[i];
- voo_chegada[i]=voo_chegada[i-1];
- voo_chegada[i-1]=aux_c;
- printf("depois: %d %d\n", voo_chegada[i].init,voo_chegada[i-1].init);
- i--;
- }
- }
- void ordenar_gestor_partidas(Voo_partida voo_partida[], int i){
- Voo_partida aux_p;
- while(voo_partida[i].init<voo_partida[i-1].init){
- //printf("I: %d %d\n",voo_partida[i].init, voo_partida[i-1].init);
- aux_p=voo_partida[i];
- voo_partida[i]=voo_partida[i-1];
- voo_partida[i-1]=aux_p;
- printf("depois: %d %d\n", voo_partida[i].init, voo_partida[i-1].init);
- i--;
- }
- }
- /*void print_array(Voo_chegada v[]){
- for(int i=0; i<3; i++){
- printf("%s\n", v[i].id);
- }
- }*/
- void *ler_do_pipe(){
- //ABRE O PIPE
- if ((mkfifo(PIPE_NAME, O_CREAT | O_EXCL | 0600) < 0) && (errno != EEXIST))
- {
- perror("Cannot create pipe: ");
- logger("Cannot create named pipe.");
- exit(0);
- }
- // Opens the pipe for reading
- if ((fd = open(PIPE_NAME, O_RDWR)) < 0)
- {
- perror("Cannot open pipe for reading:");
- logger("Cannot open pipe for reading");
- exit(0);
- }
- contador_chegada=0;
- contador_partida=0;
- while (1){
- read(fd, received_cmd, sizeof(cmd));
- #ifdef DEBUG
- 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);
- #endif
- if(received_cmd->command!=NULL){
- //printf("%d\n", pos);
- if(strcmp(received_cmd->command, "ARRIVAL")==0){
- //printf("%s | %d | %d | %d \n", received_cmd->plane, received_cmd->init, received_cmd->eta, received_cmd->fuel);
- //printf("Pos inicio: %d\n", contador_chegada);
- strcpy(voo_chegada[contador_chegada].id, received_cmd->plane);
- voo_chegada[contador_chegada].init=received_cmd->init;
- //printf("VOO CHEGADA: %d %d\n", voo_chegada[contador_chegada].init, contador_chegada);
- voo_chegada[contador_chegada].eta=received_cmd->eta;
- voo_chegada[contador_chegada].combustivel=received_cmd->fuel;
- voo_chegada[contador_chegada].prioridade=0;
- //printf("Adicionou novo voo ao array\n");
- //printf("antes: %d %d\n", voo_chegada[contador_chegada].init, contador_chegada);
- if(contador_chegada>0){
- ordenar_gestor_chegadas(voo_chegada, contador_chegada);
- }
- //printf("INIT: %d %d %d %d\n", voo_chegada[contador_chegada].init, voo_chegada[pos_chegada].init, contador_chegada, pos_chegada);
- contador_chegada++;
- pthread_mutex_lock(&mutex);
- //printf("Vai enviar sinal...\n");
- controlo=1;
- //printf("ENVIEI CONTROLO %d\n", controlo);
- pthread_cond_signal(&condicao_t_c);
- pthread_mutex_unlock(&mutex);
- //printf("Enviou sinal chegada..\n");
- }
- else if(strcmp(received_cmd->command, "DEPARTURE")==0){
- //printf("Pos inicio: %d\n", contador_partida);
- strcpy(voo_partida[contador_partida].id, received_cmd->plane);
- voo_partida[contador_partida].init=received_cmd->init;
- //printf("VOO PARTIDA: %d %d\n", voo_partida[contador_partidas].init, contador_partida);
- voo_partida[contador_partida].takeoff=received_cmd->takeoff;
- voo_partida[contador_partida].prioridade=0;
- //printf("Adicionou novo voo ao array\n");
- //printf("antes: %d %d\n", voo_partida[contador_partida].init, contador_partida);
- if(contador_partida>0){
- ordenar_gestor_partidas(voo_partida, contador_partida);
- }
- //printf("INIT: %d %d %d %d\n", voo_partida[contador_partida].init, voo_partida[pos_partida].init, contador_partida, pos_partida);
- contador_partida++;
- pthread_mutex_lock(&mutex);
- //printf("Vai enviar sinal...\n");
- controlo=2;
- //printf("ENVIEI CONTROLO %d\n", controlo);
- pthread_cond_signal(&condicao_t_c);
- pthread_mutex_unlock(&mutex);
- //printf("Enviou sinal..\n");
- }
- }
- }
- }
- void stats_print(int sig) {
- (void) sig;
- printf("\n----- Analise de Voos -----\n");
- printf("Numero de Voos criados: %d\n", estatisticas->n_voos_criados);
- printf("Numero de Voos aterrados: %d\n", estatisticas->n_voos_aterrados);
- printf("Numero de Voos que descolaram: %d\n", estatisticas->n_voos_descolaram);
- printf("Numero de Voos rejeitados: %d\n", estatisticas->n_voos_rejeitados);
- printf("Numero de Voos redirecionados: %d\n", estatisticas->n_voos_redirecionados);
- printf("----- Analise Temporal -----\n");
- printf("Tempo medio de espera (atterragem): %.2f\n", estatisticas->tempo_medio_espera_aterrar);
- printf("Tempo medio de espera (descolagem): %.2f\n", estatisticas->tempo_medio_espera_descolar);
- printf("----- Holding -----\n");
- printf("Numero medio de holding (urgencia): %.2f\n", estatisticas->n_medio_holding_urgencia);
- printf("Numero medio de holding (aterragem): %.2f\n\n", estatisticas->n_medio_holding_aterragem);
- }
- void gestor_simulacao(){
- pos_partida=0;
- pos_chegada=0;
- contador_chegadas=0;
- contador_partidas=0;
- gettimeofday(&tp_incial, NULL);
- ts_inicial.tv_sec=tp_incial.tv_sec;
- controlo=0;
- n_holding=0;
- n_holding_u=0;
- //criacao da Message Queue
- if((msgid=msgget(IPC_PRIVATE, IPC_CREAT|0666))==-1){
- perror("Erro na criacao da message queue");
- exit(1);
- }
- else
- printf("MESSAGE QUEUE CRIADA COM SUCESSO\n");
- //alocar memoria para os comandos
- received_cmd = malloc(sizeof(cmd *));
- //alocar espaco para as informacoes das threads
- voo_partida=malloc(cfg->max_depart*sizeof(Voo_partida));
- voo_chegada=malloc(cfg->min_depart*sizeof(Voo_chegada));
- for (int i = 0; i < cfg->max_depart; ++i)
- {
- voo_partida[i].init=-1;
- }
- for (int i = 0; i < cfg->min_depart; ++i)
- {
- voo_chegada[i].init=-1;
- }
- //alocar espaco para as threads
- threads_voo_partida=malloc(cfg->max_depart*sizeof(pthread_t*));
- threads_voo_chegada=malloc(cfg->min_depart*sizeof(pthread_t*));
- //Memoria partilhada para algoritmo
- shm_algoritmo = shmget(IPC_PRIVATE, sizeof(Algoritmo), IPC_CREAT | 0777);
- if (shm_algoritmo < 0) {
- logger("Error shared memory creation");
- clean();
- }
- algoritmo=(Algoritmo*)shmat(shm_algoritmo, NULL, 0);
- if(algoritmo==(Algoritmo*)-1)
- logger("Error in mapping variable.");
- algoritmo->n_chegadas=0;
- algoritmo->n_partidas=0;
- algoritmo->controlo_algoritmo=0;
- sem_init(&algoritmo->sem_controlo_algoritmo, 0, 1);
- //Memoria partilhada para estatisticas
- shmid_estatistica = shmget(IPC_PRIVATE, sizeof(Estatistica), IPC_CREAT | 0777);
- if (shmid_estatistica < 0) {
- logger("Error shared memory creation");
- clean();
- }
- estatisticas=(Estatistica*)shmat(shmid_estatistica, NULL, 0);
- if(estatisticas==(Estatistica*)-1)
- logger("Error in mapping variable.");
- estatisticas->n_voos_criados=0;
- estatisticas->n_voos_aterrados=0;
- estatisticas->tempo_medio_espera_aterrar=0;
- estatisticas->n_voos_descolaram=0;
- estatisticas->tempo_medio_espera_descolar=0;
- estatisticas->n_medio_holding_aterragem=0;
- estatisticas->n_medio_holding_urgencia=0;
- estatisticas->n_voos_redirecionados=0;
- estatisticas->n_voos_rejeitados=0;
- sem_init(&estatisticas->sem_estatisticas, 0, 1);
- //Memoria partilhada para os slots
- shmid_slots = shmget(IPC_PRIVATE, sizeof(Estatistica), IPC_CREAT | 0777);
- if (shmid_slots < 0) {
- logger("Error shared memory creation");
- clean();
- }
- slots = (Slots*)shmat(shmid_slots, NULL, 0);
- if (slots == (Slots*)-1)
- logger("Error in mapping variable.");
- slots->slot1.id=1;
- slots->slot1.tipo=1; //aterragem
- slots->slot1.holding=0;
- slots->slot1.desvio=0;
- slots->slot1.livre=1;
- sem_init(&slots->slot1.sem_slot, 0, 1);
- slots->slot2.id=2;
- slots->slot2.tipo=1; //aterragem
- slots->slot2.holding=0;
- slots->slot2.desvio=0;
- slots->slot2.livre=1;
- sem_init(&slots->slot2.sem_slot, 0, 1);
- slots->slot3.id=3;
- slots->slot3.tipo=0; //descolagem
- slots->slot3.holding=0;
- slots->slot3.desvio=0;
- slots->slot3.livre=1;
- sem_init(&slots->slot3.sem_slot, 0, 1);
- slots->slot4.id=4;
- slots->slot4.tipo=0; //descolagem
- slots->slot4.holding=0;
- slots->slot4.desvio=0;
- slots->slot4.livre=1;
- sem_init(&slots->slot4.sem_slot, 0, 1);
- //Memoria partilhada para o tamanho da MQ e seu semaforo
- shm_size_mq = shmget(IPC_PRIVATE, sizeof(Mq_size*), IPC_CREAT | 0777);
- if (shm_size_mq < 0) {
- logger("Error shared memory creation");
- clean();
- }
- mq_size=(Mq_size*)shmat(shm_size_mq, NULL, 0);
- if(mq_size==(Mq_size*)-1)
- logger("Error in mapping variable.");
- mq_size->tamanho=0;
- sem_init(&mq_size->sem_mq, 0, 1);
- //Memoria partilhada para controlar chegadas
- shm_controlo_chegada = shmget(IPC_PRIVATE, sizeof(int*), IPC_CREAT | 0777);
- if (shm_size_mq < 0) {
- logger("Error shared memory creation");
- clean();
- }
- controlo_chegadas = (int*)shmat(shm_controlo_chegada, NULL, 0);
- if (controlo_chegadas == (int*)-1 )
- logger("Error in mapping variable.");
- //Memoria partilhada para controlar partidas
- shm_controlo_partida = shmget(IPC_PRIVATE, sizeof(int*), IPC_CREAT | 0777);
- if (shm_size_mq < 0) {
- logger("Error shared memory creation");
- clean();
- }
- controlo_partidas = (int*)shmat(shm_controlo_partida, NULL, 0);
- if (controlo_partidas == (int*)-1) {
- logger("Error in mapping variable.");
- }
- *controlo_partidas=0;
- *controlo_chegadas=0;
- //Variaveis de condicao
- pthread_cond_init(&condicao_partida, NULL);
- pthread_cond_init(&condicao_chegada, NULL);
- pthread_cond_init(&condicao_t_c, NULL);
- pthread_cond_init(&condicao_t_p, NULL);
- sem_init(&sem_partida,0,MAX_THREADS);
- sem_init(&sem_partida,0,MAX_THREADS);
- if(sem_init(&sem_log, 0, 1)==-1){
- perror("Erro a criar semaforo log\n");
- exit(1);
- }
- if(sem_init(&sem_controlos, 0, 1)==-1){
- perror("Erro a criar semaforo slots\n");
- exit(1);
- }
- if(sem_init(&sem_mq, 0, 1)==-1){
- perror("Erro a criar semaforo slots\n");
- exit(1);
- }
- //cria a thread do pipe
- if(pthread_create(&thread_pipe, NULL, ler_do_pipe, &id_thread_pipe)!=0){
- perror("Erro criacao das threads\n");
- }
- my_pid = fork();
- if(my_pid == 0){
- torre_controlo();
- exit(0);
- }
- while(1){
- gettimeofday(&tp_atual, NULL);
- ts_atual.tv_sec=tp_atual.tv_sec;
- ts_atual.tv_nsec=tp_atual.tv_usec*1000;
- if(controlo==1){
- ts_atual.tv_sec+=voo_chegada[pos_chegada].init*((cfg->time)/1000);
- }
- else if(controlo==2)
- ts_atual.tv_sec+=voo_partida[pos_partida].init*((cfg->time)/1000);
- else{
- ts_atual.tv_sec+=10;
- }
- //printf("tempo: %ld\n", ts.tv_sec);
- pthread_mutex_lock(&mutex);
- pthread_cond_timedwait(&condicao_t_c, &mutex, &ts_atual);
- if(controlo==1){
- gettimeofday(&tp_aux, NULL);
- ts_aux.tv_sec=tp_aux.tv_sec;
- if(ts_aux.tv_sec-ts_inicial.tv_sec>=voo_chegada[pos_chegada].init){
- if(pthread_create(&threads_voo_chegada[pos_chegada], NULL, voos_chegada, &voo_chegada[pos_chegada])!=0){
- perror("Erro criacao das threads\n");
- }
- else{
- pos_chegada++;
- if(voo_partida[pos_partida].init<voo_chegada[pos_chegada].init && voo_chegada[pos_chegada].init!=-1 && voo_partida[pos_partida].init!=-1){
- controlo=2;
- }
- if(voo_partida[pos_partida].init>voo_chegada[pos_chegada].init && voo_chegada[pos_chegada].init!=-1 && voo_partida[pos_partida].init!=-1){
- controlo=1;
- }
- else if(voo_partida[pos_partida].init!=-1){
- controlo=2;
- }
- else if(pos_chegada==contador_chegada)
- controlo=0;
- }
- }
- }
- else if(controlo==2){
- gettimeofday(&tp_aux, NULL);
- ts_aux.tv_sec=tp_aux.tv_sec;
- if(ts_aux.tv_sec-ts_inicial.tv_sec>=voo_partida[pos_partida].init){
- if(pthread_create(&threads_voo_partida[pos_partida], NULL, voos_partida, &voo_partida[pos_partida])!=0){
- perror("Erro criacao das threads\n");
- }
- else{
- pos_partida++;
- //printf("%d %d \n", voo_partida[pos_partida].init, voo_chegada[pos_chegada].init);
- if(voo_partida[pos_partida].init>voo_chegada[pos_chegada].init && voo_chegada[pos_chegada].init!=-1 && voo_partida[pos_partida].init!=-1)
- controlo=1;
- else if(voo_partida[pos_partida].init<voo_chegada[pos_chegada].init && voo_chegada[pos_chegada].init!=-1 && voo_partida[pos_partida].init!=-1)
- controlo=2;
- else if(voo_chegada[pos_chegada].init!=-1)
- controlo=1;
- else if(pos_partida==contador_partida)
- controlo=0;
- }
- }
- }
- pthread_mutex_unlock(&mutex);
- }
- }
- void clean()
- {
- while (wait(NULL) != -1);
- if (shmid_estatistica >= 0) {
- shmctl(shmid_estatistica, IPC_RMID, NULL);
- }
- if (shmid_slots >= 0) {
- shmctl(shmid_slots, IPC_RMID, NULL);
- }
- if (shm_controlo_chegada >= 0) {
- shmctl(shm_controlo_chegada, IPC_RMID, NULL);
- }
- if (shm_controlo_partida >= 0) {
- shmctl(shm_controlo_partida, IPC_RMID, NULL);
- }
- if (shm_size_mq >= 0) {
- shmctl(shm_size_mq, IPC_RMID, NULL);
- }
- if (shm_voo_chegada >= 0) {
- shmctl(shm_voo_chegada, IPC_RMID, NULL);
- }
- if (shm_voo_partida >= 0) {
- shmctl(shm_voo_partida, IPC_RMID, NULL);
- }
- sem_destroy(&sem_partida);
- sem_destroy(&sem_chegada);
- sem_destroy(&sem_mq);
- sem_destroy(&sem_log);
- sem_destroy(&sem_controlos);
- exit(1);
- }
- void catch_ctrlc(int sig)
- {
- (void)sig;
- logger("Signal SIGINT received - Server terminating ...");
- logger("Printing statistics...");
- kill(my_pid, SIGUSR1);
- sigprocmask (SIG_BLOCK, &block_stats, NULL);
- logger("Cleaning resources...");
- clean();
- logger("Program ended.");
- exit(0);
- }
- void init()
- {
- key = ftok("progfile", 65);
- cfg = (config *)malloc(sizeof(config));
- read_config(cfg);
- }
- int main()
- {
- logger("## Program Started ##");
- init();
- gestor_simulacao();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement