Network Packet Processing Simulation
I am doing a certification course on Coursera. And two days before I came across this question.
Question: Implement network packet processing simulation.
Programming Language: I have written using C. You can prefer whichever you are comfortable with.
Description: You'll have a buffer memory and a list of instruction. Arrival time and processing time will be provided for each instruction. You have a processor which can process a single instruction at a time. So you have to find out the process start time for each instruction.
Note: If you are interested and would like to solve this question, mail me here (debasishiter@gmail.com). I will forward you the complete question.
It's not challenging or difficult but it's interesting. You might come up with a simpler solution compare to mine.
Spoiler Alert!!! Find my solution below.
/*****************************************************
Implementation of newtork processing simulation
Coursera : Data Structures
Assignment 1
Question 3
*****************************************************/
//Defining the preambles
#include <stdio.h>
#include <stdlib.h>
#define ARRIVAL_PCKTS_SIZE 10
#define PROCESSING_TIME_PERIOD 100
#define FAILED 0
#define SUCCESS 1
#define BUFFER_FULL 2
#define BUFFER_EMPTY 3
#define PACKET_NOT_PROCESSED 4
#define PACKET_IN_PROGRESS 5
//Structure for buffer elements
struct buffer_node
{
int packet_number;
int pckt_process_time;
int pckt_process_time_counter;
int buffer_node_status;
int packet_process_status;
struct buffer_node* buffer_next;
};
typedef struct buffer_node buffer_node;
typedef struct buffer_node* Buffer_Node;
//Declaring Global varibles
Buffer_Node curr_buffer_packet = NULL;
Buffer_Node next_buffer_location = NULL;
int pckt_process_start_time[ARRIVAL_PCKTS_SIZE]={0};
//Declaring the user defined function
void network_information(int* func_buffer_size, int* func_packets_count);
void read_pckt_information(int func_pckt_arrival_time[], int func_pckt_process_time[], int func_packet_count);
int buffer_creation(int* func_buffer_size);
Buffer_Node create_buffer_node();
void func_network_packet_process(int func_pckt_arrival_time[], int func_pckt_process_time[], int func_packets_count);
int push_to_buffer(int func_arrival_packet_number, int func_pckt_process_time, int func_clock_oscillator);
void network_packet_processor(int func_clock_oscillator);
//Defining the main function
int main()
{
int buffer_size = 0;
int packets_count = 0;
int pckt_arrival_time[ARRIVAL_PCKTS_SIZE] = {0};
int pckt_process_time[ARRIVAL_PCKTS_SIZE]={0};
int counter=0;
//Reading the buffer size and number of packet information
network_information(&buffer_size, &packets_count);
//Reading the inputs for network packets arrival time and processing time
read_pckt_information(pckt_arrival_time, pckt_process_time, packets_count);
//Create the buffer to store the network packets
//Exit the program if the buffer creation failed
/**************************************************************************************
2 ways to create the buffer : Array and Linked List
Array is difficult for C as we need to allocate the array size during compile time
So implementing Linked List to create a circular buffer
**************************************************************************************/
if(buffer_creation(&buffer_size) == FAILED && buffer_size != 0)
exit(-1);
//Function to process network packets
//Verify if the number of packets is zero
if(packets_count != 0)
func_network_packet_process(pckt_arrival_time, pckt_process_time, packets_count);
//Print the packet start processing time
for(counter=0; counter<packets_count; counter++)
{
printf("%d\n", pckt_process_start_time[counter]);
}//End of for(counter=0; counter<packets_count; counter++)
return 0;
}//End of int main()
//Defing the user defined function
//Function to read the network information
void network_information(int* func_buffer_size, int* func_packet_count)
{
//Reading the buffer size
scanf("%d", func_buffer_size);
//Reading the number of packets to come
scanf("%d", func_packet_count);
}//End of void network_information(int* func_buffer_size, int* func_packet_count)
//Function to read the input for packet information: arrival time, processing time
void read_pckt_information(int func_pckt_arrival_time[], int func_pckt_process_time[], int func_packet_count)
{
int counter =0;
//Reading the packet arrival time and the packet processing time
for(counter=0; counter<func_packet_count; counter++)
{
scanf("%d", &func_pckt_arrival_time[counter]);
scanf("%d", &func_pckt_process_time[counter]);
}//End of for(counter=0; counter<func_packet_count; counter++)
}//End of void read_pckt_information(int func_pckt_arrival_time[], int func_pckt_process_time[])
//Creating the circular buffer
int buffer_creation(int* func_buffer_size)
{
int buffer_creation_flag = FAILED;
int counter = 0;
Buffer_Node prev_buffer_node = NULL;
Buffer_Node curr_buffer_node = NULL;
//Creating the pointer for the current packet and the next buffer location to be entered
curr_buffer_packet = create_buffer_node();
next_buffer_location = create_buffer_node();
//If the memory allocation for curr_buffer_packet and next_buffer_location is not sucessful
if(curr_buffer_packet == NULL || next_buffer_location == NULL)
return buffer_creation_flag;
//Creating the first Buffer Node for the circular buffer
curr_buffer_node = create_buffer_node();
if(curr_buffer_node == NULL)
return buffer_creation_flag;
//Pointing the curr_buffer_packet and next_buffer_location to the first node in the Buffer Circle
curr_buffer_packet -> buffer_next = curr_buffer_node;
next_buffer_location -> buffer_next = curr_buffer_node;
//Create the rest buffer nodes in the circular buffer
for(counter=0; counter< *func_buffer_size-1; counter++)
{
prev_buffer_node = curr_buffer_node;
//Creating the next buffer_node
curr_buffer_node = create_buffer_node();
if(curr_buffer_node == NULL)
return buffer_creation_flag;
//Connecting the prev_buffer_node to the curr_buffer_node
prev_buffer_node -> buffer_next = curr_buffer_node;
}//End of for(counter=0; counter< *func_buffer_size-1; counter++)
//Complete the circle by pointing the last buffer node to the first buffer node of the circle
curr_buffer_node -> buffer_next = curr_buffer_packet -> buffer_next;
//Circular Buffer has been created successfully so swich the flag
buffer_creation_flag = SUCCESS;
return buffer_creation_flag;
}//End of int buffer_creation(int* func_buffer_size)
//Create buffer nodes
Buffer_Node create_buffer_node()
{
Buffer_Node new_node = NULL;
//Allocate dynamic eory to the new nodes
new_node = (Buffer_Node) malloc(sizeof(buffer_node));
//Assigning value to the buffer node elements
new_node -> packet_number = 0;
new_node -> pckt_process_time = 0;
new_node -> pckt_process_time_counter = -1;
new_node -> buffer_node_status = BUFFER_EMPTY;
new_node -> buffer_next = NULL;
new_node -> packet_process_status = PACKET_NOT_PROCESSED;
return new_node;
}//End of void create_buffer_node()
//Function to process the network information
void func_network_packet_process(int func_pckt_arrival_time[], int func_pckt_process_time[], int func_packets_count)
{
int clock_oscillator=0;
int arrival_packet_counter = 0;
int buffer_push_flag = FAILED;
/**********************************************************************************************************************
Time Oscillator will oscillates after every 1second and it'll record the current time
And read the data from the packet arrival time and the packet processing time
If the current time(clock_oscillator) matches the arrival time then, the data will be pushed to the buffer
If the push operation failed because of buffer full then it will be recorded in func_pckt_process_start_time array
**********************************************************************************************************************/
//Time oscillator starts : NOW
while(clock_oscillator <= PROCESSING_TIME_PERIOD)
{
//If current time matches to the func_pckt_arrival_time
while(clock_oscillator == func_pckt_arrival_time[arrival_packet_counter] && arrival_packet_counter<func_packets_count)
{
//Push the packet information to the buffer
buffer_push_flag = push_to_buffer(arrival_packet_counter, func_pckt_process_time[arrival_packet_counter], clock_oscillator);
//If buffer_push operation failed, record the process start time = -1
if(buffer_push_flag == FAILED)
pckt_process_start_time[arrival_packet_counter] = -1;
//Verify the next packet
arrival_packet_counter++;
}//End of while(clock_oscillator == func_pckt_arrival_time[arrival_packet_counter])
//Process the network packets from the buffer
network_packet_processor(clock_oscillator);
//Increase the clock_oscillator
clock_oscillator++;
}//End of while(clock_oscillator <= PROCESSING_TIME_PERIOD && arrival_packet_counter!=func_packets_count-1)
//If the buffer is still not empty then clear it;
while(curr_buffer_packet -> buffer_next -> buffer_node_status != BUFFER_EMPTY)
{
network_packet_processor(clock_oscillator);
//Increase the clock_oscillator
clock_oscillator++;
}//End of while(curr_buffer_packet -> buffer_next -> buffer_node_status != BUFFER_EMPTY)
}//End of void func_network_packet_process(int func_pckt_arrival_time[], int func_pckt_process_time[], int func_pckt_process_start_time[])
int push_to_buffer(int func_arrival_packet_number, int func_pckt_process_time, int func_clock_oscillator)
{
//Find the buffer location to push the packet information
Buffer_Node curr_buffer_node = next_buffer_location -> buffer_next;
Buffer_Node curr_processing_node = curr_buffer_packet -> buffer_next;
//Verify the buffer_node_status : For full or empty
//If buffer if full then return as push operation failed
if(curr_buffer_node->buffer_node_status == BUFFER_FULL)
return FAILED;
//Else enter the packet information
curr_buffer_node -> packet_number = func_arrival_packet_number;
curr_buffer_node -> pckt_process_time = func_pckt_process_time;
curr_buffer_node -> buffer_node_status = BUFFER_FULL;
//Point the next_buffer_location to the nezt buffer node
next_buffer_location -> buffer_next = curr_buffer_node -> buffer_next;
//Verify if the current_buffer_packet
//If the processing time of the current_buffer_packet =0, then clear it from the buffer
while(curr_processing_node -> pckt_process_time == 0 && curr_processing_node -> buffer_node_status != BUFFER_EMPTY)
{
//Record the processing start time
pckt_process_start_time[curr_processing_node -> packet_number] = func_clock_oscillator;
//Clear out the packet from the buffer memory
curr_processing_node -> buffer_node_status = BUFFER_EMPTY;
//Change the curr_buffer_packet to the next buffer location and verify again
curr_buffer_packet -> buffer_next = curr_processing_node -> buffer_next;
curr_processing_node = curr_buffer_packet -> buffer_next;
}//End of while(curr_buffer_packet -> buffer_next -> pckt_process_time == 0)
return SUCCESS;
}//End of int push_to_buffer(int func_arrival_packet_number, int func_pckt_process_time)
//Process the network information in the buffer
void network_packet_processor(int func_clock_oscillator)
{
Buffer_Node curr_processing_node = curr_buffer_packet -> buffer_next;
//Verify the buffer_node status of the curr_buffer_packet
//If buffer_node_status == BUFFER_EMPTY, then return
if(curr_processing_node -> buffer_node_status == BUFFER_EMPTY)
{
return;
}//End of if(curr_processing_node -> buffer_node_status == BUFFER_FULL)
//Record the packet processing start time
if(curr_processing_node -> packet_process_status == PACKET_NOT_PROCESSED)
{
pckt_process_start_time[curr_processing_node -> packet_number] = func_clock_oscillator;
curr_processing_node -> packet_process_status = PACKET_IN_PROGRESS;
}//End of if(curr_processing_node -> packet_process_status == PACKET_NOT_PROCESSED)
curr_processing_node -> pckt_process_time_counter = (curr_processing_node -> pckt_process_time_counter) + 1;
if(curr_processing_node -> pckt_process_time_counter + 1 >= curr_processing_node -> pckt_process_time)
{
//Reset the buffer node as packet processing is finished
curr_processing_node -> pckt_process_time_counter = -1;
curr_processing_node -> buffer_node_status = BUFFER_EMPTY;
curr_processing_node -> packet_process_status = PACKET_NOT_PROCESSED;
//Move the curr_buffer_packet pointer to the next buffer node location
curr_buffer_packet -> buffer_next = curr_processing_node -> buffer_next;
if (curr_processing_node -> pckt_process_time == 0)
network_packet_processor(func_clock_oscillator);
}
}//End of void network_packet_processor(int func_clock_oscillator)
Comments
Post a Comment