Nachos Phase 1 Code -Hints and Comments

Slides:



Advertisements
Similar presentations
Operating Systems Semaphores II
Advertisements

– R 7 :: 1 – 0024 Spring 2010 Parallel Programming 0024 Recitation Week 7 Spring Semester 2010.
Practice Session 7 Synchronization Liveness Deadlock Starvation Livelock Guarded Methods Model Thread Timing Busy Wait Sleep and Check Wait and Notify.
Ch. 7 Process Synchronization (1/2) I Background F Producer - Consumer process :  Compiler, Assembler, Loader, · · · · · · F Bounded buffer.
Silberschatz, Galvin and Gagne ©2007 Operating System Concepts with Java – 7 th Edition, Nov 15, 2006 Chapter 6 (a): Synchronization.
1 CENG334 Introduction to Operating Systems Erol Sahin Dept of Computer Eng. Middle East Technical University Ankara, TURKEY URL:
EEE 435 Principles of Operating Systems Interprocess Communication Pt II (Modern Operating Systems 2.3)
Mutual Exclusion.
CH7 discussion-review Mahmoud Alhabbash. Q1 What is a Race Condition? How could we prevent that? – Race condition is the situation where several processes.
CY2003 Computer Systems Lecture 05 Semaphores - Theory.
Programming with Alice Computing Institute for K-12 Teachers Summer 2011 Workshop.
Asteroids Games and Simulations O-O Programming in Java The Walker School The Walker School – Games and Simulations
Threading Part 2 CS221 – 4/22/09. Where We Left Off Simple Threads Program: – Start a worker thread from the Main thread – Worker thread prints messages.
Race Conditions Critical Sections Deker’s Algorithm.
Review: Process Management Objective: –Enable fair multi-user, multiprocess computing on limited physical resources –Security and efficiency Process: running.
1 CS318 Project #3 Preemptive Kernel. 2 Continuing from Project 2 Project 2 involved: Context Switch Stack Manipulation Saving State Moving between threads,
Synchronization Principles. Race Conditions Race Conditions: An Example spooler directory out in 4 7 somefile.txt list.c scores.txt Process.
Home: Phones OFF Please Unix Kernel Parminder Singh Kang Home:
Monitors CSCI 444/544 Operating Systems Fall 2008.
Stacks. 2 What is a stack? A stack is a Last In, First Out (LIFO) data structure Anything added to the stack goes on the “top” of the stack Anything removed.
CPS110: Implementing threads/locks on a uni-processor Landon Cox.
Race Conditions CS550 Operating Systems. Review So far, we have discussed Processes and Threads and talked about multithreading and MPI processes by example.
U NIVERSITY OF M ASSACHUSETTS, A MHERST Department of Computer Science Emery Berger University of Massachusetts, Amherst Operating Systems CMPSCI 377 Lecture.
Heapsort Based off slides by: David Matuszek
Nachos.
Programming with Alice Computing Institute for K-12 Teachers Summer 2011 Workshop.
Iteration. Adding CDs to Vic Stack In many of the programs you write, you would like to have a CD on the stack before the program runs. To do this, you.
Not Another Completely Heuristic Operating System
Chapter 11 Heap. Overview ● The heap is a special type of binary tree. ● It may be used either as a priority queue or as a tool for sorting.
Java Threads. What is a Thread? A thread can be loosely defined as a separate stream of execution that takes place simultaneously with and independently.
1 Web Based Programming Section 8 James King 12 August 2003.
Games Development 2 Concurrent Programming CO3301 Week 9.
1 Announcements The fixing the bug part of Lab 4’s assignment 2 is now considered extra credit. Comments for the code should be on the parts you wrote.
Synchronized and Monitors. synchronized is a Java keyword to denote a block of code which must be executed atomically (uninterrupted). It can be applied.
Kernel Locking Techniques by Robert Love presented by Scott Price.
ICS 313: Programming Language Theory Chapter 13: Concurrency.
CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.
Java Thread and Memory Model
(c) University of Washington16-1 CSC 143 Java Linked Lists Reading: Ch. 20.
CS399 New Beginnings Jonathan Walpole. 2 Concurrent Programming & Synchronization Primitives.
Monitors and Blocking Synchronization Dalia Cohn Alperovich Based on “The Art of Multiprocessor Programming” by Herlihy & Shavit, chapter 8.
M1G Introduction to Programming 2 3. Creating Classes: Room and Item.
Problems with Semaphores Used for 2 independent purposes –Mutual exclusion –Condition synchronization Hard to get right –Small mistake easily leads to.
CS533 – Spring Jeanie M. Schwenk Experiences and Processes and Monitors with Mesa What is Mesa? “Mesa is a strongly typed, block structured programming.
U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Computer Systems Principles Synchronization Emery Berger and Mark Corner University.
Operating Systems CMPSC 473 Signals, Introduction to mutual exclusion September 28, Lecture 9 Instructor: Bhuvan Urgaonkar.
Implementing Lock. From the Previous Lecture  The “too much milk” example shows that writing concurrent programs directly with load and store instructions.
CSCI1600: Embedded and Real Time Software Lecture 17: Concurrent Programming Steven Reiss, Fall 2015.
Implementing Mutual Exclusion Andy Wang Operating Systems COP 4610 / CGS 5765.
Mutual Exclusion -- Addendum. Mutual Exclusion in Critical Sections.
Embedded Real-Time Systems Processing interrupts Lecturer Department University.
© Janice Regan, CMPT 300, May CMPT 300 Introduction to Operating Systems Mutual Exclusion Mutexes, Semaphores.
CS162 Section 2. True/False A thread needs to own a semaphore, meaning the thread has called semaphore.P(), before it can call semaphore.V() False: Any.
Tutorial 2: Homework 1 and Project 1
CS703 – Advanced Operating Systems
Background on the need for Synchronization
January 29, 2004 Adrienne Noble
Lecture 25 More Synchronized Data and Producer/Consumer Relationship
Lecture 14: Pthreads Mutex and Condition Variables
Multithreading.
Dr. Mustafa Cem Kasapbaşı
Implementing Mutual Exclusion
CSCI1600: Embedded and Real Time Software
Implementing Mutual Exclusion
Lecture 14: Pthreads Mutex and Condition Variables
CSE 153 Design of Operating Systems Winter 19
CS333 Intro to Operating Systems
CSCI1600: Embedded and Real Time Software
CSE 451 Section 1/27/2000.
“The Little Book on Semaphores” Allen B. Downey
Presentation transcript:

Nachos Phase 1 Code -Hints and Comments

Task I –Implement join() Join method: Should have a test to prevent a thread from trying to join itself. Interrupts should be disabled – they must be disabled before calling sleep(). The calling thread is the current thread and it must be stored so that it can be awoken later. I think it’s a good idea to store the threads in a list so that more than one thread can join a given thread. The documentation seems to suggest that a thread can only be joined once, so I didn’t take marks off for not handling multiple threads, although this seems an unnecessary limitation. You may find having multiple threads join a thread useful in testing.

Task I (continued) Don’t forget to wake the sleeping thread(s). This should happen in the finish method. The sleeping threads should be moved back to the ready queue by calling the ready() method. Some groups put the code to wake the thread in the restoreState method just before the thread was destroyed. This should work as well, since the finished thread should be destroyed by the next thread. In general though, the time a thread finishes and the time it is destroyed may not be the same, so I think it is better to put the code in the finish method.

Task II Implement Condition2 This task was generally well done. Make sure to check that the current thread has the lock for all methods. The sleep method stores the threads waiting on this condition in a queue. After waking the thread must re-acquire the lock. Interrupts should be disabled to make the operation atomic. The wake methods removes the first element in the queue (unless the queue is empty) and puts it back on the ready queue. Again, interrupts should be disabled to make the operation atomic. The wakeAll method is similar, but instead of waking just one thread it wakes all the threads in the queue.

Task III Implement waitUntil method The waitUntil(long x) method must first determine the wake time of the thread by adding x to the current time. The waiting threads must be stored in a queue. The most efficient method is to use a priority queue so the whole queue doesn’t have to be searched. Remember, the timerInterrupt method is called every 500 ticks, so it should be efficient. The problem is that we have to store both the thread and the wake time. One way to do this is to create a new class, consisting of the thread and the wake time, that implements the Comparable interface. Then implement the compareTo method to allow objects of this type to be sorted by the wake time. (You should have learned how to do this in the Data Structures course).

Task III (continued) Java now has a priority queue (as of version 1.5) but nachos doesn’t use java 1.5 so you won’t be able to use it. The priority queue can also be easily implemented with a linked list – just insert the objects in ascending order. Other groups used heaps or Treesets to implement the priority queue. These methods should work as well. If a priority queue is used, the timerInterrupt can use a while loop to wake the threads whose wake time is less than the current time.

Task IV Implement Communicator This is the most difficult of the tasks. One key to getting this class to work is to understand how different variable types work in threads. In a context switch the variables on the stack are saved for each thread. These include the parameters and local variables. This means that parameters and local variables are unique for each thread. In contrast, data on the heap is global to all threads. This includes any instance variables. Since in this class we must pass data from the speaker to the listener we need to use an instance variable to do this.

Task IV (Continued) The speak(int word) method: One detail to determine, is whether the speaker should transfer the message (i.e. move the word from the parameter to the instance variable) before or after going to sleep on the condition. If we move the message before going to sleep we have the problem of it being overwritten by another speaker before it is picked up by a listener. Remember that the sleep method in the condition class releases the lock. This means a number of speakers can be waiting on the condition at the same time, so we must ensure that their messages don’t get lost. The way our group got around this was to store the messages in a queue. However, Doctor Passi doesn’t like this method, so I will suggest another method.

Task IV (Continued) If the speaker can’t store the message before going to sleep, it must do it after waking. This requires a compound condition; the speaker must sleep while either there are no listeners or the message from the previous speaker has not yet been picked up by a listener (this will require a boolean instance variable). Once the speaker exits the while loop it can leave its message and set the boolean variable to indicate that there is a message to pick up because it knows there is at least one listener waiting. It then wakes a listener and exits.

Task IV (Continued) The int listen() method: After entering the critical region, the listener increments the counter keeping track of the number of listeners waiting. It then wakes a speaker (if there is one). This ensures that if a speaker was only waiting for a listener (no message waiting from the last speaker) it will be woken. The listener must sleep while there is no message to pick up (the boolean variable). On exiting the while loop it decrements the number of listeners waiting and can pick up the message. The message should be moved to a local variable. This is because the listener must release the lock before returning. This means the instance variable containing the message might be overwritten before the listener returns the message. After moving the message to a local variable, the listener sets the boolean variable to indicate the message has been picked up (no message waiting). Then wake up a speaker (if there is one), since there may be a speaker waiting only for the boolean flag (there are other listeners). The listener can then release the lock and return the local variable.

Task IV (Continued) You should just use one lock, but it’s probably simpler to use 2 condition variables, one for the speakers and one for the listeners, if you use this method.

Task V Implement ReactWater This task was well done by all groups, so I have no additional comments to make.

Additional Comments Test Cases Its important to think about how to test your code. The test cases should include both what you want to test and an outline of how you are going to test it. You should test both normal conditions and any special cases.

Compiling The Code The group0X/nachos (X is your group number) directory contains the file Makefile. This file contains the names of the source files to be compiled listed by directory. To get it to compile ReactWater type ReactWater in the threads section. E.g. threads = ThreadedKernel KThread Alarm \ Scheduler ThreadQueue RoundRobinScheduler \ Semaphore Lock Condition SynchList \ Condition2 Communicator Rider ElevatorController \ PriorityScheduler LotteryScheduler Boat ReactWater Add any other new classes in here as well. To compile, go to directory group0X/nachos/proj1 and type gmake. To run nachos key in nachos in the same directory (group0X/nachos/proj1).

Where to put Your Test Code When nachos starts up it calls ThreadedKernel (in the threads directory). ThreadedKernel has a method called selfTest. You can add your testing code here. Probably the cleanest way to do this is to have selfTest methods in each of the classes and call these methods. –i.e. in ThreadedKernel’s selfTest add: Condition2.selfTest(); ReactWater.selfTest(); etc. Add the test code to the selfTest method in each class.

Testing When the main thread ends, nachos will shut down. This isn’t supposed to happen. According to the documentation it should wait for all threads to finish. This easiest way to get around this problem is to have the main thread join each test thread, so the main thread doesn’t end until all test threads have finished. This won’t work if your join is limited to one thread, which is one reason I recommend keeping a queue of joined threads in task I.