You are on page 1of 3

Programming for Engineers

Operating Systems

Tutorial M1 Solution - Operating system fundamentals


Question 1
(a) Why do we need operating systems? What functionality do they provide for application
programmers? Create a list of features provided by an operating system.
Operating systems provide an abstraction for the hardware contained in our machine so that
applications can be written to run on any machine the operating system supports. Programmers
write to an OS API which implements many of the functions required.
OSes provide features such as: multi-tasking, networking, hardware abstraction, memory
protection, file system abstractions, security.
(b) How is programming for Windows or Linux environments different than programming under
older environments such as MS-DOS?
In MS-DOS the programmer generally writes directly to the hardware since the OS provides
almost no functionality. In Windows or Linux, you make OS API calls which handle pretty much
everything for you. The programmer can concentrate on the functionality of their application
instead of low level hardware details.

Question 2
Describe in your own words the difference between kernel and user modes required by modern
operating systems.
Kernel mode is where operating system code must run if it needs to talk to the hardware of the
machine or manipulate memory for use by other processors. Kernel mode is sometimes called
supervisor mode, and is used to manage the system. It is important to realise that not all operating
system code needs to run in kernel land, only the code which needs to manage the whole system.
User mode is where everything else runs. Most applications and tools run in user land so that if
they have bugs they will not drag down the rest of the system. Kernel code must be perfect to
protect the machine while it should be impossible to crash the system with rogue user land code.
What CPU feature is used to control the mode of operation, and what operations does it restrict?
CPUs implement a protection register of some kind. It can be a single bit or multiple values which
controls the mode the CPU operates in. In supervisor/kernel mode the CPU can do anything, while
in user mode the CPU prevents operations which write directly to the hardware or modify memory
protection registers.
How can a program switch between kernel and user modes?
When in kernel mode, the CPU is able to perform any kind of instruction, including returning to
user mode by just setting the right register. When in user mode, the only way a program can enter
kernel mode is via an exception, either intentionally executed by the code, or by a hardware
device raising an interrupt.

University of South Australia

Programming for Engineers

Question 3
Explain how shared memory can be used to communicate information between two processes
running concurrently?
Programs can create variables that are visible to multiple processes. When the variable changes
all the other processes which share the same memory will see the change immediately.

Question 4
What is the difference between blocking and non-blocking calls?
Blocking calls put the process to sleep until the resource is available. Non-blocking calls return
immediately with an error code to indicate the resource is not available.
What happens in each case when a resource is not available?
See above.
What type of semantics does Java use for its calls? Give an example.
Java uses blocking calls. Any socket or file based reads/writes are always blocking. Java does not
really have non-blocking calls, although you should say Thread.start() is non-blocking because it
returns immediately.

Question 5
Look at the following source code which waits for a keypress from the user:
print (Press the escape key to exit!);
while (1)
{
char ch = getKeyboardPress ();
if (ch == EscapeKey)
exit ();
}

Explain what occurs if getKeyboardPress() is either blocking or non-blocking? Which one is more
efficient for the rest of the system and why?
If getKeyboardPress() is blocking then it will put the process to sleep in this call until a key is
pressed by the user. This is very efficient because the OS can get other work done while the
process is waiting for input.
If getKeyboardPress() is non-blocking then the CPU will start thrashing around the while(1) loop,
polling thousands or even millions of times per second checking for keyboard events. Each check
will require a system call, which will slow the machine down. The process will attempt to consume
100% of the CPU if available just to check for a key being available. This is obviously a waste of
the CPU and should not be done. Old DOS programs used to be written this way and they did not
run well under Windows 3.0 when it attempted to multi-task many applications.

University of South Australia

Programming for Engineers

Question 6
For this question, imagine the writing of software that would handle the operation of a automatic
bank teller machine (ATM). The code which handles the adjustment of the users account might
look something like the following:
void adjustAccount (int customerId, double withdrawlAmount)
{
double currentBalance = lookupCustomerBalance (customerId, withdrawlAmount); // 1
currentBalance = currentBalance - withdrawlAmount;
// 2
storeCustomerBalance (customerId, currentBalance);
// 3
}

It is possible for the customer to go to two ATMs simultaneously and withdraw money. As the two
withdrawls are being processed, it is possible that the operating system may switch between the
processes and corrupt the bank balance of the customer.
Work through every possible scenario of what the final bank balance could be for the customer
assuming a task switch can occur any time from lines 1-3 in the code.
Lets assume that the user has $1000 in the bank and each user tries to withdrawl $100 from the
account. The correct answer the bank wants is $800. However, due to task switching which can
occur between any of the calls, the result could be $900 in some scenarios. Lets represent the two
processes as A and B, and then work through some possible outcomes:
1A 2A 3A 1B 2B 3B - $800 (Correct)
1A 1B 2A 2B 3A 3B - $900 (Incorrect - this is because B captured the balance before A saved it)
1B 1A 2B 2A 3B 3A - $900 (Incorrect - same as above but A and B swapped around)
There are many other possible combinations. The problem occurs when one process makes a
copy of the balance and then the other process modifies it. So 1-3 must run without interruption or
there will be an incorrect $900 balance.

University of South Australia

You might also like