CO527 Anonymous Questions and Answers |
This page lists the various questions and answers. To submit a question, use the anonymous questions page. You may find the keyword index and/or top-level index useful for locating past questions and answers.
We have taken the liberty of making some minor typographical corrections to some of the questions as originally put. Although most of the questions here will have been submitted anonymously, this page also serves to answer some questions of general interest to those on the course.
Submission reference: IN5055
Hi, I'm getting this error:
DSched.java:140: error: '.class' expected swap(ReadReq[],readqueue_tail,nxt);
I don't know why when my code seems right?:
[snip code]
One problem, though you haven't encountered it yet probably, is related to something in Question 53 (2015), in the mixing of circular-queue and zero-indexed (stack-based) code. However, the code you're feeding to the test-rig really doesn't compile. As suggested, make sure it at least compiles and runs on your own machine before feeding it to the test-rig. The issue is in the way you're trying to call "swap". The first parameter of "ReadReq[]" is nonsense unfortunately — that is a type not an expression. The parameter you probably want is the request-queue array itself, not its type.
Keywords: assess4-1516
Submission reference: IN5053
I believe my logic is completely wrong here? Can you point me in the right direction? I see a lot of code online using Math.abs(). What is the reason for this?
public void readcomplete (int blk, BRequest req) { int[] anArray; anArray = new int[readstack_size]; for(int i = 0; i < readstack_size ; i++) { ... code reading "anArray[i]" ... code dispatching a request } }
Yes, there's something wrong here. The most obvious problem is that you're creating a new array, "anArray" then are blindly reading from it: its contents will be undefined (zero I guess). There's no need to have a separate array however: it's a matter of searching through the request queue looking for the most appropriate one. See Question 37 (2015). The other issue is that the code which dispatches a new request is actually inside the for() loop, thus it will be called for each request, and things will very quickly go badly wrong. The fact this isn't obvious is probably because of the horrible layout — indentation is used so you can see the structure of your code (and mandatory in some languages like Python, occam). Hint: embrace good code layout, it will save you a lot of grief in the long-run :-).
Keywords: assess4-1516
Submission reference: IN5054
Hi, with regards to Question 38 (2015) and Question 48 (2015), I still can't get the swapping right. I have spent hours just looking at it and I feel like it's just simple stuff I'm not seeing or that I have missed?
... inside readcomplete(): if (readqueue_size > 0) { nxtblk (blk); ... dispatch request at readqueue_tail, increment tail&wrap, reduce size } public int nxtblk (int blk) { int n = SOME_LARGE_VALUE; ... some code for (int i = 0; i < readqueue.length; i++){ ... some more code ... something involving "(blk - readqueue[i].blk)", maybe set "n" } return n; swap (blk, n); } public void swap (ReadReq a[], int blk, int nearest) { ReadReq readreq = a[blk]; a[blk] = a[nearest]; a[nearest] = readreq; }
There are a few things wrong with the code, that I've tried to pick out above. However, the code that implements "swap" is not one of them, which looks okay to me (although the parameters are strangely named, given what the method does — parameters should be named in the context of the method/function to which they belong [just two arbitrary array indices], not in the context of where/how that method/function is called).
One problem is how you're using the array: it's partly circular-queue (from tail to head), partly zero indexed up to (size - 1). Use one or the other (I'd suggest getting rid of the circular queue stuff, see Question 52 (2015)).
Another problem is in what you're comparing in "nxtblk": this code compares block numbers, but in the context of disk-scheduling, it should be comparing track numbers, not block numbers. See Question 37 (2015) and Question 34 (2015).
What you set "n" to here, and subsequently return, is essentially a difference in block numbers. Luckily, the code that calls this disregards the return value. You're trying to use "n" for two things I suspect: the smallest difference between the last request and something in the request-queue, and the particular index in the queue where that request is. These are two different things, thus you need two different variables: one to store the smallest distance between the last request and one of the ones in the request-queue; and another to say where in the request-queue that smallest difference comes from (initially an impossibly large value, see Question 46 (2015)).
The last issue, and probably why the swap doesn't appear to work, is that it never gets called; the code in "nxtblk" returns before it's called. But it wouldn't swap the right things anyway unfortunately: it's called with a block number "blk" and a difference in block numbers "n", that it then blindly treats as array indices: this will quickly give you an array-bounds exception. To swap the request at, say, "idx_n" with the last one in a circular-queue, you would do: "swap (readqueue, idx_n, readqueue_tail)"; and a little differently for a zero-indexed queue.
Keywords: assess4-1516
Referrers: Question 55 (2015)
Submission reference: IN5051
I believe I have implemented SSTF for my assignment, code here:
... snip code for(int i = readqueue_tail; i < readqueue_head; i++){ ... code involving "readqueue[i]" }
I was wondering if there was any changes I could make to my code to make it more efficient on the online tests. Sorry if I wasn't allowed to paste code on here. I was just wondering why whenever I tried it was always only a bit better than SSTF on 2 of the tests.
Pasting chunks of code into the anonymous Q+A is less than ideal, as it's always better if the answer is of use to more than 1 person! (usually very specific questions like "what's wrong with my code" are best taken to the lecturer/supervisor in person or via email).
The loop here is broken, in the sense that it doesn't look at all the requests, but isn't broken to the point where it tries to dispatch invalid requests. This is one reason why I suggest not to start with the FIFO code (with its head and tail indices) but start with the LIFO code (that just has a size variable tracking how many things are in the array). For how you can do this correctly with a circular-queue, see Question 28 (2011), but best not to go there if avoidable. The specific situation in your code is that readqueue_head may have wrapped-around the end of the array, and now be less-than or equal to readqueue_tail, so the test "i < readqueue_head" immediately fails, when it ought not to. Only when head > tail will this loop work correctly.
Keywords: assess4-1516
Referrers: Question 53 (2015) , Question 58 (2015)
Submission reference: IN5052
I am getting this error:
java.lang.NullPointerException at DiskSim.disk_readblock(DiskSim.java:821) at DSched.readcomplete(DSched.java:113) at DiskSim.readready_dispatch(DiskSim.java:921) at DiskSim.do_sim(DiskSim.java:1159) at DiskSim.main(DiskSim.java:1307)
this gets highlighted in the DiskSim class: "req.time_read = timenow;". I'm not sure what the cause is, the line of code in DSched is:
DiskSim.disk_readblock (readqueue[readqueue_size].blk, readqueue[readqueue_size].req);
This error is almost certainly caused by "readqueue[readqueue_size].req" being NULL. In turn, that probably means that readqueue_size is an invalid item in the request queue. Given the way this normally works, that would be the case. I.e. if readqueue_size is 5, say, then the valid requests would be from readqueue[0] to readqueue[4] inclusive. And readqueue[5] is invalid. Thus, the correct way to refer to the last valid request if organised this way is with readqueue[readqueue_size - 1].
Keywords: assess4-1516
Referrers: Question 60 (2015)
Submission reference: IN5050
I've based my C-Scan implementation off the LIFO code, and it appears to be working well. However I have to make multiple jumps to high extreme values. I think this is happening because, not all the data has been put into the stack yet, is this a fair assumption or should it find a way to wait for all the data?
That's probably expected. It will depend, of course, on the request file fed to the program. You can look at the two provided, or (even better!) create your own to test this hypothesis. As for waiting for requests, that's a hard one in the sense that it's usually impossible to tell what the best strategy will be: deal with the request(s) you already have, with a possibly large overhead in moving the read/write heads, or wait in the hope some closer requests come in. Of course, by the time you've waited, and no new requests have arrived, it would have been better to have made the other choice. But such is the unpredictable nature (non-determinacy) of this sort of thing. Whilst it's somewhat outside the scope of the assessment, a real OS might employ some form of heuristic, based on past behaviour or how many requests are outstanding. In the context of the assessment, however, don't try and wait — if you have a request to service, service it. I don't think enough of the simulator framework is exposed (in public methods/etc.) to support it.
Keywords: assess4-1516 , disk-scheduling
Submission reference: IN5049
I have implemented the temporary storage method you described in Question 42 (2015) and have got my code for SSTF working to the point where there is only one logical error, which is always on read queue 0. I assume that this is something to do with the first block being sent having no previous block to compare to but am unsure how to fix that or if it is even a correct assumption. hopefully you can shed some light:
highlevel_didread(): read queue 0 already done at time 1095 (block 2048) finished at time 3367 with 1 pending queues disk spent 31 idle, 2864 seeking to track, 472 reading 97 blocks *** had 1 logical errors!
That assumption seems reasonable. In the general case, if the request-queue is empty and new request comes in, readcomplete() will be called with an invalid block number and null request to indicate this. That might be the cause of the error, or it could be something else — if the request-queue got corrupted, that error could be an outcome. Basically you're calling highlevel_didread() with something that it never asked for, or asked for and got previously, so the problem could be in the other half where it's deciding what to dispatch to the disk next, and is dispatching something it should not be (i.e. an old/invalid request).
Keywords: assess4-1516
Submission reference: IN5048
I asked Question 38 (2015) and since then have done some improvement to my code but am still getting errors so am still completely off track with trying to swap at the tail:
public void readcomplete (int blk, BRequest req) ... some code nxtblk(blk); int temp = blk; blk = int nearest.nxtblk; nearest.nxtblk = temp;
Elsewhere in the code:
for (int i = 0; i < readqueue.length; i++) {
Regarding swapping, see Question 42 (2015). The type of T here would be ReadReq, since that's the type of the array: thus, you are trying to swap ReadReq objects around inside the array (or references to those objects), not integer block numbers (this will lead to all sorts of inconsistencies).
The other potential problem is that your code seems to be based on the FIFO code, in that it still has head+tail pointers and modulo arithmetic. The loop you have above is therefore probably broken, as it inspects all elements in that array, regardless of whether they're valid or invalid requests. Solution: get rid of all the head/tail stuff and stick with something that's more like the LIFO version (just a counter for how many things in the array are valid).
Keywords: assess4-1516
Referrers: Question 53 (2015)
Submission reference: IN5046
Does the difficulty of implementing the listed algorithms scale with their efficiency?
A bit perhaps, but not significantly. From the steady stream of people I've seen today, most of the issues are related to actually writing code, not understanding the particulars of the algorithm. It's probably true that things like the elevator, C-scan, etc. are more complicated to implement than SSTF, but not massively (i.e. elevator/C-scan are SSTF but in one direction only).
Keywords: assess4-1516
Submission reference: IN5045
I'm using a large integer (int s_diff = 99999999;) inside my SSTF implementation to compare tracks between blocks, thereby finding the nearest block. I was wondering if this might be an issue as the disk scheduler might not be able to use such large integers? If so, is there a way around this?
My suggestion would be to pick an appropriate value: no distance between any two tracks is going to be more than the number of tracks on the disk, so sensible to use that as an impossibly high starting value (i.e. DiskSim.NTRACKS).
Keywords: assess4-1516
Referrers: Question 53 (2015)
Submission reference: IN5047
Are we allowed to use Math.abs?
See Question 8 (2015).
Submission reference: IN5044
Hiya, I have come across an error that I don't completely understand;
highlevel_didread() : readqueue 7 already done at time 1099 (block 1),
is here any way you could possibly give a hint as to what's going wrong? Thank you!
This is a case of something in your code calling highlevel_didread() with something invalid (block 1 in this instance). Various possible causes, but a typical one would be sending a request to the disk that has already been serviced previously; when it comes back into readcomplete(), the code there will probably just hand it upwards (as a completed read-request) but the problem is likely to do with when it got requested from the disk — i.e. your request-queue has gone bad.
Keywords: assess4-1516
Submission reference: IN5040
highlevel_didread(): read queue 2 got unexpected block 1048500 ...
There are more errors but you get the gist. My current system uses a method I have called update. It takes the parameter of the last block used by the system. The idea is that I store my last block in a variable after the first running of the read complete method. The next time the read complete method is ran it would run my update method which would update some global variables.
[snip code]
See Question 42 (2015). Might be better to come and see me with your code however and I'll see if I can give you some pointers.
Keywords: assess4-1516
Submission reference: IN5043
In reference to Question 38 (2015), I am also attempting to implement an SSTF solution however I am unsure if this method of creating a temporary is what you are looking for:
[snip some stuff] temp1 = readqueue[readqueue_tail].blk; temp2 = readqueue[readqueue_tail].req; readqueue_tail = i; readqueue[i].blk = temp1; readqueue[i].req = temp2;
This will almost certainly not work, for various reasons. You have over-complicated this somewhat however: think about what the code is doing, and what the variable values are (e.g. primitive types or object references). For any array whose elements are of type T, you can swap them with a trivial bit of code (this is something that you should be familiar with, as it's pretty fundamental stuff):
/* swap elements 'i1' and 'i2' of 'a' */ void swappy (T a[], int i1, int i2) { T t = a[i1]; a[i1] = a[i2]; a[i2] = t; }
Note that this doesn't know, nor does it need to know, anything about the structure of type T. It could be an object reference, a primitive type, doesn't matter.
Keywords: assess4-1516
Referrers: Question 43 (2015) , Question 48 (2015) , Question 49 (2015)
Submission reference: IN5041
Can we use code directly from CO518 terminals i.e. the project with different sort implementations?
You can use whatever sorting algorithms you like! As long as it's clear where the code came from (if it came from elsewhere, even if your own on another module). But these things may not be wrapped up in classes: you only submit a single file, DSched.java, so any sorting functionality must be contained within the methods there. No inner classes doing sorts please! But given that most sort algorithms can sit in a single method, that shouldn't be an issue. See also Question 39 (2015).
Keywords: assess4-1516
Submission reference: IN5042
Slight add on to a previous question, i missed out that i have a swap that doesn't seem to do anything. I've been staring at my code for a while now thinking it all makes sense. Is there a reason my swap code doesn't work?
public void swap (int i, int j) { int temp = i; i = j; j = temp; }
This code successfully swaps the two integer parameters, i and j. It doesn't swap anything else (e.g. stuff inside the request queue). If you look at that method in isolation, how could it? (given it has no references to the request-queue).
What you're trying to swap here are not i and j, but the request-queue (array) entries at the ith and jth indices.
Keywords: assess4-1516
Submission reference: IN5039
Could you tell me if I'm the right track please, this is what I have so far:
[snip something that looks like quicksort with bits of the existing DSched code in it]
Short answer, no :(. It looks like you tried to blend quicksort with the existing code that's already there. This isn't going to work. But unless you're trying to be real-time efficient (which isn't necessary for this assessment) sorting isn't needed. What's required is, more or less, searching through the set of queued requests looking for the best/appropriate.
Keywords: assess4-1516
Referrers: Question 41 (2015)
Submission reference: IN5038
I'm trying to do the SSTF implementation, but I can't seem to rap my head around swapping a particular request with the tail. Can you point me in the right direction?
... in readcomplete() somewhere int val = nxtblk (blk); readqueue_tail = val;
"nxtblk" is something that returns the next best block number.
There are two things wrong here. The first is a confusion about what units are involved. As your "nxtblk" returns a particular block number, assigning it to something which is an array index is nonsense unfortunately. If your "nxtblk" returned the index in the read-queue of the next best block, then the assignment to "readqueue_tail" would at least make some sense. But this is the second problem: this is not the way to swap two things in an array. It can't be done in a single operation in Java — you'll need a temporary. What your assignment does is change the value of "readqueue_tail", not change the contents of the array at position "readqueue_tail".
Keywords: assess4-1516
Referrers: Question 42 (2015) , Question 48 (2015) , Question 53 (2015)
Submission reference: IN5036
Could you please tell me if my thought process is correct for SSTF:
You would have two variables (i and j) and you would compare the tail to the last block read and find to find out the track distance and store it in 'i'. Then you would decrement size and increase the tail and then compare that to the last block read and store it in 'i' then you would compare i and j and process the smallest one.
Not quite — there are two separate things here, and they should stay separate. One of them is about finding the next best request to dispatch to the disk (where "best" depends on the scheduling algorithm, SSTF or otherwise). The other is about removing that request from the queue and sending it to the low-level disk (with disk_readblock()).
For SSTF (shortest seek-time first), where seek-time mostly involves the time required to move the read/write heads between tracks, the next best request will be the one that is closest to the last block read. Thus, unless your request-queue is sorted, this will involve searching through it. For that you need a few things: the track number of the last block read (i.e. where the read-write heads are now); a loop (and a loop-variable) to iterate through all the requests in the queue, looking at each one in turn; and some variable to tell you which the best (closest) request so far is. Algorithmically this is a bounded linear search (the concept of which should not be unfamiliar). Once you've found the best, you can then request it from the disk (taking some care of how it is removed from the queue, if it was in the middle of the array).
Keywords: assess4-1516
Referrers: Question 53 (2015) , Question 54 (2015)
Submission reference: IN5035
drive busy, cannot read block 1 at this time! drive busy, cannot read block 2049 at this time! ... highlevel_didread(): read queue 3 got unexpected block 2457601 ...
Why does this happen?
The drive-busy errors probably mean that your code is trying to dispatch a read-request whilst one is already ongoing. Remember that the "readcomplete()" method, where the dispatch happens in the given code, is called when the previously requested block has been read successfully, or when the disk is idle and is ready to accept a new request. But only one new request should be dispatched in response to this. The second kind of error is likely an artefact of the first; this is the high-level code (e.g. an application, or OS file-system) complaining that it got back a block that it hadn't requested (or was otherwise not expecting).
Keywords: assess4-1516
Maintained by Fred Barnes, last modified Wed May 25 15:07:19 2016 |