// file expiration timer thread void * file_expiration_timer(void * opt) { u32_t current_dtn_time; file_transfer_info_list_item_t * item, * next; while(1) { pthread_sleep(10); current_dtn_time = get_current_dtn_time(); pthread_mutex_lock(&mutexdata); for(item = file_transfer_info_list.first; item != NULL; item = next) { next = item->next; /* if (item->info->last_bundle_time + item->info->expiration < current_dtn_time) { char* filename = (char*) malloc(item->info->filename_len + strlen(item->info->full_dir) +1); strcpy(filename, item->info->full_dir); strcat(filename, item->info->filename); if (remove(filename) < 0) perror("Error eliminating expired file:"); printf("Eliminated file %s because timer has expired\n", filename); file_transfer_info_list_item_delete(&file_transfer_info_list, item); free(filename); }*/ } pthread_mutex_unlock(&mutexdata); sched_yield(); } pthread_exit(NULL); }
void *departing(void* arg){ // departing function performs takeoff in 2t seconds plane* p = (plane*) arg; //pthread_mutex_lock(p->p_lock); pthread_cond_wait(p->cond, p->p_lock); pthread_sleep(2*t); FILE* f; f=fopen(filename, "a"); fprintf(f, " %d\t D\t\t %ld\t\t %ld\t\t %ld\n", p->ID, p->arrival_time, time(NULL)-begtime, (time(NULL)-begtime)-p->arrival_time); fclose(f); printf("Takeoff plane with ID: %d departed at t: %ld\n", p->ID, time(NULL)-begtime); pthread_cond_signal(p->cond); pthread_mutex_unlock(p->p_lock); pthread_exit(0); }
void *emergency_landing (void* arg){ // Emergency landing plane* p = (plane*) arg; //pthread_mutex_lock(p->p_lock); pthread_cond_wait(p->cond, p->p_lock); pthread_sleep(2*t); FILE* f; f=fopen(filename, "a"); fprintf(f, " %d\t E\t\t %ld\t\t %ld\t\t %ld\n", p->ID, p->arrival_time, time(NULL)-begtime, (time(NULL)-begtime)-p->arrival_time); fclose(f); printf("EMERGENCY Landing plane with ID: %d landed at t: %ld\n", p->ID, time(NULL)-begtime); pthread_cond_signal(p->cond); pthread_mutex_unlock(p->p_lock); pthread_exit(0); }
void *print_queue (void* arg){ // Prints the current snapshot of both landing and departing queues while(time(NULL)<=begtime+simtime){ // If at second t a planes send request, we don't show that plane in if(time(NULL)-begtime >= n){ // that time's queue. If a plane is created at second t, that plane is queue_element* lelement = Landing_Queue->first; // included in that time's queue. THIS IS OUR ASSUMPTION queue_element* telement = TakeOff_Queue->first; printf("Current Landing Queue: ["); while(lelement != NULL){ printf(" %d ", lelement->now->ID); lelement=lelement->next; } printf("] at t: %ld\n", time(NULL)-begtime); printf("Current TakeOff Queue: ["); while(telement != NULL){ printf(" %d ", telement->now->ID); telement=telement->next; } printf("] at t: %ld\n", time(NULL)-begtime); } pthread_sleep(t); } pthread_exit(0); }
// session expiration timer thread void * session_expiration_timer(void * opt) { u32_t current_dtn_time; struct timeval current_time; session_t * session, * next; while(1) { pthread_sleep(5); current_dtn_time = get_current_dtn_time(); gettimeofday(¤t_time, NULL); pthread_mutex_lock(&mutexdata); for(session = session_list->first; session != NULL; session = next) { next = session->next; // all status reports has been received: close session if (session->total_to_receive > 0 && session->delivered_count == session->total_to_receive) { // close monitor if dedicated if (dedicated_monitor) { kill(getpid(), SIGUSR2); } else { session_close(session_list, session); } } // stop bundle arrived but not all the status reports have arrived and the timer has expired else if (session->total_to_receive > 0 &&session->stop_arrival_time->tv_sec + session->wait_after_stop < current_time.tv_sec) { fprintf(stdout, "DTNperf monitor: Session Expired: Bundle stop arrived, but not all the status reports did\n"); // close monitor if dedicated if (dedicated_monitor) { kill(getpid(), SIGUSR2); } else { fprintf(stdout, "\tsaved log file: %s\n\n", session->full_filename); if (fclose(session->file) < 0) perror("Error closing expired file:"); session_del(session_list, session); } } // stop bundle is not yet arrived and the last bundle has expired else if (session->last_bundle_time + session->expiration < current_dtn_time) { fprintf(stdout, "DTNperf monitor: Session Expired: Bundle stop did not arrive\n"); // close monitor if dedicated if (dedicated_monitor) { kill(getpid(), SIGUSR2); } else { fprintf(stdout,"\tsaved log file: %s\n\n", session->full_filename); if (fclose(session->file) < 0) perror("Error closing expired file:"); session_del(session_list, session); } } } pthread_mutex_unlock(&mutexdata); sched_yield(); } pthread_exit(NULL); }
void * congestion_control(void * opt) { dtnperf_options_t *perf_opt = ((dtnperf_global_options_t *)(opt))->perf_opt; boolean_t debug = perf_opt->debug; int debug_level = perf_opt->debug_level; boolean_t create_log = perf_opt->create_log; bp_timestamp_t reported_timestamp; bp_endpoint_id_t ack_sender; HEADER_TYPE ack_header; bp_copy_eid(&ack_sender, &dest_eid); struct timeval temp; int position = -1; if (debug && debug_level > 0) printf("[debug cong crtl] congestion control = %c\n", perf_opt->congestion_ctrl); if (perf_opt->congestion_ctrl == 'w') // window based congestion control { bp_bundle_create(&ack); while ((close_ack_receiver == 0) || (gettimeofday(&temp, NULL) == 0 && ack_recvd.tv_sec - temp.tv_sec <= perf_opt->wait_before_exit)) { // if there are no bundles without ack, wait pthread_mutex_lock(&mutexdata); if (close_ack_receiver == 0 && count_info(send_info, perf_opt->window) == 0) { pthread_cond_wait(&cond_ackreceiver, &mutexdata); pthread_mutex_unlock(&mutexdata); // pthread_yield(); sched_yield(); continue; } // Wait for the reply if ((debug) && (debug_level > 0)) printf("\t[debug cong crtl] waiting for the reply...\n"); if ((error = bp_bundle_receive(handle, ack, BP_PAYLOAD_MEM, count_info(send_info, perf_opt->window) == 0 ? perf_opt->wait_before_exit : -1)) != BP_SUCCESS) { if(count_info(send_info, perf_opt->window) == 0 && close_ack_receiver == 1) // send_bundles is terminated break; fprintf(stderr, "error getting server ack: %d (%s)\n", error, bp_strerror(bp_errno(handle))); if (create_log) fprintf(log_file, "error getting server ack: %d (%s)\n", error, bp_strerror(bp_errno(handle))); client_clean_exit(1); } // Check if is actually a server ack bundle get_bundle_header_and_options(&ack, &ack_header, NULL); if (ack_header != DSA_HEADER) { fprintf(stderr, "error getting server ack: wrong bundle header\n"); if (create_log) fprintf(log_file, "error getting server ack: wrong bundle header\n"); pthread_mutex_unlock(&mutexdata); //pthread_yield(); sched_yield(); continue; } gettimeofday(&ack_recvd, NULL); if ((debug) && (debug_level > 0)) printf("\t[debug cong crtl] ack received\n"); // Get ack infos error = get_info_from_ack(&ack, NULL, &reported_timestamp); if (error != BP_SUCCESS) { fprintf(stderr, "error getting info from ack: %s\n", bp_strerror(error)); if (create_log) fprintf(log_file, "error getting info from ack: %s\n", bp_strerror(error)); client_clean_exit(1); } if ((debug) && (debug_level > 1)) printf("\t[debug cong crtl] ack received timestamp: %lu %lu\n", reported_timestamp.secs, reported_timestamp.seqno); position = is_in_info(send_info, reported_timestamp, perf_opt->window); if (position < 0) { fprintf(stderr, "error removing bundle info\n"); if (create_log) fprintf(log_file, "error removing bundle info\n"); client_clean_exit(1); } remove_from_info(send_info, position); if ((debug) && (debug_level > 0)) printf("\t[debug cong crtl] ack validated\n"); sem_post(&window); if ((debug) && (debug_level > 1)) { int cur; sem_getvalue(&window, &cur); printf("\t[debug cong crtl] window is %d\n", cur); } pthread_mutex_unlock(&mutexdata); //pthread_yield(); sched_yield(); } // end while(n_bundles) bp_bundle_free(&ack); } else if (perf_opt->congestion_ctrl == 'r') // Rate based congestion control { double interval_secs; if (perf_opt->rate_unit == 'b') // rate is bundles per second { interval_secs = 1.0 / perf_opt->rate; } else // rate is bit or kbit per second { if (perf_opt->rate_unit == 'k') // Rate is kbit per second { perf_opt->rate = kilo2byte(perf_opt->rate); } else // rate is Mbit per second { perf_opt->rate = mega2byte(perf_opt->rate); } interval_secs = (double)perf_opt->bundle_payload * 8 / perf_opt->rate; } if (debug) printf("[debug cong crtl] wait time for each bundle: %.4f sec\n", interval_secs); pthread_mutex_lock(&mutexdata); while(close_ack_receiver == 0) { pthread_mutex_unlock(&mutexdata); sem_post(&window); //pthread_yield(); sched_yield(); if (debug && debug_level > 0) printf("[debug cong crtl] increased window size\n"); pthread_sleep(interval_secs); pthread_mutex_lock(&mutexdata); } } else // wrong char for congestion control { client_clean_exit(1); } pthread_exit(NULL); return NULL; }
int main(int argc, char **argv){ // Initially we created two planes one for landing (thy) and one for departing (pegasus) int i; for(i=0; i<argc; i++){ if(strncmp(argv[i], "-s", 3)==0){ simtime= strtol(argv[i+1], NULL, 10); } if(strncmp(argv[i], "-p", 3)==0){ prob = strtod(argv[i+1], NULL); } if(strncmp(argv[i], "-n", 3)==0){ n = strtol(argv[i+1], NULL, 10); } } srand(3); begtime = time(NULL); int odds=1; int evens=0; pthread_t* atc = (pthread_t*)malloc(sizeof(pthread_t)); // We created 3 threads for air traffic control, landing and departing pthread_t* land = (pthread_t*)malloc(sizeof(pthread_t)); pthread_t* depart = (pthread_t*)malloc(sizeof(pthread_t)); pthread_t* printQueue = (pthread_t*)malloc(sizeof(pthread_t)); pthread_cond_t* pegasus_cond = (pthread_cond_t*)malloc(sizeof(pthread_cond_t)); pthread_cond_t* thy_cond = (pthread_cond_t*)malloc(sizeof(pthread_cond_t)); pthread_mutex_t* pegasus_mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t)); pthread_mutex_t* thy_mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t)); pthread_cond_init(pegasus_cond, NULL); pthread_cond_init(thy_cond, NULL); pthread_mutex_init(pegasus_mutex, NULL); // Initializations of planes and queues pthread_mutex_init(thy_mutex, NULL); atc_main_lock = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t)); atc_main_cond = (pthread_cond_t*)malloc(sizeof(pthread_cond_t)); pthread_cond_init(atc_main_cond, NULL); pthread_mutex_init(atc_main_lock, NULL); FILE* f; f=fopen(filename, "w"); fprintf(f, "PlaneID\t Status\t Request Time\t Runway Time\t Turnaround Time\t\n"); fclose(f); plane* pegasus = (plane*)malloc(sizeof(plane)); plane* thy = (plane*)malloc(sizeof(plane)); pegasus->ID =0; pegasus->arrival_time = time(NULL)-begtime; pegasus->cond = pegasus_cond; pegasus->p_lock=pegasus_mutex; thy->ID=1; thy->arrival_time = time(NULL)-begtime; thy->cond = thy_cond; thy->p_lock=thy_mutex; Landing_Queue = createQueue(); TakeOff_Queue = createQueue(); Emergency_Queue = createQueue(); put(Landing_Queue, thy); put(TakeOff_Queue, pegasus); printf("INITIAL:New departing plane is created with ID: %d at t: %ld\n", pegasus->ID, pegasus->arrival_time); printf("INITIAL:New landing plane is created with ID: %d at t: %ld\n", thy->ID, thy->arrival_time); pthread_create(land, NULL, landing, (void*) (Landing_Queue->first)->now); pthread_create(depart, NULL, departing, (void*) (TakeOff_Queue->first)->now); pthread_create(atc, NULL, air_traffic_control, NULL); pthread_create(printQueue, NULL, print_queue, NULL); //pthread_create(printQueue, NULL, print_queue, (void*) TakeOff_Queue->first); while(time(NULL)<= begtime+simtime){ pthread_sleep(t); // Tower sleeps for t seconds not to perform any other operations while new planes are arriving double a = (double)rand()/RAND_MAX; // If the chance of an incoming landing plane is less than or equal to the if(a<=prob){ // probability of creating a new landing plane, then a new landing plane will be created pthread_t* new_thread = (pthread_t*)malloc(sizeof(pthread_t)); pthread_cond_t* new_cond = (pthread_cond_t*)malloc(sizeof(pthread_cond_t)); pthread_mutex_t* new_mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t)); pthread_cond_init(new_cond, NULL); pthread_mutex_init(new_mutex, NULL); plane* new_p = (plane*)malloc(sizeof(plane)); new_p->ID =odds + 2; new_p->arrival_time = time(NULL)-begtime; new_p->cond = new_cond; new_p->p_lock=new_mutex; put(Landing_Queue, new_p); // Since the new plane is a landing one, we add this to the end of the landing queue odds=odds+2; printf("New landing plane is created with ID: %d at t: %ld\n", new_p->ID, new_p->arrival_time); pthread_create(new_thread, NULL, landing, (void*) new_p); } double b = (double)rand()/RAND_MAX; // If the chance of an incoming departing plane is less than or equal to the if(b<(1-prob)){ // probability of creating a new departing plane, then a new departing plane will be created pthread_t* new_thread = (pthread_t*)malloc(sizeof(pthread_t)); pthread_cond_t* new_cond = (pthread_cond_t*)malloc(sizeof(pthread_cond_t)); pthread_mutex_t* new_mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t)); pthread_cond_init(new_cond, NULL); pthread_mutex_init(new_mutex, NULL); plane* new_p = (plane*)malloc(sizeof(plane)); new_p->ID =evens + 2; new_p->arrival_time = time(NULL)-begtime; new_p->cond = new_cond; new_p->p_lock=new_mutex; put(TakeOff_Queue, new_p); // Since the new plane is a departing one, we add this to the end of the takeoff queue evens=evens+2; printf("New takeoff plane is created with ID: %d at t: %ld\n", new_p->ID, new_p->arrival_time); pthread_create(new_thread, NULL, departing, (void*) new_p); } if((time(NULL)-begtime)%(40*t)==0){ pthread_t* new_thread = (pthread_t*)malloc(sizeof(pthread_t)); pthread_cond_t* new_cond = (pthread_cond_t*)malloc(sizeof(pthread_cond_t)); pthread_mutex_t* new_mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t)); pthread_cond_init(new_cond, NULL); pthread_mutex_init(new_mutex, NULL); plane* new_p = (plane*)malloc(sizeof(plane)); new_p->ID =odds + 2; new_p->arrival_time = time(NULL)-begtime; new_p->cond = new_cond; new_p->p_lock=new_mutex; put(Emergency_Queue, new_p); // Every 40t seconds an emergency plane appears and plane is put into the emergency queue odds=odds+2; printf("EMERGENCY landing plane is appeared with ID: %d at t: %ld !!!\n", new_p->ID, new_p->arrival_time); pthread_create(new_thread, NULL, emergency_landing, (void*) new_p); } pthread_cond_signal(atc_main_cond); //pthread_mutex_lock(atc_main_lock); //pthread_cond_wait(atc_main_cond, atc_main_lock); pthread_mutex_unlock(atc_main_lock); } printf("End of simulation\n"); return 0; }