diff --git a/Job.java b/Job.java index 23cddf9..1f7fb56 100644 --- a/Job.java +++ b/Job.java @@ -38,5 +38,9 @@ public class Job { } } + public void setBeginningLocation(int newBeginning) + { + myThread.setBeginning(newBeginning); + } } diff --git a/NextFit.java b/NextFit.java index bff1a3d..43d2a9b 100644 --- a/NextFit.java +++ b/NextFit.java @@ -15,7 +15,7 @@ class NextFit implements baseAlgorithm startLoc, endLoc, blkSize, - memSize = memoryManagement.memory, + memSize = memoryManagement.MEMORYSIZE, active, noJobs=0, s1=0, diff --git a/jobThread.java b/jobThread.java index 72cf764..1bd91da 100644 --- a/jobThread.java +++ b/jobThread.java @@ -1,8 +1,7 @@ -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class jobThread extends Thread { - private final int sleepResolution = 200; //Milliseconds + private final int sleepResolution = 20; //Milliseconds private long jobTime; //Milliseconds private long elapsedTime; private boolean isPaused, pauseStateChanged; @@ -28,6 +27,10 @@ public class jobThread extends Thread { this.beginningLocation = beginningLocation; } + public void setBeginning(int newBeginning){ + this.beginningLocation = newBeginning; + } + public void pause(){ synchronized(this){ isPaused = true; diff --git a/memoryManagement.java b/memoryManagement.java index 9d8f066..ef28e5f 100644 --- a/memoryManagement.java +++ b/memoryManagement.java @@ -9,12 +9,11 @@ import java.util.StringTokenizer; public class memoryManagement{ - public static int memory = 1024; - + static final int JOBAMOUNT = 1000; + static final int MEMORYSIZE = 10000; + public static void main(String args[])throws Exception{ - final int JOBAMOUNT = 1000; - final int MEMORYSIZE = 10000; - + File file = new File("null"); Scanner keyboard = new Scanner(System.in); Scanner fileScan; @@ -79,4 +78,4 @@ public class memoryManagement{ System.out.println("Completed Successfully"); } -} \ No newline at end of file +} diff --git a/threadedAllocation.java b/threadedAllocation.java index 63820b3..0fab164 100644 --- a/threadedAllocation.java +++ b/threadedAllocation.java @@ -1,5 +1,9 @@ +import java.lang.reflect.Method; + public class threadedAllocation implements baseAlgorithm{ int[] memoryBlock; + threadedAllocationGarbage garbageThread; + Job[] jobArray; threadedAllocation(int memorySize) { /* Constructor specific for this algorithm @@ -7,6 +11,12 @@ public class threadedAllocation implements baseAlgorithm{ * Start the threaded garbage collector, and then begin * our actual operations */ memoryBlock = new int[memorySize]; + + this.garbageThread = new threadedAllocationGarbage(this.memoryBlock, 20, this.jobArray); + this.garbageThread.run(); + + // Set up the array of job references + jobArray = new Job[memoryManagement.JOBAMOUNT]; } int locateBlock(int blockSize){ @@ -40,20 +50,28 @@ public class threadedAllocation implements baseAlgorithm{ public void allocate(int jobID, int jobSize, int jobLength ){ /* Over-rides allocate() of baseAlgorithm */ - - //Loop until we get a block big enough for our job - // Note that this assumes we're not going to race against ourselves - int beginningLocation = locateBlock( jobSize ); - while (beginningLocation == -1) - beginningLocation = locateBlock( jobSize ); - - //We've got a location, mark it as filled, and start the job. - for (int x = 0; x < jobSize; x++) - { - memoryBlock[beginningLocation + x] = jobID; + try{ + Method deallocateMethod = this.getClass().getMethod("deallocate", new Class[]{int.class, int.class}); + + //Loop until we get a block big enough for our job + // Note that this assumes we're not going to race against ourselves + int beginningLocation = locateBlock( jobSize ); + while (beginningLocation == -1) + beginningLocation = locateBlock( jobSize ); + + //We've got a location, mark it as filled, and start the job. + for (int x = 0; x < jobSize; x++) + { + memoryBlock[beginningLocation + x] = jobID; + } + + //TODO: Code to start the job + Job newJob = new Job(jobLength, jobID, jobSize, beginningLocation, deallocateMethod, this); + jobArray[jobID] = newJob; + newJob.start(); + } catch (Exception e){ + System.out.println("Could not allocate job with ID " + jobID); } - - //TODO: Code to start the job } public void deallocate(int jobSize, int beginningLocation){ diff --git a/threadedAllocationGarbage.java b/threadedAllocationGarbage.java index 69dc4de..9e3706b 100644 --- a/threadedAllocationGarbage.java +++ b/threadedAllocationGarbage.java @@ -7,18 +7,120 @@ class threadedAllocationGarbage extends Thread int[] memoryBlock; int sleepTime; + Job[] jobArray; - threadedAllocationGarbage( int[] memoryBlock, int sleepTime ){ + threadedAllocationGarbage( int[] memoryBlock, int sleepTime, Job[] jobArray ){ /* Set up a reference to the algorithm's memory location */ this.memoryBlock = memoryBlock; /* Set up the time quantum */ this.sleepTime = sleepTime; + + /* Set up the array of jobs so that we can pause them as need be */ + this.jobArray = jobArray; + } + + public int[] largestBlock(){ + //Find an open location + int memoryLoc = 0; + int maxFreeSize = 0, maxFreeIndex = 0; + while (memoryLoc < this.memoryBlock.length) + { + if (this.memoryBlock[memoryLoc] != 0) + //Block isn't free + continue; + + //One location is free, find out total size free + //This loop breaks either when we've found the size we need, or + //we found the beginning of the next block. + int beginningLoc = memoryLoc; + int free = 0; + while (this.memoryBlock[memoryLoc] == 0) + { + memoryLoc += 1; + free += 1; + } + //We've found the end of that chunk, see if it's bigger than what we have on file + if (free > maxFreeSize){ + maxFreeSize = free; + maxFreeIndex = beginningLoc; + } + } + + //We've reached the end of memory, return what the largest block was (if we found a block) + if (maxFreeSize > 0) + return new int[]{maxFreeIndex, maxFreeSize}; + else + return new int[]{-1, -1}; } public void run() { /* Code to run in the background */ - //Sleep for sleepTime, then scan for memory to compact + while (true) + { + /* The way this algorithm works is to: + * Start at the beginning of the memory block + * Find the largest available block + * Shift the closest job down to fill up this space + * Repeat until deconstructed + */ + + int[] largestBlockInfo = largestBlock(); + int maxFreeBeginning = largestBlockInfo[0]; + int maxFreeSize = largestBlockInfo[1]; + + if (maxFreeSize == -1) + //No open space found + continue; + + //Find out what ID the job is, and how big it is + int jobID = this.memoryBlock[maxFreeBeginning + maxFreeSize + 1]; + + int jobSize = 0; + int counter = maxFreeBeginning + maxFreeSize; + while (this.memoryBlock[counter] == jobID){ + counter++; + jobSize++; + } + + //Pause the job, and then relocate it + //Note that we need to lock out the allocation to prevent a race + synchronized (this.memoryBlock) { + //Pause the job operation + jobArray[jobID].pause(); + + //Write the job into the free space + int memoryLoc = maxFreeBeginning; + counter = 0; + while (counter < jobSize){ + memoryBlock[memoryLoc] = jobID; + counter++; + } + + //Inform the job of its new beginning location + jobArray[jobID].setBeginningLocation(maxFreeBeginning); + + //Restart the job + jobArray[jobID].resume(); + + //Write the remaining memory as free + counter = 0; + while (counter < maxFreeSize){ + memoryBlock[memoryLoc] = 0; + } + + } + //Sleep for sleepTime, then go back to the top to continue compaction + try { + sleep(sleepTime); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + System.out.println("Error in compaction thread! Algorithm is aborting."); + + //Kill ourselves + this.interrupt(); + } + } } }