public class PhysicalMemory

{

/* constructor */

public PhysicalMemory()

/* If the memory has enough free frames to satisfy this request, allocate the

frames to the thread and build the page table.

@param id the threadID of the requesting thread

@param requestLength the number of pages the thread requests

@return If the request can be satisfied(which means the free

frames in memory is greater or equal to the requestLength), return true else

return false

*/

public boolean requestMemory(int id, int requestLength)

/* Convert logical page number to physical frame number.

@param id the threadID of the requesting thread

@param pageNumber the page number the thread wants to access

@return the frameNumber (physical address) of the pageNumber

(logical address)

*/

public int accessMemory(int id, int pageNumber)

/* Set the frames allocated to the calling thread to free

@param id the threadID of the calling thread

*/

public void releaseMemory(int id)

}

/* This class implements a linked list which contains all the page tables in the system */

public class PageTableList

{

public PageTableList()

{

first = null;

}

/* add a new entry to the head of the linked list */

public void addFirst(PageTable pt)

{

Node newNode = new Node();

newNode.pt = pt;

newNode.next = first;

first = newNode;

}

/* return the page table associated with the thread id */

public PageTable lookup(int id)

{

Node t = first;

while(t != null)

{

if(t.pt.getThreadID() == id)

return t.pt;

t = t.next;

}

return null;

}

/* head of the linked list */

private Node first;

private class Node

{

public PageTable pt;

public Node next;

}

}

/*

This class implements a page table associated with a thread

*/

import java.util.Arrays;

public class PageTable

{

/* id of the thread a page table is associated with */

private int tid;

/* size of the page table */

private int size;

/* frame number array. page number is used to index the array to find the corresponding frame number */

private int[] pageTableArray;

/* length of the page table */

private int length;

public PageTable(int id, int s)

{

tid = id;

size = s;

length = 0;

pageTableArray = new int[s];

}

/* return the frame number of the page number (index) */

public int lookupPageTable(int index)

{

return pageTableArray[index];

}

/* add an entry to the end of the page table */

public void appendEntry(int frameNumber)

{

pageTableArray[length] = frameNumber;

length++;

}

/* return length of the page table */

public int getLength()

{

return length;

}

/* return thread ID */

public int getThreadID()

{

return tid;

}

/* print the content of the page table */

public void printPageTable()

{

for(int i=0; i<length; i++)

{

System.out.println("Thread " + tid + " Page " + i + " has frame number " + pageTableArray[i]);

}

}

}

/**

* Factory class to start five threads.

*

*/

public class Factory

{

public static void main(String args[]) {

PhysicalMemory physicalMemory = new PhysicalMemory();

Thread[] threadArray = new Thread[5];

for(int i=0; i<5 ;i++)

threadArray[i] = new Thread(new MemoryThread(physicalMemory, i));

for(int i=0; i<5; i++)

threadArray[i].start();

}

}

/**

* This is the thread to simulate the request, access and release of memory space

*/

import java.util.Random;

public class MemoryThread implements Runnable

{

public MemoryThread(PhysicalMemory m, int id) {

physicalMemory = m;

threadID = id;

}

public void run()

{

//Generate a memory request of a random size

Random generator = new Random();

int requestSize = 1 + generator.nextInt(MAX_REQUEST_SIZE);

//Debuging message

//System.out.println("Thread " + threadID + " has been started");

//request memory space

boolean flag = physicalMemory.requestMemory(threadID, requestSize);

//Debuging message

//System.out.println("Thread " + threadID + " has been allocate memory space " + flag);

while (!flag)

{

flag = physicalMemory.requestMemory(threadID, requestSize);

}

//Generate a random memory access

int requestPageNumber = generator.nextInt(requestSize);

int frameNumber = physicalMemory.accessMemory(threadID, requestPageNumber);

System.out.printf("Thread %d requests for page number %d which has frame number %d \n", threadID, requestPageNumber, frameNumber);

// Release the memory

physicalMemory.releaseMemory(threadID);

}

private PhysicalMemory physicalMemory;

private int threadID;

public static final int MAX_REQUEST_SIZE = 50;

}