The University of Queensland Homepage
School of ITEE ITEE Main Website

 COMP3300 - Operating Systems Assignment 1 2005


COMP3300 – Assignment 1 2005

Updated on Tuesday, 3 May 2005 at 5:02 PM
COURSE PROFILE

LECTURE NOTES

ASSIGNMENTS
First assignment
Second assignment

TUTORIALS

CONTACT
email to
<comp3300@itee.uq.edu.au>
Lecturer
Philip Machanick

<philip@itee.uq.edu.au>

EXAM
TBA

ITEE
 

Tutors
Timothy Brown <s4006402@student.uq.edu.au>
Richard Woon <woon@itee.uq.edu.au>


What’s New:

A solution is available. The solution is not necessarily worth 100% (e.g., it could use more comments on some details) but aims to illustrate:

  • how to use the supplied interfaces
  • relatively simple approach to the problem


General Feedback on Assignment 1

Try to use the interface provided. Some members of the class pretty much redefined given functions which you could have called from the existing code.

If you do define functions or variables (at the top level of the C file; variables defined within a function are not a problem) be sure to define them as static. If you do not make them static, their names could conflict with names in other C files.

Sorting the schedules in order of burst time was not a particularly useful step because only those schedules up to the current time should have been considered. Most of those who sorted did not correctly handle cases like a gap when nothing should be scheduled, or when the shortest job hadn’t arrived early enough to start.

To facilitate sorting, one approach was to put the data in an array rather than use the given list structure. Organizing the array as a 2-dimensional array with a row representing process id, arrival time and burst time as positions [row][0], [row][1] and [row][2] is terrible programming style. It’s not obvious what each element of the array is for, requiring tedious commenting for the program to make sense, and process id, arrival time and burst time are coincidentally similar types of data, but this need not be so (for example, it may make sense in some situations for the process ID to be a 16-bit unsigned value, arrival time to be a 64-bit value and burst time a 32-bit value). Grouping related data is what structs were invented for. Given that you already have the data in a list, one approach would have been to implement an array of pointers to the data in the list. Another would have been to copy the data over to an array of a suitable struct type.

An array of a struct type is easy to use once you have the struct type defined. For example

typedef struct {
unsigned id, arrivalTime, burstTime;
} ProcessInfo;

ProcessInfo processSchedules [N];

You can assign struct values from another struct of similar type, but comparing struct values is not a feature of C. You need to write your own comparison code for each struct type. Structs are passed as parameters (“arguments” in C terminology) by copying the whole struct. If the struct is large, or you want the option of altering the original data, you need to create a pointer to the struct (assuming it’s not already allocated via a pointer) using “&”, e.g.,

void swap (ProcessInfo *first, ProcessInfo *second) {
ProcessInfo temp = *first;
*first = *second;
*second = temp;
}

Call by (e.g. – noting use of “&” to pass pointers to the structs):

swap (&processData[i], &processData[j]);

Can you explain why temp is defined as type ProcessInfo, not ProcessInfo* ?

You may wonder about the alternative notation in which you put a name after the word “struct”, e.g.:

struct ProcessInfo {
// same as before
};

This creates a type called “struct ProcessInfo”. In this case, “ProcessInfo” is called a tag and is not a type name on its own. Using the typedef is more convenient because you don’t have to keep on typing “struct”. However there is one case where you do need to use the tag notation: when you are creating a struct with a pointer inside to itself (typically for types like lists and trees). In this case, the typedef is not complete when you hit the pointer definition, which freaks out the compiler.

You need in cases like that to do something like this:

typedef struct TreeNode {
  struct TreeNode *left, *right; void * data;
} TreeNode;

From here on you can refer to the type as either TreeNode or struct TreeNode (to be even more confusing, the type and tag names need not be the same, e.g., struct TN and TreeNode could be alternative names for the same type).

Isn’t C fun?