// 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);
}	
示例#5
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(&current_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);
}
示例#6
0
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;
}