#include "csim.h"
#include <stdio.h>

#define NUM_CLIENTS 5L
#define NUM_SERVER 1L
#define T_DELAY 0.8 // (data_size/bandwidth) = 1024*8/10000
#define REQUEST 1L
#define REPLY 2L
#define Query_delay_time 10 // output is taken when value is 10 or 20 or 25 or 30 or 50
#define CACHE_SIZE 100
#define SERVER_NODE 5
#define L 20.0

typedef struct msg* msg_t;

struct msg
{

    int flag;
    long from;
    long to;
    long type;
    long data_id;
    float start_time;
    long updated_time;
    msg_t link;
};

typedef struct invalidationReport* ir;

struct invalidationReport
{
    long current_timestamp;
    long data_item_id[500];
    long last_update_time[500];
    long from;
    long to;
    long start_time;
    ir link;
};

msg_t msg_queue;
ir ir_queue;

struct nde
{
    FACILITY cpu;
    MBOX input;
};

struct cache
{
    long valid_bit[CACHE_SIZE];
    long data_item_id[CACHE_SIZE];
    long last_update_time[CACHE_SIZE];
    long last_accessed_time[CACHE_SIZE];
};

struct nde node[NUM_CLIENTS + NUM_SERVER];
struct cache c[NUM_CLIENTS];
TABLE resp_tm;
FILE* fp;
EVENT ir_event;
EVENT server_sent_msg;
EVENT server_receive;

msg_t new_msg();
void init();
void process_server();
void process_client();
void update();
void process_receiveservermsg();
void IR();
void query();
void CilentReceiverProcess();
void form_reply();
void broadcast();
ir generate_IR();
void send_IR();
void send_msg();
void send_query_msg();
void process_receivecilentmsg();
void displayOutput();

long T_update = 0;
long T_query = 0;
long simulationTime = 0.0;
long a[500];
long data_id;

long query_generated_count = 0;
long cache_hit_count = 0;
float cache_hit_ratio = 0;
float query_delay = 0;
long queries_served_count = 0;

void sim()
{
    long i;
    create("sim");
    ir_event = event("ir_event");
    server_sent_msg = event("server_sent_msg");
    server_receive = event("server_receive");
    init();
    printf("\n Enter the mean update value ");
    scanf("%ld", &T_update);
    printf("\n Enter the mean query generate time ");
    scanf("%ld", &T_query);
    simulationTime = (CACHE_SIZE * Query_delay_time * 10);
    for (i = 0; i < 500; i++)
    {
        a[i] = 0;
    }

    process_client();
    process_server();
    hold(simulationTime);
    displayOutput();
}

void displayOutput()
{
    float avg_query_delay = 0;
    long avg_number_of_queries_served = 0;

    printf("\n Total Querries Generated: %ld, cache_hit_count: %ld\n", query_generated_count, cache_hit_count);
    cache_hit_ratio = (float)cache_hit_count / query_generated_count;
    printf("\n Cache hit ratio is %6.3f\n", cache_hit_ratio);

    avg_query_delay = (float)(query_delay / (query_generated_count * NUM_CLIENTS));

    printf("\n Average query delay is %6.3f\n", avg_query_delay);
}

void init()
{
    int i = 0;
    char str[24];
    long NUM_NODES;
    long x;
    NUM_NODES = NUM_CLIENTS + NUM_SERVER;
    max_facilities(NUM_NODES * NUM_NODES + NUM_NODES);
    max_servers(NUM_NODES * NUM_NODES + NUM_NODES);
    max_mailboxes(NUM_NODES);
    max_events(2 * NUM_NODES * NUM_NODES);
    resp_tm = table("message response time");
    ir_queue = NIL;
    for (; i < NUM_NODES; i++)
    {
        node[i].cpu = facility(str);
        node[i].input = mailbox(str);
    }

   
}

void process_server()
{
    create("serverprocess");
    update();
    IR();
    process_receiveservermsg();
    while (clock < simulationTime)
    {
        hold(10.0);
    }
}

void update()
{
    long x;
    double total_update_prob;
    long server_node = SERVER_NODE; 
    create("updateproc");
    while (clock < simulationTime)
    {
        hold(T_update);
        total_update_prob = uniform(0.0, 1.0);
        if (total_update_prob < 0.33)//hot
        {
            data_id = uniform(0, 49);
        }
        else //cold
        {
            data_id = uniform(50, 499);
        }
        x = (long)clock;
        a[data_id] = x;
    }
}

void IR()
{
    create("irproc");
    while (clock < simulationTime)
    {
        hold(L);
        broadcast();
    }
}

generate a report Brief explanations of functions  ,  note that this is only part of the code and i will feed the rest to you as well, for reference here is the description of the code
Implement a simple pull-based cache invalidation scheme by using CSIM in C. In the scheme, a node generates a query and sends a request message to a server if the queried data item is not found in its local cache. If the node generates a query that can be answered by its local cache, it sends a check message to the server for validity. The server replies to the node with a requested data item or a confirm message. A set of data items is updated in the server. This scheme ensures a strong consistency that guarantees to access the most updated data items. Note that remove a cold state before collecting any results. use the following simulation parameters .make sure to output cache hit ratio and (ii) query delay by changing mean query generation time and mean update arrival time. 
Parameter Values 
Number of clients 5 
Database (DB) size 500 items 
Data item size 1024 bytes
 Bandwidth 10000 bits/s 
Cache size 100 items 
Cache replacement policy LRU 
Mean query generate time (T_query) 5, 10, 25, 50, 100 seconds 
Hot data items 1 to 50 
Cold data items remainder of DB 
Hot data access prob. 0.8 
Mean update arrival time (T_update) 5, 10, 20, 100, 200 seconds 
Hot data update prob. 0.33