Download COS 318: Operating Systems Implementing Threads

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

RSTS/E wikipedia , lookup

Burroughs MCP wikipedia , lookup

VS/9 wikipedia , lookup

Unix security wikipedia , lookup

Distributed operating system wikipedia , lookup

Linux kernel wikipedia , lookup

Spring (operating system) wikipedia , lookup

DNIX wikipedia , lookup

Process management (computing) wikipedia , lookup

Thread (computing) wikipedia , lookup

Transcript
COS 318: Operating Systems
Implementing Threads
Jaswinder Pal Singh
Computer Science Department
Princeton University
(http://www.cs.princeton.edu/courses/cos318/)
Today’s Topics
u 
Non-preemptive versus preemptive threads
u 
Kernel vs. user threads
u 
Too many cookies problem
2
Revisit Monolithic OS Structure
u 
u 
Kernel has its address space,
shared with all processes
Kernel consists of
l 
l 
l 
l 
l 
u 
Boot loader
BIOS
Key drivers
Threads
Scheduler
User
Process
User
Process
Scheduler
l 
l 
l 
Use a ready queue to hold all
ready threads
Schedule in a thread with the
same address space (thread
context switch)
Schedule in a thread with a
different address space
(process context switch)
Kernel scheduler
3
Non-Preemptive Scheduling
Terminate
(call scheduler)
Scheduler
dispatch
Running
Block for resource
(call scheduler)
Yield
(call scheduler)
Create
Exited
Ready
Blocked
Resource becomes available
(move to ready queue)
4
Scheduler
u 
A non-preemptive scheduler invoked by calling
l 
l 
block()
yield()
u 
The simplest form
Scheduler:
save current process/thread state
choose next process/thread to run
dispatch (load PCB/TCB and jump to it)
u 
Scheduler can be viewed as just another kernel thread
5
Where and How to Save Thread Context?
u 
Save the context on the thread’s stack
l 
l 
Many processors have a special instruction to do it efficiently
But, need to deal with the overflow problem
Thread 2
Thread 1
u 
frame
frame
frame
frame
Save the context
of Thread 1 to
its stack
frame
frame
Context
frame
frame
Check before saving
l 
l 
l 
Make sure that the stack has no overflow problem
Copy it to the TCB residing in the kernel heap
Not so efficient, but no overflow problems
6
Preemption
u 
Why
l 
l 
u 
CPU
Interrupts
l 
l 
u 
Timer interrupt for
CPU management
Asynchronous I/O completion
Between instructions
Within an instruction,
except atomic ones
Memory
Interrupt
Manipulate interrupts
l 
l 
l 
Disable (mask) interrupts
Enable interrupts
Non-Masking Interrupts
7
State Transition for Non-Preemptive Scheduling
Terminate
(call scheduler)
Scheduler
dispatch
Running
Block for resource
(call scheduler)
Yield
(call scheduler)
Create
Exited
Ready
Blocked
Resource becomes available
(move to ready queue)
8
State Transition for Preemptive Scheduling
Terminate
(call scheduler)
Scheduler
dispatch
Create
Ready
Running
Exited
Block for resource
(call scheduler)
Yield, Interrupt
(call scheduler)
Blocked
Resource free, I/O completion interrupt
(move to ready queue)
9
Interrupt Handling for Preemptive Scheduling
u 
Timer interrupt handler:
l 
l 
u 
I/O interrupt handler:
l 
l 
l 
u 
Save the current process / thread to its PCB / TCB
Call scheduler
Save the current process / thread to its PCB / TCB
Do the I/O job
Call scheduler
Issues
l 
l 
Disable/enable interrupts
Make sure that it works on multiprocessors
10
Dealing with Preemptive Scheduling
u 
Problem
l 
u 
An obvious approach
l 
u 
Interrupts can happen
anywhere
Worry about interrupts and
preemptions all the time
What we want
l 
l 
l 
l 
Worry less of the time
Low-level behavior
encapsulated in “primitives”
Synchronization primitives
worry about preemption
OS and applications use
synchronization primitives
Concurrent applications
OS services
Synchronization
primitives
Scheduling
and interrupt handling
11
User Threads vs. Kernel Threads
User
Process
User
Process
User
Process
Scheduler
u 
u 
u 
Context switch at user-level
without a system call (Java
threads)
Is it possible to do preemptive
scheduling?
What about I/O events?
Kernel scheduler
u 
A user thread
l 
l 
u 
Makes a system call (e.g. I/O)
Gets interrupted
Context switch in the kernel
12
Summary of User vs. Kernel Threads
u 
User-level threads
l 
l 
l 
l 
l 
u 
Kernel-threads
l 
l 
u 
User-level thread package implements thread context switches
OS doesn’t know the process has multiple threads
Timer interrupt (signal facility) can introduce preemption
When a user-level thread is blocked on an I/O event, the whole
process is blocked
Allows user-level code to build custom schedulers
Kernel-level threads are scheduled by a kernel scheduler
A context switch of kernel-threads is more expensive than user
threads due to crossing protection boundaries
Hybrid
l 
It is possible to have a hybrid scheduler, but it is complex
13
Interactions between User and Kernel Threads
u 
Two approaches
l 
l 
Each user thread has its own kernel stack
All threads of a process share the same kernel stack
Private kernel stack
Shared kernel stack
Memory usage
More
Less
System services
Concurrent access
Serial access
Multiprocessor
Yes
Not within a process
Complexity
More
Less
14
“Too Many Cookies” Problem
u 
u 
Want cookies, but don’t want to buy too many cookies
Any person can be distracted at any point
RoomMate A
RoomMate B
15:00
Look in cabinet: out of cookies
15:05
Leave for Wawa
15:10
Arrive at Wawa
Look at fridge: out of cookies
15:15
Buy a bag of cookies
Leave for Wawa
15:20
Arrive home; put cookies away
Arrive at Wawa
15:25
Buy a bag of cookies
Arrive home; put cookies away
Oh No! Too many cookies.
15
Using A Note?
Thread A
Thread B
if (noCookies) {
if (noNote) {
leave note;
buy cookies;
remove note;
}
}
if (noCookies) {
if (noNote) {
leave note;
buy cookies;
remove note;
}
}
u  Any
issue with this approach?
16
Another Possible Solution?
Thread A
Thread B
leave noteA
if (noNoteB) {
if (noCookies) {
buy cookies
}
}
remove noteA
leave noteB
if (noNoteA) {
if (noCookies)
{
buy cookies
}
}
remove noteB
Didn’t buy
cookies
u  Does
this method work?
Didn’t buy
cookies
17
Yet Another Possible Solution?
Thread A
Thread B
leave noteA
while (noteB)
do nothing;
if (noCookies)
buy cookies;
remove noteA
leave noteB
if (noNoteA) {
if (noCookies) {
buy cookies
}
}
remove noteB
u  Would
this fix the problem?
18
Remarks
u 
The last solution works, but
l 
l 
l 
u 
Life is too complicated
A’s code is different from B’s
Busy waiting is a waste
What we want is:
Acquire(lock);
if (noCookies)
buy cookies;
Release(lock);
Critical section
19
What Is A Good Solution
Only one process/thread inside a critical section
u  No assumption about CPU speeds
u  A process/thread inside a critical section should not be
blocked by any process outside the critical section
u  No one waits forever
u 
Works for multiprocessors
u  Same code for all processes/threads
u 
20
Summary
u 
Non-preemptive threads issues
l 
l 
u 
Preemptive threads
l 
u 
Interrupts can happen any where!
Kernel vs. user threads
l 
u 
Scheduler
Where to save contexts
Main difference is which scheduler to use
Too many cookies problem
l 
What we want is mutual exclusion
21