TDDB63 Nachos - Lesson 1 Introduction Laboratory Sessions

advertisement
Introduction
TDDB63
Nachos - Lesson 1
• Alexandru Andrei
• alean@ida.liu.se
• /liu/ida/eslab
• Course: Concurrent Programming and
Operation Systems
TDDB63
• Homepage: http://www.ida.liu.se/~TDDB63/
check regularly
read messages section
-2-
Laboratory Sessions
Laboratory Assignments
• Lesson 1
– Lab 0: Nachos Overview
– Lab 0: C/C++ Intro
•
– Lab 1: Threads and Synchronization
• Lesson 2
•
– Lab 2: System Calls
• Lesson 3
– Lab 3: Memory Management
-3-
7''% /DEOHVVRQ
Labs build upon
the previous labs
Lab 3 is (usually) the
most time consuming
TDDB63 Lab lesson
TDDB63 Lab lesson
•
•
•
•
SU rooms
Sun machines
C/C++
Check the web page for setting up gcc 2.8.1 (module add
prog/gcc-2.8.1)
•
•
•
•
Be prepared
Tools: emacs(or another editor), gmake, ddd, man
=> No support without using debugger before!
Mark your changes in the source code
-4-
TDDB63 Lab lesson
Laboratory Sessions
• Documentation
Laboratory Sessions
• Marking changes
– A readme file which contains:
• The files you have created and a short description
• The major changes you have made to the given files
– A testcase file which contains:
• Which test cases did you use
• What was the output of the test cases
• What those testcases should demonstrate
-5-
// -----------------------------------------------// 04-01-24: your_name: changed
...
// end of changes
// ------------------------------------------------
TDDB63 Lab lesson
-6-
Laboratory Sessions
• File header
Laboratory Sessions
• Function header
// ==========================================
// TDDB63: Lab 1: solution.cpp
// -----------------------------------------------// Group XYZ: Mister X / Miss Y
// -----------------------------------------------// This module extends Nachos to be able to work
// with semaphores.
// -----------------------------------------------// 00-02-01: misterX: created
// 99-02-12: missY: semSignal: changed signal type
// ===========================================
-7-
7''% /DEOHVVRQ
TDDB63 Lab lesson
TDDB63 Lab lesson
// -----------------------------------------------// int readInput(int file)
// -----------------------------------------------// This function reads continuously from the
// file and returns the number of bytes read
// -----------------------------------------------// Parameters:
// file: handle of the file to read from
// ------------------------------------------------
-8-
TDDB63 Lab lesson
Tips
• “Not Another Completely Heuristic Operating System”
• Free operating system and simulation environment
to study an operating system
• Runs as a single Unix process
(real operating systems run on bare machines)
• Simulates low-level facilities
(including interrupts, virtual memory and interrupt-driven device
I/O)
• Implemented in subset of C++, ca. 2.500 lines of code
• Read documentation and source code
– Nachos Beginner’s Guide (html)
– A Roadmap Through Nachos (pdf)
•
•
•
•
Nachos Overview {}
Use a debugger (gdb / ddd)
Use code browsing tools (emacs, grep)
Use different test cases
Read homepage regularly
• See homepage material and links
• Read/understand source code !!!!!!!
TDDB63 Lab lesson
TDDB63 Lab lesson
-10-
Overview}
• Nachos simulates a machine approximating a real
machines architecture
• Has:
Nachos
code/machine
– Registers, Memory, CPU, interrupts
– Event-driven simulated clock
OS KERNEL
• Can execute arbitrary programs
• Two modes: simulator (running programs)
and “kernel mode” (starting up or reacting on
hardware traps)
-11-
7''% /DEOHVVRQ
code/threads
code/userprog
TDDB63 Lab lesson
*LYHQ
code/test
Test programs
-9-
/DE
-12-
TDDB63 Lab lesson
Machine Object
• Available through variable machine
• Public attributes:
• Nachos simulates interrupts with an event queue and a clock
(clock ticks -> queue is examined for pending events)
• The clock ticks, when ...
– registers
– mainMemory
– virtualMemory
(single linear page and software-managed TLB)
– Interrupts are restored
(used often for mutual exclusion purposes)
– One instruction is executed
– “Ready list” is empty
• Methods: Machine (constructor), Translate (translates virtual
addresses), OneInstruction, Run, ReadRegister,
WriteRegister, ReadMem, WriteMem
=> Read documentation and source code
-13-
Interrupt Management
• Object Interrupt:
– Main methods: Schedule (schedule event), SetLevel (disable / enable),
OneTick
=> Read documentation / source code
TDDB63 Lab lesson
-14-
Real-Time Clock Interrupts
TDDB63 Lab lesson
Address Translation
• Nachos supports two virtual memory architectures:
• Object Timer:
– Simulates a real-time clock
(generates interrupts at regular intervals)
– Methods: Timer (creates a real-time clock, can be
randomly influenced)
– ./nachos –rs #number (nachos –rs 100)
– Linear page tables
(easier to program)
– Software-managed TLB
(closer to what current machines support)
– Only one at a time
• Linear page tables:
– Virtual address: page number and page offset
– Physical address: machine->mainMemory + n * PageSize + m
• Read documentation / source code
-15-
7''% /DEOHVVRQ
TDDB63 Lab lesson
-16-
TDDB63 Lab lesson
Terminal Console Device
• Accessed through low-level primitives (initiated by I/O
operation, performed by an “operation complete”
interrupt)
Disk Device
• Accessed through low-level primitives
(initiated by I/O operation, performed by an “operation
complete” interrupt)
• Object Disk
• Object Console
– Simulates behavior of a character-oriented CRT device
(one character at a time)
– Methods: Console (constructor, connects to files / streams),
PutChar, GetChar, CheckCharAvail
-17-
TDDB63 Lab lesson
Nachos Processes and Threads
Overview
• Process: a user program in execution
• Thread (Nachos): the kernel correspondent of
a user process
Thread
Process
1
Thread
2
Thread
3
OS KERNEL
-19-
7''% /DEOHVVRQ
– Simulates behavior of a real disk
(single platter, multiple tracks containing sectors,
blocks uniquely identified by their sector number)
– Methods: Disk (constructor), ReadRequest (read single sector),
WriteRequest (write single sector), ComputeLatency (used to decide
when to schedule an “I/O complete” interrupt when servicing a read or
write request)
1
Process
2
Process
3
Test
Testprograms
programs
TDDB63 Lab lesson
-18-
TDDB63 Lab lesson
Nachos Processes and Threads:
Overview
• Process:
– Single thread of control (executing the code)
– Other objects (open file descriptors, etc.)
– => program (instructions), data, state information
(memory, registers, etc.)
• Thread (Nachos):
– Address space (memory allowed to reference:
code, stack, heap, dynamically allocated memory)
– Global variables are shared among all threads
(=> synchronisation?, mutual exclusion?)
-20-
TDDB63 Lab lesson
Lab1: Threads
• Nachos threads are in one of four states
– READY
– RUNNING
– BLOCKED
– JUST_CREATED (temporary state)
• The scheduler decides which thread to run next
• Synchronization facilities are provided through
semaphores
Threads and Scheduling
• Scheduler decides which thread to run next
(invoked whenever the current thread gives up the
CPU or an interrupt arrives)
• Ready list (threads which are ready to run)
• Nachos: unprioritized, round-robin fashion
• Object Scheduler methods:
– ReadyToRun(thread_object) -place the thread in ready list
– FindNextToRun
– Run
TDDB63 Lab lesson
-21-
Thread switching
•
•
•
•
Suspend current thread
Save thread state (registers)
Restore state of of thread to switch to
=> function Switch(oldThread, nextThread)
(written in assembly language)
TDDB63 Lab lesson
-22-
Thread Object
• Thread Object methods:
–
–
–
–
–
–
Thread (constructor)
Fork (making thread executable)
StackAllocate
Yield (suspend and select next waiting one)
Sleep (suspend)
Finish (terminate)
• Read documentation / source code
-23-
7''% /DEOHVVRQ
TDDB63 Lab lesson
-24-
TDDB63 Lab lesson
Nachos Threads
void ThreadFunction1(int which);
void ThreadFunction2(int which);
void ThreadTest() {
Thread *t1 = new Thread(“first thread");
Thread *t2 = new Thread(“second thread");
t1->Fork(ThreadFunction1, 1);
t2->Fork(ThreadFunction2, 2);
ThreadFunction(1);
}
void ThreadFunction1(int which){
int num;
for (num = 0; num < 5; num++) {
printf("*** thread %d looped %d times\n", which, num);
currentThread->Yield();
}
}
TDDB63 Lab lesson
-25-
Why Synchronization
int num;
void ThreadFunction1(int which);
void ThreadFunction2(int which);
void ThreadTest() {
Thread *t1 = new Thread(“first thread");
Thread *t2 = new Thread(“second thread");
t1->Fork(ThreadFunction1, 1);
t2->Fork(ThreadFunction2, 2);
}
-27-
7''% /DEOHVVRQ
Nachos Threads (cont.)
-26-
TDDB63 Lab lesson
Synchronisation and Mutual Exclusion
• Mutual exclusion achieved by disabling / enabling
interrupts
• Synchronisation provided through semaphores
• Object Semaphore methods:
– Semaphore (constructor)
– P (decrement semaphore’s counter,
blocking caller if 0)
– V (increment semaphore’s counter,
releasing one thread if any are blocked)
TDDB63 Lab lesson
-28-
TDDB63 Lab lesson
Lab1: Semaphores
• A semaphore is an integer variable, accessible only
by the operations P and V (Claim, and Release)
• P() - decrement the semaphore’s count,
blocking the caller if count is zero.
void Semaphore::P() {
IntStatus oldLevel = interrupt->SetLevel(IntOff) ;
while(value == 0) {
queue->Append((void *)currentThread) ;
currentThread->Sleep() ;
}
value = value - 1 ;
(void) interrupt->SetLevel(oldLevel) ;
};
Wait(S): while S <= 0 do no-op;
S := S -1 ;
Signal(S): S := S + 1 ;
-29-
Lab1: Semaphores - P()
TDDB63 Lab lesson
-30-
Lab1: Semaphores - V()
• V() - Increment the semaphore’s count,
releasing one thread if any are blocked waiting on the
count
void Semaphore::V() {
Thread *thread;
IntStatus oldLevel = interrupt->SetLevel(IntOff) ;
thread = (Thread *)queue->remove() ;
if (thread != NULL)
scheduler->ReadyToRun(thread) ;
value = value + 1 ;
(void) interrupt->SetLevel(oldLevel) ;
};
-31-
7''% /DEOHVVRQ
TDDB63 Lab lesson
TDDB63 Lab lesson
Locks
• A binary semaphore
• Checks that only the thread that acquired the lock
can release it
• Use the Semaphore class + additional stuff
-32-
TDDB63 Lab lesson
Lab1: Lock
class Lock {
public:
Lock(char* debugName);
~Lock();
void Acquire();
// atomic
void Release(); // atomic
bool isHeldbyCurrentThread();
private:
char *name;
// some variables you need
};
-33-
Condition Variables
• Semaphores and Locks are not very efficient when
dealing with multiple resources
P1
Lock1->Acquire();
Lock2->Acquire();
…
Lock2->Release;
Lock1->Release();
P3
Lock2->Acquire();
Lock3->Acquire();
…
Lock3->Release();
Lock2->Release();
Why hold a lock if you can not use it ?
TDDB63 Lab lesson
-34-
Condition Variables (Wait)
• Wait
TDDB63 Lab lesson
Condition Variables (Signal)
• Signal
– Release the lock
– Add the thread to a queue of threads waiting on
this condition
– Go to sleep
– Acquire the lock
-35-
7''% /DEOHVVRQ
P2
Lock3->Acquire();
Lock1->Acquire();
…
Lock1->Release;
Lock3->Release();
TDDB63 Lab lesson
– Take one thread from the list
– Run it (scheduler->ReadyToRun(that thread))
• Broadcast
– Wake up all the threads and let them compete for the
lock
-36-
TDDB63 Lab lesson
Readers&Writers
• Given a file
• Two kinds of processes can access that file:
– Readers
– Writers
• Correct operation:
Readers&Writers
•
•
•
•
•
int counter_for_read;
Lock *lock_for_counter;
Lock *lock_for_readers_writers;
Condition *c_counter;
Condition *c_write;
– several readers can read simultaneously
– Only one writer is allowed to access the file
TDDB63 Lab lesson
-37-
-38-
Readers&Writers
Reader() {
wait(c_counter);
counter_for_read++;
if (counter_for_read==1) wait(c_write);
signal(c_counter);
…..do the reading….
wait(c_counter);
counter_for_read--;
if (counter_for_read==0) signal(c_write);
signal(c_counter);
}
-39-
7''% /DEOHVVRQ
TDDB63 Lab lesson
Readers&Writers
Writer() {
wait(c_write);
…..do the writing….
signal(c_write);
}
TDDB63 Lab lesson
-40-
TDDB63 Lab lesson
Lab 1: Preparation
• Read and understand the partial thread system
(nachos-3.4/code/threads)
• Remember: module add prog/gcc/2.8.1
• Run the test program in the debugger and
follow the state of each thread object
• Compile in the code/threads directory
TDDB63 Lab lesson
-41-
Lab1: Condition
class Condition {
public:
Condition (char * debugName);
~Condition();
void Wait(Lock *conditionLock);
void Signal(Lock *conditionLock);
void Broadcast(Lock *conditionLock);
private:
char *name;
// some variables you need
};
-43-
7''% /DEOHVVRQ
Lab1: Assignment 1
• Implement locks and conditions - when used together
provides the same functionality as monitors
• Write code for the Lock and Condition classes (in
the file ../code/threads/sync.cc)
– Interfaces (class definition) for Lock and Condition
are already defined (in ../code/threads/sync.h)
– No changes to the interfaces should be done. Only
needed variables should be added to the classes
– NB: It should not take too much code for you to
implement all functionality
-42-
TDDB63 Lab lesson
Lab1: Assignment 2
• Test your implementation
– Write a class BoundedBuffer (in the file
code/threads/threadtest.cc) and use it for
producer/consumer communication.
(Silberschatz, p. 172)
– Don’t forget border conditions: empty buffer, full
buffer
– Try several producers and/or consumers
TDDB63 Lab lesson
-44-
TDDB63 Lab lesson
BoundedBuffer
class BoundedBuffer {
public:
BoundedBuffer(int bufsize);
~BoundedBuffer();
int Read();
void Write(int value);
private:
// some variables you need
};
-45-
7''% /DEOHVVRQ
TDDB63 Lab lesson
Download