Showing posts with label Lab code. Show all posts
Showing posts with label Lab code. Show all posts

Monday, May 5, 2014

Unix terminal driver simulation program

The following program is a simulation of UNIX terminal driver canonical mode only minimal functions are implemented

#include
#include
#include

/*
 * 
 */

struct cblock
{
    struct cblock * next;
    char data[8];
    int start;
    int end;
};
typedef struct cblock * Cblock;

struct clist
{
    Cblock first;
    Cblock last;
    int count;
};
typedef struct clist * Clist;


Clist freelist;
Clist inputClist;
Clist cookedClist;
Clist outputClist;

void intializeClist(Clist);
void initializeCblock(Cblock);
void initalizeFreelist();
void addToClist(Clist list,Cblock block);
void writeToHardware();

void intializeClist(Clist list)
{
    list->first=NULL;
    list->last=NULL;
    list->count=0;
}

void initializeCblock(Cblock block)
{
    block->start=-1;
    block->end=-1;
    block->next=NULL;
}

void initalizeallClist()
{
    Cblock temp;
    int i;
    freelist = (Clist)malloc(sizeof (struct clist));
    inputClist = (Clist)malloc(sizeof (struct clist));
    outputClist = (Clist)malloc(sizeof (struct clist));
    cookedClist = (Clist)malloc(sizeof (struct clist));
    intializeClist(inputClist);
    intializeClist(cookedClist);
    intializeClist(outputClist);
    intializeClist(freelist);
    for(i=0;i<50 font="" i="">
    {
        temp=(Cblock)malloc(sizeof (struct cblock));
        initializeCblock(temp);
        addToClist(freelist,temp);
    }

}

void addToClist(Clist list,Cblock block)
{
    if(list->first==NULL)
    {
        list->first=block;
    }
    if(list->last!=NULL)
    {
        list->last->next=block;
    }
    list->last=block;
    list->count++;
}

Cblock getBlockFromList(Clist list)
{
    Cblock temp;
    if(list->first==NULL)
    {
        return NULL;
    }
    temp=list->first;
    list->first=list->first->next;
    if(list->first==NULL)
        list->last=NULL;
    list->count--;
    return temp;
}

Cblock getBlockFromFreeList()
{
    Cblock temp;
    temp = getBlockFromList(freelist);
    if(temp==NULL)
        return temp;
    initializeCblock(temp);
    return temp;
}

void addCharToCLIST(Clist list,char c)
{
    Cblock temp;
    if(list->first==NULL)
    {
        temp=getBlockFromFreeList();
        if(temp!=NULL)
        addToClist(list,temp);
    }
   
    if(list->last->end==7)
    {
        temp=getBlockFromFreeList();
        if(temp!=NULL)
        addToClist(list,temp);
    }
    if(list->last->start==-1)
        list->last->start++;
    list->last->end++;
    list->last->data[list->last->end]=c;
    
}

char getCharFromList(Clist list)
{
    char temp;
    int pos;
    Cblock block;
    if(list->first==NULL)
    {
        printf("\nList Empty\n");
        return '\0';
    }
    pos=list->first->start;
    list->first->start++;
    if(pos<0 pos="">=8)
        printf("error");
    temp=list->first->data[pos];
    if(list->first->start==8)
    {
        block=getBlockFromList(list);
        addToClist(freelist,block);
    }
    return temp;
}

void terminal_write(char userspace[],int start,int count)
{
    
    int last,pos,i,j;
    pos=start;
    char c;
    last = start+count-1;
    while(pos<=last)
    {
        //if(outputClist->count>4)
        //{
        //    writeToHardware();
        //}
        for(i=0;i<8 font="" i="">
        {
           c=userspace[pos++];
           if(c=='\t')
           {
               for(j=0;j<5 font="" j="">
               addCharToCLIST(outputClist,' ');
           }
           else
               addCharToCLIST(outputClist,c);
        }
    }
    writeToHardware();
    
}

void writeToHardware()
{
    char c;
    int pos=0;
    char string[100];
    while(outputClist->first!=NULL)
    {
        c=getCharFromList(outputClist);
        if(c=='\0')
            continue;
        string[pos++]=c;
    }
    string[pos++]='\0';
    write(1,string,pos);
}

void terminal_read(char userspace[],int start,int count)
{
    int i,j;
    char data[2];
    char c;
    int outcount=0;
    if(cookedClist->first==NULL)
    {
        for(i=0;i
        {
            read(0,data,1);
            if(data[0]=='\n')
                break;
            addCharToCLIST(inputClist,data[0]);
        }
        while(inputClist->first!=NULL)
        {
            c=getCharFromList(inputClist);
              if(c=='\t')
           {
               for(j=0;j<5 font="" j="">
               addCharToCLIST(cookedClist,' ');
           }
              else
                  if(c=='\n')
                  {
                      break;
                  }
           else
               addCharToCLIST(cookedClist,c);
        }
    }
    while(cookedClist->first!=NULL&&outcount
    {
        c=getCharFromList(cookedClist);
        userspace[outcount++]=c;
    }
}

int main(int argc, char** argv) {

    char userspace[6]={'a','b','\t','c','d','e'};
    char userspace2[6];
    
    initalizeallClist();
    
    terminal_write(userspace,0,6);
    terminal_write(userspace,0,6);
    terminal_read(userspace2,0,5);
    userspace2[5]='\0';
    printf("\n%s",userspace2);
    return 0;
}

Friday, March 14, 2014

Cristian's Algorithm for clock synchronization

The following programs implement the basic form of Cristian's algorithm for physical clock synchronization.
It is the basic form of clock synchronization.
Run the server first then run the client.



ClockServer.java

import java.io.*;
import java.net.*;
import java.util.*;

/**
 *
 * @author student
 */
public class ClockServer {

    /**
     * @param args the command line arguments
     */

    public static void main(String[] args) throws IOException {
        String port;
        BufferedReader stdIn =
                new BufferedReader(
                    new InputStreamReader(System.in));
        System.out.println("Enter the port no");
       
        port=stdIn.readLine();
               
        int portNumber = Integer.parseInt(port);
        
        try (
            ServerSocket serverSocket =
                new ServerSocket(portNumber);
            Socket clientSocket = serverSocket.accept();     
            PrintWriter out =
                new PrintWriter(clientSocket.getOutputStream(), true);                   
            BufferedReader in = new BufferedReader(
                new InputStreamReader(clientSocket.getInputStream()));
            
        ) {
            String inputLine;
            System.out.println("Server Started");
            while (true) {
                inputLine = in.readLine();
                if(inputLine.equalsIgnoreCase("Exit"))
                {
                     System.out.println("Exiting");
                     out.println("Server Exiting");
                     break;
                }
                out.println(System.currentTimeMillis()+5000);
            }
        } catch (IOException e) {
            System.out.println("Exception caught when trying to listen on port "
                + portNumber + " or listening for a connection");
            System.out.println(e.getMessage());
        }
    }

}


ClockClient.java

import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
/**
 *
 * @author student
 */
public class ClockClient {

    /**
     * @param args the command line arguments
     */
public static void main(String[] args) throws IOException {
        
        String port,hostName;
        BufferedReader stdIn =
                new BufferedReader(
                    new InputStreamReader(System.in));
        System.out.println("Enter the port no");
        port=stdIn.readLine();
        int portNumber = Integer.parseInt(port);
        System.out.println("Enter the host name");
        hostName=stdIn.readLine();
        try (
            Socket echoSocket = new Socket(hostName, portNumber);
            PrintWriter out =
                new PrintWriter(echoSocket.getOutputStream(), true);
            BufferedReader in =
                new BufferedReader(
                    new InputStreamReader(echoSocket.getInputStream()));
            ) {
            String userInput;
            System.out.println("Client Started");
            System.out.println("Enter Exit to stop");
            
                long T0;
                long serverTime;
                long T1;
                long finalTime;                
                out.println(T0=System.currentTimeMillis());
                serverTime = Long.parseLong(in.readLine());
                T1 =System.currentTimeMillis();
                finalTime =  serverTime + (T1-T0)/2;
                DateFormat formatter = new SimpleDateFormat("HH:mm:ss:SSS");
                System.out.println("Client Time: " + formatter.format(new Date(T1)));
                System.out.println("Server Time: " + formatter.format(new Date(serverTime)));
                System.out.println("Client Time after reset: " + formatter.format(new Date(finalTime)));
                out.println("EXit");
                
               
           
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host " + hostName);
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to " +
                hostName);
            System.exit(1);
        } 
    }

}


Output:


Server
Enter the port no
2222
Server Started

Exiting


Client
Enter the port no
2222
Enter the host name
localhost
Client Started
Enter Exit to stop
Client Time: 13:53:23:515
Server Time: 13:53:28:515

Client Time after reset: 13:53:28:515



Thursday, March 13, 2014

Lamport algorithm for logical clock synchronization

A very basic implementation of Lamport logical clock synchronization.



public class Lamport {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        Process p1,p2,p3;
        p1= new Process(1);
        p2= new Process(2);
        p3= new Process(3);
        System.out.println("P1  P2   p3");
        System.out.println(p1.time+"  "+ p2.time+"  "+p3.time);
        p1.passMessege(p3);
        System.out.println("P1->P3");
        System.out.println(p1.time+"  "+ p2.time+"  "+p3.time);
        p2.passMessege(p3);
         System.out.println("P2->P3");
        System.out.println(p1.time+"  "+ p2.time+"  "+p3.time);
        p3.passMessege(p2);
         System.out.println("P3->P2");
        System.out.println(p1.time+"  "+ p2.time+"  "+p3.time);
        
    }
    
}


public class Process {
    
    public int time;
    public int timestep;
    
    public void passMessege(Process p)
    {
        time+=timestep;
        p.time+=p.timestep;
        if(p.time<=time)
            p.time=time+1;
    }
    public Process(int tstep)
    {
        time=0;
        timestep=tstep;
    }
}

Output
P1  P2   p3
0  0  0
P1->P3
1  0  3
P2->P3
1  2  6
P3->P2
1  10  9


Wednesday, March 5, 2014

UNIX Process management data structure

The following program is used to implement data structures for unix process management


#include
#include
#include

#define MAXSIZE 10
/*
 *
 */
struct region
{
    int startAdress;
    int offset;
    int allocated;
};
typedef struct region* Region;

struct perProcessRegion
{
    int type;
    Region region;
    int allocated;
};
typedef struct perProcessRegion* PerProcessRegion;

struct process
{
    PerProcessRegion textArea;
    PerProcessRegion dataArea;
    PerProcessRegion stackArea;
    int allocated;
};
typedef struct process* Process;

struct uarea
{
    Process procees;
    int allocated;
};
typedef struct uarea* Uarea;

Uarea u;
Uarea uareaTable[MAXSIZE];
Process processTable[MAXSIZE];
PerProcessRegion perProcessRegionTable[MAXSIZE];
Region regionTable[MAXSIZE];

void init();
void display();
Uarea allocateUare();
Process allocateProcess();
PerProcessRegion allocatePerProcessRegion(int);
Region allocateRegion(int);

void init()
{
    int i;
    for(i=0;i    {
        uareaTable[i]= (Uarea) malloc(sizeof (struct uarea));
        uareaTable[i]->allocated =0;
        processTable[i]= (Process) malloc(sizeof (struct process));
        processTable[i]->allocated =0;
        perProcessRegionTable[i]= (PerProcessRegion) malloc(sizeof (struct perProcessRegion));
        perProcessRegionTable[i]->allocated =0;
        regionTable[i]= (Region) malloc(sizeof (struct region));
        regionTable[i]->allocated =0;
       
        u = uareaTable[0];
    }
   
}

void display()
{
    int i;
    printf("\nUser Areas\n");
    for(i=0;i    {
        printf("%p\t %d\n",uareaTable[i]->procees,uareaTable[i]->allocated);
    }
    printf("\nProcess Table\n");
    for(i=0;i    {
        printf("%p \t%p \t%p \t%d\n",processTable[i]->textArea,processTable[i]->dataArea,processTable[i]->stackArea,processTable[i]->allocated);
    }
    printf("\nPer Process Region Table\n");
    for(i=0;i    {
        printf("%p \t%d \t %d\n",perProcessRegionTable[i]->region,perProcessRegionTable[i]->type,perProcessRegionTable[i]->allocated);
    }
    printf("\nRegion Table\n");
    for(i=0;i    {
        printf("%d \t %d \t %d\n",regionTable[i]->startAdress,regionTable[i]->offset,regionTable[i]->allocated);
    }
}

Uarea allocateUarea()
{
    int i;
    for(i=0;i    {
        if(uareaTable[i]->allocated==0)
            break;
    }
    if(i==MAXSIZE)
    {
        printf("uarea Table FUll");
        return NULL;
    }
    uareaTable[i]->procees=allocateProcess();
    if(uareaTable[i]->procees==NULL)
        return NULL;
    uareaTable[i]->allocated=1;
    return uareaTable[i];
}

Process allocateProcess()
{
    int i;
    for(i=0;i    {
        if(processTable[i]->allocated==0)
            break;
    }
    if(i==MAXSIZE)
    {
        printf("Process Table FUll");
        return NULL;
    }
   
    processTable[i]->textArea= allocatePerProcessRegion(0);
    processTable[i]->dataArea= allocatePerProcessRegion(1);
    processTable[i]->stackArea= allocatePerProcessRegion(2);
    if((processTable[i]->textArea==NULL)||(processTable[i]->dataArea==NULL)||(processTable[i]->stackArea==NULL))
        return NULL;
    processTable[i]->allocated=1;
    return processTable[i];
}

PerProcessRegion allocatePerProcessRegion(int type)
{
    int i;
    for(i=0;i    {
        if(perProcessRegionTable[i]->allocated==0)
            break;
    }
    if(i==MAXSIZE)
    {
        printf("Per Process RegionTable FUll");
        return NULL;
    }
       
    perProcessRegionTable[i]->region=allocateRegion(type);
    if(perProcessRegionTable[i]->region==NULL)
        return NULL;
    perProcessRegionTable[i]->allocated =1;
    return perProcessRegionTable[i];
   
}

Region allocateRegion(int type)
{
    int i;
    for(i=0;i    {
        if(regionTable[i]->allocated==0)
            break;
    }
    if(i==MAXSIZE)
    {
        printf("RegionTable FUll");
        return NULL;
    }
   
    switch(type)
    {
        case 0:
            regionTable[i]->startAdress=0;
            regionTable[i]->offset=1024;
            break;
         case 1:
            regionTable[i]->startAdress=1024;
            regionTable[i]->offset=1024;
            break;
          case 2:
            regionTable[i]->startAdress=2048;
            regionTable[i]->offset=1024;
            break;          
    }
    regionTable[i]->allocated =1;
    return regionTable[i];
    }

int main(int argc, char** argv) {

    init();
    u=allocateUarea();
    display();
    return 0;
}

UNIX FIle system data structure

The following program will be used to understand data structure used in UNIX file system.

#include
#include
#include

#define MAXSIZE 10

struct inode_table
{
                int count;
                int check;
                char filename[20];
 };
typedef struct inode_table*  Inode;

struct file_table
{
                int check;
                int count;
                char mode;
                Inode ptr;
};

typedef struct file_table* FileDescriptor;


struct user_file_descriptor
{
int check;
FileDescriptor ptr;
};
typedef struct user_file_descriptor* UserFileDescriptor;

char buffer[100],ip[100];
char mode;
int no=0;
UserFileDescriptor userFDTable[MAXSIZE];
FileDescriptor fileTable[MAXSIZE];
Inode inodeTable[MAXSIZE];

void setup_Tables();
void display_Tables();

UserFileDescriptor allocate_UFD(char[],char);
FileDescriptor allocate_FileDescriptor(char[],char);
Inode allocate_inode(char[]);

void close_UFD(UserFileDescriptor);
void close_FD(FileDescriptor);
void close_inode(Inode);


void setup_Tables()
{
        int i;
        for (i = 0; i < MAXSIZE; i++) {
        userFDTable[i] = (UserFileDescriptor) malloc(sizeof (struct user_file_descriptor));
        userFDTable[i]->check = 0;

        fileTable[i] = (FileDescriptor) malloc(sizeof (struct file_table));
        fileTable[i]->check = 0;
        fileTable[i]->count = 0;

        inodeTable[i] = (Inode) malloc(sizeof (struct inode_table));
        inodeTable[i]->check = 0;
        inodeTable[i]->count = 0;
    }
}

void display_Tables()
{
    int i;
    printf("\nUser File Descriptor Table\n");
    for(i=0;i        printf("%p\t %d\n",fileTable[i]->ptr,fileTable[i]->check);
    printf("\nFile Descriptor Table\n");
    for(i=0;i        printf("%p\t %d \t%d \t%c\n",fileTable[i]->ptr,fileTable[i]->check,fileTable[i]->count,fileTable[i]->mode);
    printf("\nFile Descriptor Table\n");
    for(i=0;i        printf("%s\t %d \t%d\n",inodeTable[i]->filename,inodeTable[i]->check,inodeTable[i]->count);
   
}

UserFileDescriptor allocate_UFD(char filename[],char mode)
{

int current;
                FileDescriptor temp;
                for(current=3;current                {
                    if(userFDTable[current]->check==0)
                        break;
                }
               
                if(current==MAXSIZE)
                {
                    printf("UFD Table out of space");
                    return NULL;
                }
               
                temp = allocate_FileDescriptor(filename,mode);
                if(temp==NULL)
                    return NULL;
               
                userFDTable[current]->check = 1;
                userFDTable[current]->ptr = temp;
               
                return userFDTable[current];
}


FileDescriptor allocate_FileDescriptor(char filename[],char mode)
{
   
int current;
                Inode temp;
                for(current=0;current                {
                    if(fileTable[current]->check==0)
                        break;
                }
               
                if(current==MAXSIZE)
                {
                    printf("File Descriptor Table out of space");
                    return NULL;
                }
               
                temp = allocate_inode(filename);
                if(temp==NULL)
                    return NULL;
               
                fileTable[current]->check = 1;
                fileTable[current]->ptr = temp;
                fileTable[current]->count=1;
                fileTable[current]->mode = mode;
               
                return fileTable[current];
   
}

Inode allocate_inode(char fileName[])
{
int current;
       
        for(current=0;current        {
            if(inodeTable[current]->check==1)
            {
                if(strcmp(inodeTable[current]->filename,fileName)==0)
                {
                    inodeTable[current]->count++;
                    return inodeTable[current];
                }
            }
        }
       
        for(current=0;current        {
              if(inodeTable[current]->check==0)
                  break;
        }
       
        if(current==MAXSIZE)
        {
             printf("Inode Table out of space");
             return NULL;
        }
       
        inodeTable[current]->check=1;
        inodeTable[current]->count++;
        strcpy(inodeTable[current]->filename,fileName);
        return inodeTable[current];      
}





void close_UFD(UserFileDescriptor ufd)
{
    close_FD(ufd->ptr);
    ufd->check=0;
}

void close_FD(FileDescriptor fd)
{
    close_inode(fd->ptr);
    fd->check=0;
    fd->count--;
}

void close_inode(Inode iNode)
{
    iNode->count--;
    if(iNode->count==0)
        iNode->check=0;
}

int main(int argc, char** argv) {
setup_Tables();
UserFileDescriptor ufd =allocate_UFD("aaa",'R');
display_Tables();
close_UFD(ufd);
display_Tables();
return 0;
}

Unix Buffer Cache management

The following program is a partial implementation to understand getblk,bread,brelse,breada,bwrite system calls of UNIX

#include
#include
#define MAXSIZE 40
#define HASHQSIZE 4


/*
 *
 */

struct buffer_block
    {
        int blockNo;
        struct buffer_block * next_HQ;
        struct buffer_block * prev_HQ;
        struct buffer_block * prev_FreeList;
        struct buffer_block * next_FreeList;
        int lock;
        int valid;
        int delayedWrite;
    };
   
typedef struct buffer_block * BufferCache;
   
BufferCache hashQueue[MAXSIZE];
BufferCache freeListHeader;



void initializeBuffer(BufferCache);
void addToHashQueue(BufferCache);
void addToFreeList(BufferCache,int);
void removeFromFreeList(BufferCache);
void removeFromHashQueue(BufferCache);
BufferCache searchHashQueue(int);
BufferCache newBuffer();
BufferCache getblk(int);
void brelse(BufferCache);
BufferCache bread(int);
BufferCache breada(int,int);
void bwrite(BufferCache,int);
void printHashQueue();
void printFreeList();



void addToHashQueue(BufferCache buf)
{
    int hash;
    hash = buf->blockNo % HASHQSIZE;
   
    if(hashQueue[hash]==NULL)
    {
        hashQueue[hash]=buf;
        buf->prev_HQ=NULL;
        buf->next_HQ=NULL;
    }
    else
    {
        buf->next_HQ=hashQueue[hash];
        buf->prev_HQ=NULL;
        hashQueue[hash]=buf;
    }
   
}



void removeFromHashQueue(BufferCache buf)
{
    int hash;
    hash = buf->blockNo % HASHQSIZE;
   
    if(buf->prev_HQ==NULL)
    {
        hashQueue[hash]=buf->next_HQ;
    }
    else
    {
        buf->prev_HQ->next_HQ=buf->next_HQ;
        if(buf->next_HQ!=NULL)
        {
            buf->next_HQ->prev_HQ=buf->prev_HQ;
        }
    }
}

void addToFreeList(BufferCache buf,int pos)
{
    if(freeListHeader->next_FreeList==freeListHeader)
    {
        freeListHeader->next_FreeList=buf;
        freeListHeader->prev_FreeList=buf;
        buf->next_FreeList=freeListHeader;
        buf->prev_FreeList=freeListHeader;
    }
    else
    {
        if(pos==1)/*Front of the list*/
        {
            buf->next_FreeList=freeListHeader->next_FreeList;
            buf->prev_FreeList=freeListHeader;
            freeListHeader->next_FreeList->prev_FreeList=buf;
            freeListHeader->next_FreeList=buf;
        }
        else /* Back of the list */
        {
            buf->prev_FreeList=freeListHeader->prev_FreeList;
            buf->next_FreeList=freeListHeader;
            freeListHeader->prev_FreeList->next_FreeList=buf;
            freeListHeader->prev_FreeList=buf;
        }
    }
}

void removeFromFreeList(BufferCache buf)
{
    if(buf==freeListHeader->next_FreeList)
    {
       
        buf->next_FreeList->prev_FreeList=freeListHeader;
        freeListHeader->next_FreeList=buf->next_FreeList;
        return;
    }
    if(buf==freeListHeader->prev_FreeList)
    {
       
        buf->prev_FreeList->next_FreeList=freeListHeader;
        freeListHeader->prev_FreeList=buf->prev_FreeList;
        return;
    }
   
   buf->next_FreeList->prev_FreeList=buf->prev_FreeList;
   buf->prev_FreeList->next_FreeList=buf->next_FreeList;
}


void intializeBuffer()
{
    int i;
    BufferCache buf;
    freeListHeader=newBuffer();
   
    freeListHeader->prev_FreeList =freeListHeader;
    freeListHeader->next_FreeList =freeListHeader;
   
    for(i=0;i    {
        buf= newBuffer();
        buf->blockNo=i;
        addToHashQueue(buf);
        addToFreeList(buf,1);      
    }
   
}

BufferCache newBuffer()
{
    BufferCache buf = (BufferCache) malloc(sizeof (struct buffer_block));
    buf->valid = 0;
    buf->delayedWrite=0;
    buf->lock=0;
    return buf;
}

BufferCache searchHashQueue(int blockno)
{
    int hash;
    BufferCache buf;
    hash = blockno % HASHQSIZE;
    buf = hashQueue[hash];
    while(buf!=NULL)
    {
        if(buf->blockNo==blockno)
            return buf;
        buf=buf->next_HQ;
    }
    return NULL;  
}

BufferCache getblk(int blockno)
{
    int found=0;
    BufferCache buf;
    while(found==0)
    {
        buf = searchHashQueue(blockno);
        if(buf!=NULL)/*Block in Hash Queue */
        {
            if(buf->lock)
            {
                printf("\nbuffer busy Sleep till block become free \n");              
                /* workaround*/
                brelse(buf);
                /* end of workaround*/
                continue;              
            }
            buf->lock=1;
            removeFromFreeList(buf);
            return buf;
        }
        else
        {
            if(freeListHeader->next_FreeList==freeListHeader)
            {
                printf("\nFree list empty sleep till any buffer available\n");
                /* workaround*/
                brelse(hashQueue[0]);
                /* end of workaround*/
                continue;
            }
            buf=freeListHeader->next_FreeList;
            removeFromFreeList(buf);
            if(buf->delayedWrite)
            {
                printf("\nPerform asyncranous write of block %d\n",buf->blockNo);
                bwrite(buf,0);
                continue;
            }
            removeFromHashQueue(buf);
            buf->blockNo=blockno;
            addToHashQueue(buf);
            buf->valid=0;      
            buf->lock=1;
            return buf;
        }
    }
}

void brelse(BufferCache buf)
{
    printf("\nWakeup all process waiting for any buffer\n");
    printf("\nWakeup all process waiting for buffer with block %d\n",buf->blockNo);
    printf("\nRaise processor execution level to block interrupts\n");
    if(buf->valid)//also check If buffer is old
    {
        addToFreeList(buf,0);
    }
    else
    {
        addToFreeList(buf,1);
    }
    printf("\nlower processor execution level to allow interrupts\n");
    buf->lock=0;
}

BufferCache bread(int blockno)
{
    BufferCache buf;
    buf=getblk(blockno);
    if(buf->valid)
        return buf;
    printf("\nInitiate disk read of block %d\n",blockno);
    printf("\nSleep till disk read complete\n");
    return buf;
}

BufferCache breada(int imdBlockno,int asynBlockno)
{
    BufferCache buf1,buf2;
    int flag=0;
    buf1=searchHashQueue(imdBlockno);
    buf2=searchHashQueue(asynBlockno);
    if(buf1==NULL)
    {
        flag=1;
        buf1 = getblk(imdBlockno);
        if(buf1->valid==0)
            printf("\nInitiate disk read of block %d\n",imdBlockno);
    }
    if(buf2==NULL)
    {
        buf2=getblk(asynBlockno);
        if(buf2->valid)
            brelse(buf2);
        else
            printf("\nInitiate disk read of block %d\n",asynBlockno);
    }
    if(!flag)
    {
        buf1=bread(imdBlockno);
        return buf1;
    }
    printf("\nSleep till Cache contains valid data\n");
    return buf1;
}

void bwrite(BufferCache buf,int syn)
{
    printf("\nInitiate disk write\n");
    if(syn)
    {
        printf("\nSleep till IO complete\n");
        brelse(buf);
    }
    else
        if(buf->delayedWrite)
        {
            buf->delayedWrite=0;
            removeFromFreeList(buf);
            addToFreeList(buf,1);
        }
}

void printHashQueue()
{
    int i;
    BufferCache buf;
    for(i=0;i    {
        printf("\nElement with Hash value %d\n",i);
        buf=hashQueue[i];
        while(buf!=NULL)
        {
            printf("%d\t%d\t%d\t%d\n",buf->blockNo,buf->delayedWrite,buf->lock,buf->valid);
            buf=buf->next_HQ;
        }
    }
}
void printFreeList()
{
    BufferCache buf;
    buf= freeListHeader;
    printf("\nElement in Freelist\n");
    while(buf->next_FreeList!=freeListHeader)
    {
        buf=buf->next_FreeList;
        printf("%d\t%d\t%d\t%d\n",buf->blockNo,buf->delayedWrite,buf->lock,buf->valid);
    }
}

int main(int argc, char** argv) {

    intializeBuffer();
    BufferCache buf,buf1;
    //printHashQueue();
    //printFreeList();
    buf = getblk(5);    //block is in cache and available
    printf("\n%d block read\n",buf->blockNo);
    buf = getblk(55);   //block is not in cache and free list available
    printf("\n%d block read\n",buf->blockNo);
    buf = getblk(5);    //block is in cache and is in Use
    printf("\n%d block read\n",buf->blockNo);
    freeListHeader->next_FreeList->delayedWrite=1;
    buf = getblk(56);   //block is not in cache and free buffer marked delayed write
    printf("\n%d block read\n",buf->blockNo);
    while(freeListHeader->next_FreeList!=freeListHeader)
    {
        getblk(freeListHeader->next_FreeList->blockNo);
    }
   
    buf = getblk(60);
    printf("\n%d block read\n",buf->blockNo);
    brelse(buf);
   

    buf = getblk(60);
    printf("\n%d block read\n", buf->blockNo);
    buf->valid = 1;
    brelse(buf);
    printHashQueue();
    printFreeList();
    buf = bread(32);
   
    buf=breada(2,77);
    bwrite(buf,0);
   
    buf=bread(3);
    bwrite(buf,1);
    breada(2,36);
    printHashQueue();
    printFreeList();
    return 0;
}