Пример #1
0
static void execute_processing_request(SERVER_lp_state_type *pointer, time_type now, event_content_type *event_content) {
	double cpu_service_time = Expent(get_cpu_service_demand(pointer, event_content));
	ScheduleNewEvent(pointer->server_id, now + cpu_service_time, CPU_PROCESSING_REQUEST_EXECUTED, event_content, sizeof(event_content_type));
	ScheduleNewEvent(pointer->server_id, now + cpu_service_time, event_content->applicative_content.op_type, event_content, sizeof(event_content_type));
	if (pointer->configuration.server_verbose) {
		("cpu%d - event CPU_PROCESSING_REQUEST_EXECUTED sent to server at time %f\n", pointer->server_id, now + cpu_service_time);
	}
}
int acquire_a_local_lock(state_type *state, time_type timeout, int timeout_event_type, event_content_type *event_content, double now) {
	SERVER_lp_state_type *pointer = &state->type.server_state;
	if (pointer->configuration.cc_verbose)
		printf("cc%d - oggetto %d per la transizione %i da lockare\n", pointer->server_id, event_content->applicative_content.object_key_id, event_content->applicative_content.tx_id);
	//check lock...
	if (pointer->cc_metadata->locks[event_content->applicative_content.object_key_id] == -1) {
		//not locked
		pointer->cc_metadata->lock_retry_num = 0;
		//acquire lock
		pointer->cc_metadata->locks[event_content->applicative_content.object_key_id] = event_content->applicative_content.tx_id;
		if (pointer->configuration.cc_verbose)
			printf("cc%d - oggetto %d per la transizione %i lockato al tempo %f \n", pointer->server_id, event_content->applicative_content.object_key_id, event_content->applicative_content.tx_id,
					now);
		return 1;
	} else if (pointer->cc_metadata->locks[event_content->applicative_content.object_key_id] == event_content->applicative_content.tx_id) {
		// already locked by me
		return 1;
	} else {
		//already locked by another transaction
		pointer->cc_metadata->lock_retry_num++;
		//check deadlocks (if enabled)
		if (pointer->configuration.deadlock_detection_enabled && check_deadlock(event_content, pointer)) {
			return -1;
		}

		//add the timeout event
		event_content_type new_event_content;
		memcpy(&new_event_content, event_content, sizeof(event_content_type));
		ScheduleNewEvent(pointer->server_id, now + timeout, timeout_event_type, &new_event_content, sizeof(event_content_type));

		//enqueue event
		memcpy(&new_event_content, event_content, sizeof(event_content_type));
		new_event_content.applicative_content.object_key_id = event_content->applicative_content.object_key_id;
		enqueue_event(pointer, &new_event_content);

		transaction_metadata *transaction = get_transaction_metadata(event_content->applicative_content.tx_id, pointer);
		if (transaction == NULL) {
			if (pointer->configuration.cc_verbose) {
				printf("cc%d - la tx %i non è locale\n", pointer->server_id, event_content->applicative_content.tx_id);
				printf("cc%d - prepare of tx %i added in the waiting event queue %f due to a lock on object :%d tx:%i\n", pointer->server_id, event_content->applicative_content.tx_id, now,
						event_content->applicative_content.object_key_id, new_event_content.applicative_content.tx_id);
			}
			return 0;
		} else {
			transaction->is_blocked = 1;
			if (pointer->configuration.cc_verbose)
				printf("cc%d - tx %i is waiting at time %f due to a lock lock on object :%d tx:%i\n", pointer->server_id, event_content->applicative_content.tx_id, now,
						event_content->applicative_content.object_key_id, new_event_content.applicative_content.tx_id);
			return 0;
		}
	}
}
static void reschedule_event(state_type *state, double now, int object_key_id) {

	SERVER_lp_state_type *pointer = &state->type.server_state;
	event_content_type *event_content = NULL;

	do {
		event_content = get_next_event_waiting_for_object_key(state, CC_QUEUE, object_key_id);
		if (event_content != NULL) {
			transaction_metadata *transaction = get_transaction_metadata(event_content->applicative_content.tx_id, pointer);
			if (transaction != NULL)
				transaction->is_blocked = 0;
			ScheduleNewEvent(pointer->server_id, now, DELIVER_MESSAGE, event_content, sizeof(event_content_type));
			if (pointer->configuration.cc_verbose)
				printf("cc - Funzione reschedule_event: reinviato evento %d (op %d della txn %d) a server %d al tempo %f\n", event_content->applicative_content.op_type,
						event_content->applicative_content.op_number, event_content->applicative_content.tx_id, event_content->applicative_content.server_id, now);
			remove_event_of_tx(pointer->cc_metadata->event_queue, event_content->applicative_content.tx_id);
		}
	} while (event_content != NULL);
}
Пример #4
0
void ProcessEvent(unsigned int me, simtime_t now, int event_type, void *event, size_t size, lp_state_type *state) {
	simtime_t timestamp = 0;
	event_content_type new_event;
	int receiver;
	int i;
	car_t *car;
	
	event_content_type *event_content = (event_content_type *)event;
	
	(void)size;

	if(state != NULL) {
		state->lvt = now;
	}
	
	switch(event_type) {

		// This event initializes the simulation state for each LP and inject first events
		case INIT:
			state = malloc(sizeof(lp_state_type));
			if(state == NULL){
				fprintf(stderr, "ERROR: Unable to allocate simulation state!\n");
				fflush(stderr);
				exit(EXIT_FAILURE);
			}

			SetState(state);

			// Initialize state
			bzero(state, sizeof(lp_state_type));

			// Parse the topology file and set state accordingly
			init_my_state(me, state);

			// Set the number of queuable cars in this node
			if(state->lp_type == JUNCTION) {
				state->total_queue_slots = CARS_PER_JUNCTION;
			} else if(state->lp_type == SEGMENT) {
				state->total_queue_slots = (int)(state->segment_length * CARS_PER_UNIT_LENGTH);
			}

			// Set the number of cars in the current node at the beginning of the simulation
			if(state->lp_type == JUNCTION) {
				inject_new_cars(state, me);
			}
			
			// Schedule a keep alive event
			timestamp = now + Expent(10);
			ScheduleNewEvent(me, timestamp, KEEP_ALIVE, NULL, 0);
			
			break;



		case ARRIVAL:

			if(!event_content->injection && check_car_leaving(state, event_content->from, me)) {
				break;
			}
		
			if(state->queued_elements < state->total_queue_slots) {

				car = enqueue_car(me, event_content->from, state);

				// Send a leave event
				ScheduleNewEvent(me, car->leave, LEAVE, &car->car_id, sizeof(unsigned long long));
			} else {
				printf("Object queue full\n");
			}

			cause_accident(state, me);

			// If the arrival is related to a new car entering the highway, schedule
			// the next car entering
			if(event_content->injection && state->lp_type == JUNCTION) {
				inject_new_cars(state, me);
			}
			
			break;


		case LEAVE: 
			
			car = car_dequeue(me, state, (unsigned long long *)event);
			if(car != NULL) {
				new_event.from = me;
				new_event.injection = false;
				
				if(state->topology->num_neighbours > 1) {
					do {
						receiver = RandomRange(0, state->topology->num_neighbours - 1);
						receiver = state->topology->neighbours[receiver];
					} while(receiver == car->from);				
				} else {
					receiver = state->topology->neighbours[0];
				}
				
				ScheduleNewEvent(receiver, car->leave, ARRIVAL, &new_event, sizeof(event_content_type));
				free(car);
			} else {
				timestamp = now + Expent(ACCIDENT_LEAVE_TIME);
				update_car_leave(state, *(unsigned long long *)event_content, timestamp);
				ScheduleNewEvent(me, timestamp, LEAVE, (unsigned long long *)event_content, sizeof(unsigned long long));
			}
			
			break;
			

		case FINISH_ACCIDENT:
			state->accident = false;
			release_cars(me, state);
			break;


		case KEEP_ALIVE:
			determine_stop(state);
			timestamp = now + Expent(10);
			ScheduleNewEvent(me, timestamp, KEEP_ALIVE, NULL, 0);
			break;

      		default:
			printf(" state simulation: error - inconsistent event (me = %d - event type = %d)\n",me,event_type);
			break;
	}
}
int acquire_local_locks(state_type *state, data_set_entry *data_set, time_type timeout, int timeout_event_type, event_content_type *event_content, double now) {
	SERVER_lp_state_type *pointer = &state->type.server_state;
	data_set_entry *entry = data_set;
	if (entry == NULL) {
		if (pointer->configuration.cc_verbose)
			printf("cc%d -  write set of transaction %d is empty\n", pointer->server_id, event_content->applicative_content.tx_id);
		return 1;
	}
	while (entry != NULL) {
		int need_to_lock = 0;
		if (pointer->configuration.concurrency_control_type == ETL_2PL || pointer->configuration.concurrency_control_type == CTL_2PL)
			need_to_lock = is_owner(entry->object_key_id, pointer->server_id, state->num_servers, state->num_clients, state->object_replication_degree);
		else if (pointer->configuration.concurrency_control_type == PRIMARY_OWNER_CTL_2PL)
			need_to_lock = is_primary(entry->object_key_id, pointer->server_id, state->num_servers, state->num_clients);
		if (need_to_lock) {
			if (pointer->configuration.cc_verbose)
				printf("cc%d - object %d for transaction %i to be locked\n", pointer->server_id, entry->object_key_id, event_content->applicative_content.tx_id);
			//check lock...
			if (pointer->cc_metadata->locks[entry->object_key_id] == -1) {
				//not locked
				pointer->cc_metadata->lock_retry_num = 0;
				//acquire lock
				pointer->cc_metadata->locks[entry->object_key_id] = event_content->applicative_content.tx_id;
				if (pointer->configuration.cc_verbose)
					printf("cc%d - pbject %d  for transaction  %i locked at time %f \n", pointer->server_id, entry->object_key_id, event_content->applicative_content.tx_id, now);
			} else if (pointer->cc_metadata->locks[entry->object_key_id] == event_content->applicative_content.tx_id) {
				// already locked by me
				// go to the next entry
			} else {
				//already locked by another transaction
				pointer->cc_metadata->lock_retry_num++;
				//check deadlock (if enabled)
				if (pointer->configuration.deadlock_detection_enabled && check_deadlock(event_content, pointer)) {
					return -1;
				}
				//add the timeout event
				event_content_type new_event_content;
				memcpy(&new_event_content, event_content, sizeof(event_content_type));
				ScheduleNewEvent(pointer->server_id, now + timeout, timeout_event_type, &new_event_content, sizeof(event_content_type));

				//enqueue transaction
				memcpy(&new_event_content, event_content, sizeof(event_content_type));
				new_event_content.applicative_content.object_key_id = entry->object_key_id;
				enqueue_event(pointer, &new_event_content);

				transaction_metadata *transaction = get_transaction_metadata(event_content->applicative_content.tx_id, pointer);
				if (transaction == NULL) {
					if (pointer->configuration.cc_verbose) {
						printf("cc%d - transaction %i is not local\n", pointer->server_id, event_content->applicative_content.tx_id);
						printf("cc%d - prepare of tx %i added in the waiting event queue %f due to a lock on object %d tx:%i\n", pointer->server_id, event_content->applicative_content.tx_id, now,
								entry->object_key_id, new_event_content.applicative_content.tx_id);
					}
					return 0;
				} else {
					transaction->is_blocked = 1;
					if (pointer->configuration.cc_verbose)
						printf("cc%d - transaction %i is waiting at time %f due to a lock on object%d tx:%i\n", pointer->server_id, event_content->applicative_content.tx_id, now, entry->object_key_id,
								new_event_content.applicative_content.tx_id);
					return 0;
				}
			}
		}
		entry = entry->next;
	}
	return 1;
}
Пример #6
0
void ProcessEvent(int me, simtime_t now, int event_type, event_content_type *event_content, int event_size, lp_state_type *pointer) {

	event_content_type new_event_content;

	new_event_content.cell = -1;
	new_event_content.new_trails = -1;

	int i;
	int receiver, TEMP;
	int trails;

	simtime_t timestamp=0;

	switch(event_type) {

		case INIT:

			pointer = (lp_state_type *)malloc(sizeof(lp_state_type));
			if(pointer == NULL){
				rootsim_error(true, "%s:%d: Unable to allocate memory!\n", __FILE__, __LINE__);
			}
			SetState(pointer);

			if(NUM_CELLE_OCCUPATE > n_prc_tot){
				rootsim_error(true, "%s:%d: Require more cell than available LPs\n", __FILE__, __LINE__);
			}

			if((NUM_CELLE_OCCUPATE % 2) == 0){
				//Occupo le "prime" e "ultime" celle
				if(me < (NUM_CELLE_OCCUPATE/2) || me >= ((n_prc_tot)-(NUM_CELLE_OCCUPATE/2))) {
					for(i = 0; i < ROBOT_PER_CELLA; i++) {
						// genero un evento di REGION_IN
						ScheduleNewEvent(me, now + (simtime_t)(20 * Random()), REGION_IN, NULL, 0);
					}
				}
			} else {
				if(me <= (NUM_CELLE_OCCUPATE / 2) || me >= ((n_prc_tot) - (NUM_CELLE_OCCUPATE / 2))){
					for(i = 0; i < ROBOT_PER_CELLA; i++){
						// genero un evento di REGION_IN
						ScheduleNewEvent(me, now + (simtime_t)(20 * Random()), REGION_IN, NULL, 0);
					}
				}
			}


			// Set the values for neighbours. If one is non valid, then set it to -1
			for(i = 0; i < 6; i++) {
				if(isValidNeighbour(me, i)) {
					pointer->neighbour_trails[i] = 0;
				} else {
					pointer->neighbour_trails[i] = -1;
				}
			}

			break;


		case REGION_IN:

			pointer->trails++;

			new_event_content.cell = me;
			new_event_content.new_trails = pointer->trails;

			for (i = 0; i < 6; i++) {
				if(pointer->neighbour_trails[i] != -1) {
					receiver = GetNeighbourId(me, i);
					if(receiver >= n_prc_tot || receiver < 0)
						printf("%s:%d: %d -> %d\n", __FILE__, __LINE__, me, receiver);
					ScheduleNewEvent(receiver, now + TIME_STEP/100000, UPDATE_NEIGHBORS, &new_event_content, sizeof(new_event_content));
				}
			}

			// genero un evento di REGION_OUT
			ScheduleNewEvent(me, now + TIME_STEP/100000, REGION_OUT, NULL, 0);

			break;


		case UPDATE_NEIGHBORS:

			for (i = 0; i < 6; i++) {
				if(event_content->cell == GetNeighbourId(me, i)) {
					pointer->neighbour_trails[i] = event_content->new_trails;
				}
			}

			break;


		case REGION_OUT:

			// Go to the neighbour who has the smallest trails count
			trails = INT_MAX;
			for(i = 0; i < 6; i++) {
				if(pointer->neighbour_trails[i] != -1) {
					if(pointer->neighbour_trails[i] < trails) {
						trails = pointer->neighbour_trails[i];
						receiver = i;
					}
				}
			}
			TEMP = receiver;
			receiver = GetNeighbourId(me, receiver);

			switch (DISTRIBUZIONE) {

				case UNIFORME:
					timestamp= now + (simtime_t) (TIME_STEP * Random());
					break;

				case ESPONENZIALE:
					timestamp= now + (simtime_t)(Expent(TIME_STEP));
					break;

				default:
					timestamp= now + (simtime_t)(TIME_STEP * Random());
		   			break;

			}

					if(receiver >= n_prc_tot || receiver < 0)
						printf("%s:%d: %d -> %d\n", __FILE__, __LINE__, me, receiver);
			ScheduleNewEvent(receiver, timestamp, REGION_IN, NULL, 0);
			break;

      		default:
			rootsim_error(true, "Error: unsupported event: %d\n", event_type);
			break;
	}
}
Пример #7
0
void ProcessEvent(unsigned int me, simtime_t now, int event_type, event_content_type *event_content, unsigned int size, void *ptr) {

    char *parameter, *value;
    channel *c;
    int w;

    event_content_type new_event_content;

    new_event_content.cell = -1;
    new_event_content.channel = -1;
    new_event_content.call_term_time = -1;

    simtime_t handoff_time;
    simtime_t timestamp = 0;

    lp_state_type *state;
    state = (lp_state_type*)ptr;

    if(state != NULL) {
        state->lvt = now;
        state->executed_events++;
    }


    switch(event_type) {

    case INIT:

        // Initialize the LP's state
        state = (lp_state_type *)malloc(sizeof(lp_state_type));
        if (state == NULL) {
            printf("Out of memory!\n");
            exit(EXIT_FAILURE);
        }

        SetState(state);

        bzero(state, sizeof(lp_state_type));
        state->channel_counter = CHANNELS_PER_CELL;

        // Read runtime parameters
        if(IsParameterPresent(event_content, "pcs_statistics"))
            pcs_statistics = true;

        if(IsParameterPresent(event_content, "ta"))
            state->ref_ta = state->ta = GetParameterDouble(event_content, "ta");
        else
            state->ref_ta = state->ta = TA;

        if(IsParameterPresent(event_content, "ta_duration"))
            state->ta_duration = GetParameterDouble(event_content, "ta_duration");
        else
            state->ta_duration = TA_DURATION;

        if(IsParameterPresent(event_content, "ta_change"))
            state->ta_change = GetParameterDouble(event_content, "ta_change");
        else
            state->ta_change = TA_CHANGE;

        if(IsParameterPresent(event_content, "channels_per_cell"))
            state->channels_per_cell = GetParameterInt(event_content, "channels_per_cell");
        else
            state->channels_per_cell = CHANNELS_PER_CELL;

        if(IsParameterPresent(event_content, "complete_calls"))
            complete_calls = GetParameterInt(event_content, "complete_calls");

        state->fading_recheck = IsParameterPresent(event_content, "fading_recheck");
        state->variable_ta = IsParameterPresent(event_content, "variable_ta");


        // Show current configuration, only once
        if(me == 0) {
            printf("CURRENT CONFIGURATION:\ncomplete calls: %d\nTA: %f\nta_duration: %f\nta_change: %f\nchannels_per_cell: %d\nfading_recheck: %d\nvariable_ta: %d\n",
                   complete_calls, state->ta, state->ta_duration, state->ta_change, state->channels_per_cell, state->fading_recheck, state->variable_ta);
            fflush(stdout);
        }

        state->channel_counter = state->channels_per_cell;

        // Setup channel state
        state->channel_state = malloc(sizeof(unsigned int) * 2 * (CHANNELS_PER_CELL / BITS + 1));
        for (w = 0; w < state->channel_counter / (sizeof(int) * 8) + 1; w++)
            state->channel_state[w] = 0;

        // Start the simulation
        timestamp = (simtime_t) (20 * Random());
        ScheduleNewEvent(me, timestamp, START_CALL, NULL, 0);

        // If needed, start the first fading recheck
//			if (state->fading_recheck) {
        timestamp = (simtime_t) (FADING_RECHECK_FREQUENCY * Random());
        ScheduleNewEvent(me, timestamp, FADING_RECHECK, NULL, 0);
//			}

        break;


    case START_CALL:

        state->arriving_calls++;

        if (state->channel_counter == 0) {
            state->blocked_on_setup++;
        } else {

            state->channel_counter--;

            new_event_content.channel = allocation(state);
            new_event_content.from = me;
            new_event_content.sent_at = now;

            // Determine call duration
            switch (DURATION_DISTRIBUTION) {

            case UNIFORM:
                new_event_content.call_term_time = now + (simtime_t)(state->ta_duration * Random());
                break;

            case EXPONENTIAL:
                new_event_content.call_term_time = now + (simtime_t)(Expent(state->ta_duration));
                break;

            default:
                new_event_content.call_term_time = now + (simtime_t) (5 * Random() );
            }

            // Determine whether the call will be handed-off or not
            switch (CELL_CHANGE_DISTRIBUTION) {

            case UNIFORM:

                handoff_time  = now + (simtime_t)((state->ta_change) * Random());
                break;

            case EXPONENTIAL:
                handoff_time = now + (simtime_t)(Expent(state->ta_change));
                break;

            default:
                handoff_time = now + (simtime_t)(5 * Random());

            }

            if(new_event_content.call_term_time <=  handoff_time) {
                ScheduleNewEvent(me, new_event_content.call_term_time, END_CALL, &new_event_content, sizeof(new_event_content));
            } else {
                new_event_content.cell = FindReceiver(TOPOLOGY_HEXAGON);
                ScheduleNewEvent(me, handoff_time, HANDOFF_LEAVE, &new_event_content, sizeof(new_event_content));
            }
        }


        if (state->variable_ta)
            state->ta = recompute_ta(state->ref_ta, now);

        // Determine the time at which a new call will be issued
        switch (DISTRIBUTION) {

        case UNIFORM:
            timestamp= now + (simtime_t)(state->ta * Random());
            break;

        case EXPONENTIAL:
            timestamp= now + (simtime_t)(Expent(state->ta));
            break;

        default:
            timestamp= now + (simtime_t) (5 * Random());

        }

        ScheduleNewEvent(me, timestamp, START_CALL, NULL, 0);

        break;

    case END_CALL:

        state->channel_counter++;
        state->complete_calls++;
        deallocation(me, state, event_content->channel, event_content, now);

        break;

    case HANDOFF_LEAVE:

        state->channel_counter++;
        state->leaving_handoffs++;
        deallocation(me, state, event_content->channel, event_content, now);

        new_event_content.call_term_time =  event_content->call_term_time;
        ScheduleNewEvent(event_content->cell, now, HANDOFF_RECV, &new_event_content, sizeof(new_event_content));
        break;

    case HANDOFF_RECV:
        state->arriving_handoffs++;
        state->arriving_calls++;

        if (state->channel_counter == 0)
            state->blocked_on_handoff++;
        else {
            state->channel_counter--;

            new_event_content.channel = allocation(state);
            new_event_content.call_term_time = event_content->call_term_time;

            switch (CELL_CHANGE_DISTRIBUTION) {
            case UNIFORM:
                handoff_time  = now + (simtime_t)((state->ta_change) * Random());

                break;
            case EXPONENTIAL:
                handoff_time = now + (simtime_t)(Expent( state->ta_change ));

                break;
            default:
                handoff_time = now+
                               (simtime_t) (5 * Random());
            }

            if(new_event_content.call_term_time < handoff_time ) {
                ScheduleNewEvent(me, new_event_content.call_term_time, END_CALL, &new_event_content, sizeof(new_event_content));
            } else {
                new_event_content.cell = FindReceiver(TOPOLOGY_HEXAGON);
                ScheduleNewEvent(me, handoff_time, HANDOFF_LEAVE, &new_event_content, sizeof(new_event_content));
            }
        }


        break;


    case FADING_RECHECK:

        /*
        			if(state->check_fading)
        				state->check_fading = false;
        			else
        				state->check_fading = true;
        */

        fading_recheck(state);

        timestamp = now + (simtime_t) (FADING_RECHECK_FREQUENCY );
        ScheduleNewEvent(me, timestamp, FADING_RECHECK, NULL, 0);

        break;


    default:
        fprintf(stdout, "PCS: Unknown event type! (me = %d - event type = %d)\n", me, event_type);
        abort();

    }
}
Пример #8
0
void ProcessEvent(unsigned int me, simtime_t now, int event_type, event_content_type *event_content, unsigned int size, void * ptr) {
	int w;

	event_content_type new_event_content;

	new_event_content.cell = -1;
	new_event_content.second_cell = -1;
	new_event_content.channel = -1;
	new_event_content.call_term_time = -1;
	
	simtime_t handoff_time;
	simtime_t timestamp=0;
	
	lp_state_type * pointer;
	pointer = (lp_state_type*)ptr;

	switch(event_type) {
		
		case INIT:
		
			pointer = (lp_state_type *)malloc(sizeof(lp_state_type));
			if (pointer == NULL){
				printf("ERROR in malloc!\n");
				exit(EXIT_FAILURE);
			}

		
			SetState(pointer);
			
//			pointer->channels = NULL;
			pointer->contatore_canali = CHANNELS_PER_CELL;
			pointer->cont_chiamate_entranti = -1;
			pointer->cont_chiamate_complete = 0;
			pointer->cont_handoff_uscita = 0;
			pointer->cont_bloccate_in_partenza = 0;
			pointer->cont_bloccate_in_handoff  = 0;
			pointer->handoffs_entranti = 0;
//			power_management = true;
//			variable_ta = true;
//			fading_recheck = true;

			// INIT is not considered as an event
			pointer->contatore_eventi = 0;
//			pointer->time = now;


			// Load the predefined values
//			variable_ta = true;
			complete_calls = COMPLETE_CALLS;
			ta = TA;
			ta_durata = TA_DURATA;
			ta_cambio = TA_CAMBIO;
			channels_per_cell = CHANNELS_PER_CELL;
			power_management = true;

			// Read runtime parameters
			char **arguments = (char **)event_content;
			for(w = 0; w < size; w += 2) {

				if(strcmp(arguments[w],"complete-calls") == 0) {
					complete_calls = parseInt(arguments[w + 1]);
				} else if(strcmp(arguments[w],"ta") == 0) {
					ta = parseDouble(arguments[w + 1]);
				} else if(strcmp(arguments[w],"ta-durata") == 0) {
					ta_durata = parseDouble(arguments[w + 1]);
				} else if(strcmp(arguments[w],"ta-cambio") == 0) {
					ta_cambio = parseDouble(arguments[w + 1]);
				} else if(strcmp(arguments[w],"channels-per-cell") == 0) {
					channels_per_cell = parseInt(arguments[w + 1]);
				} else if(strcmp(arguments[w],"complete-time") == 0) {
					complete_time = parseInt(arguments[w + 1]);
				} else if(strcmp(arguments[w],"no-power-management") == 0) {
					w -= 1;
					power_management = false;
				} else if(strcmp(arguments[w],"power-management") == 0) {
					w -= 1;
					power_management = true;
				} else if(strcmp(arguments[w],"variable-ta") == 0) {
					w -= 1;
					variable_ta = true;
				} else if(strcmp(arguments[w],"fading-recheck") == 0) {
					fading_recheck = true;
				} else if(strcmp(arguments[w],"complete-time") == 0) {
					complete_time = parseInt(arguments[w + 1]);
				}
			}
			ref_ta = ta;

			// Show current configuration, only once
			if(me == 0) {
				printf("CURRENT CONFIGURATION:\nCOMPLETE CALLS: %d\nTA: %f\nTA_DURATA: %f\nTA_CAMBIO: %f\nCHANNELS_PER_CELL: %d\nCOMPLETE_TIME: %d\n",
					complete_calls, ta, ta_durata, ta_cambio, channels_per_cell, complete_time);
				printf("POWER MANAGMENT: %d\nFADING RECHECK: %d\nVARIABLE TA: %d\n",
					power_management, fading_recheck, variable_ta);
				fflush(stdout);
			}

			pointer->contatore_canali = channels_per_cell;

			for (w = 0; w < pointer->contatore_canali / (sizeof(int) * 8) + 1; w++)
				pointer->channel_state[w] = 0;
			
			pointer->buff_topology = (_PCS_routing*)malloc(sizeof(_PCS_routing));
			if(pointer->buff_topology == NULL){
				printf("Chiamata a malloc errata sulla topologia della rete!\n");
				exit(EXIT_FAILURE);
			}
	
			set_my_topology(me, pointer->buff_topology);

			timestamp = (simtime_t) (20 * Random());	
			ScheduleNewEvent(me, timestamp, START_CALL, NULL, 0);
			
			if (fading_recheck) {
				timestamp = now + (simtime_t) (FADING_RECHECK_FREQUENCY); 
				ScheduleNewEvent(me, timestamp, FADING_RECHECK, NULL, 0);
			}

			break;

	
		case START_CALL:
			pointer->time = now;
			

			//make_copy(pointer->cont_chiamate_entranti, pointer->cont_chiamate_entranti+1);
			pointer->cont_chiamate_entranti++;
			//make_copy(pointer->contatore_eventi, pointer->contatore_eventi+1);
			pointer->contatore_eventi++;
			
			if (pointer->contatore_canali == 0) {
				//make_copy(pointer->cont_bloccate_in_partenza, pointer->cont_bloccate_in_partenza+1);
				pointer->cont_bloccate_in_partenza++;
			} else {
						
				pointer->contatore_canali--;
				//make_copy(pointer->contatore_canali, pointer->contatore_canali-1);
				
				#ifdef ACCURATE_SIMULATION
				new_event_content.channel = allocation(me, pointer);
				#endif
				
				// Determine call duration
				switch (DISTRIBUZIONE_DURATA) {
	
					case UNIFORME:
						new_event_content.call_term_time = now+
			       			(simtime_t) (ta_durata * Random());

						break;

					case ESPONENZIALE:
						new_event_content.call_term_time = now +
 						(simtime_t)( Expent(ta_durata ));

						break;

					default:
								
 						new_event_content.call_term_time = now+
						(simtime_t) (5 * Random() );	
						}
			
				// Determine whether the call will be handed-off or not
				switch (DISTRIBUZIONE_CAMBIOCELLA) {

					case UNIFORME:
						
						handoff_time  = now+ 
			       			(simtime_t) ((ta_cambio) * Random() );
						break;

					case ESPONENZIALE:
						handoff_time = now+ 
			       			(simtime_t)( Expent( ta_cambio ));
						break;

					default:
						handoff_time = now+ 
			       			(simtime_t) (5 * Random() );
					
				}
			
				if( new_event_content.call_term_time <=  handoff_time) {
				    ScheduleNewEvent(me,new_event_content.call_term_time,END_CALL,&new_event_content,sizeof(new_event_content));

				} else {
					new_event_content.cell = __FindReceiver(me,pointer);
							
					new_event_content.second_cell = -1;
			
					ScheduleNewEvent(me,handoff_time,HANDOFF_LEAVE,&new_event_content,sizeof(new_event_content));

//					#ifdef PRE_SCHEDULING
					new_event_content.call_term_time = new_event_content.call_term_time;
					ScheduleNewEvent(new_event_content.cell,handoff_time,HANDOFF_RECV,&new_event_content,sizeof(new_event_content));
//					#endif
				}
			} // if (pointer->contatore_canali == 0) 


			if (variable_ta)
				ta = recompute_ta(ref_ta, now);

			// Determine the time at which the call will end						
			switch (DISTRIBUZIONE) {   

				case UNIFORME:
					timestamp= now+ 
			   		(simtime_t) (ta * Random() );
					break;
	
				case ESPONENZIALE:
					timestamp= now+ 
			   		(simtime_t)( Expent( ta ));
					break;

				default:
					timestamp= now+	
			   		(simtime_t) (5 * Random());		
						
			}

			ScheduleNewEvent(me, timestamp, START_CALL, NULL, 0);

			break;

		case END_CALL:
		
			pointer->time = now;
//			make_copy(pointer->contatore_eventi, pointer->contatore_eventi+1);
			pointer->contatore_eventi++;
			//make_copy(pointer->contatore_canali, pointer->contatore_canali+1);
			pointer->contatore_canali++;
			//make_copy(pointer->cont_chiamate_complete, pointer->cont_chiamate_complete+1);
			pointer->cont_chiamate_complete++;
			#ifdef ACCURATE_SIMULATION
			deallocation(me, pointer, event_content->channel);
			#endif
			
			break;

		case HANDOFF_LEAVE:

			pointer->time = now;
			//make_copy(pointer->contatore_eventi, pointer->contatore_eventi+1);
			pointer->contatore_eventi++;
			//make_copy(pointer->contatore_canali, pointer->contatore_canali+1);
			pointer->contatore_canali++;
			//make_copy(pointer->cont_handoff_uscita, pointer->cont_handoff_uscita+1);
			pointer->cont_handoff_uscita++;
			#ifdef ACCURATE_SIMULATION
			deallocation(me, pointer, event_content->channel);
			#endif
			
//			#ifndef PRE_SCHEDULING
//			new_event_content.call_term_time =  event_content->call_term_time + 0.00005;
//			ScheduleNewEvent(event_content->cell, now + 0.00003 , HANDOFF_RECV, &new_event_content, sizeof(new_event_content));
//			#endif
			break;

        	case HANDOFF_RECV:
			pointer->time = now;
			//handoff_counter++;
			//make_copy(pointer->handoffs_entranti, pointer->handoffs_entranti+1);
			pointer->handoffs_entranti++;
			//make_copy(pointer->cont_chiamate_entranti, pointer->cont_chiamate_entranti+1);
			//make_copy(pointer->contatore_eventi, pointer->contatore_eventi+1);
			pointer->contatore_eventi++;
			pointer->cont_chiamate_entranti++;
			
			if (pointer->contatore_canali == 0) 
				//make_copy(pointer->cont_bloccate_in_handoff, pointer->cont_bloccate_in_handoff+1);
				pointer->cont_bloccate_in_handoff++;
			else {
				//make_copy(pointer->contatore_canali, pointer->contatore_canali-1);
				pointer->contatore_canali--;
				
				#ifdef ACCURATE_SIMULATION
				new_event_content.channel = allocation(me, pointer);
				#endif
				
				new_event_content.call_term_time = event_content->call_term_time; 
				
				switch (DISTRIBUZIONE_CAMBIOCELLA) {
					case UNIFORME:
						handoff_time  = now+ 
			    			(simtime_t) ((ta_cambio) * Random());
			
						break;
					case ESPONENZIALE:
						handoff_time = now+ 
			    			(simtime_t)( Expent( ta_cambio ));
			
						break;
					default:
						handoff_time = now+ 
			    			(simtime_t) (5 * Random());
				}
				
				
				if (Random() < 0.5) handoff_time *= 10;
				
				if( new_event_content.call_term_time <=  handoff_time ) {
					ScheduleNewEvent(me , new_event_content.call_term_time, END_CALL, &new_event_content, sizeof(new_event_content));


				} else {
					new_event_content.cell = __FindReceiver(me,ptr);
					
					#ifdef  NO_UNCERTAINTY
						new_event_content.second_cell = -1;
					#endif
					ScheduleNewEvent(me , new_event_content.call_term_time, HANDOFF_LEAVE, &new_event_content, sizeof(new_event_content));

				}
			}
			

			break;


		case FADING_RECHECK:

//			pointer->time = now;
			if (pointer->check_fading == true) {
				//make_copy(pointer->check_fading, false);
				pointer->check_fading = false;
			} else {
				//make_copy(pointer->check_fading, true);
				pointer->check_fading = true;
			}

			timestamp = now + (simtime_t) (FADING_RECHECK_FREQUENCY);
			ScheduleNewEvent(me, timestamp, FADING_RECHECK, NULL, 0);
				
			break;

      		default: 
			fprintf(stderr, " pointer simulation: error - inconsistent event (me = %d - event type = %d)\n", me, event_type);
			break;
	} // switch(event->type) 
}