SYSC 5701 Operating System Methods for RealTime Applications - PowerPoint PPT Presentation

1 / 50
About This Presentation
Title:

SYSC 5701 Operating System Methods for RealTime Applications

Description:

SYSC 5701. Operating System Methods for Real-Time Applications. Threads ... hooks in to timer interrupt interrupt: 1/10 second. returns status OK or SYSERR ... – PowerPoint PPT presentation

Number of Views:68
Avg rating:3.0/5.0
Slides: 51
Provided by: trevorw
Category:

less

Transcript and Presenter's Notes

Title: SYSC 5701 Operating System Methods for RealTime Applications


1
SYSC 5701Operating System Methods for Real-Time
Applications
  • Threads
  • Winter 2009

2
Recall Process Creation
  • allocate code, data, and stack to the process
  • other resources too? (I/O devices?)
  • allocate a thread of control
  • managed by the kernel

3
Code, Data, Stack
  • what if processes replicate behaviour?
  • execute the same code?
  • will memory manager permit this?
  • in a strict process model
  • processes do not share memory
  • each must have its own copy of code data and
    stack space

4
Heavyweight Process
  • a heavyweight process requires all of the above
    code, data, stack
  • heavyweight processes are strict
  • do not share resources

5
Lightweight Processes
  • can share code and data
  • must have own stack and thread of control
  • less overhead during lightweight kernel activity
  • faster context switch and IPC ?
  • application programmers must manage sharing of
    data ?

6
Application Design Philosophy
  • heavyweight processes encapsulate large-grained
    parallel activities that are loosely coupled
  • i.e. interact infrequently, minimal data sharing
  • lightweight processes encapsulate finer-grained
    parallel activities that are tightly coupled
  • i.e. interact frequently, lots of data sharing

7
Performance Goals
  • heavyweight switching and IPC
  • ? more expensive
  • looser coupling less heavyweight IPC and
    switching
  • lightweight switching and IPC
  • ? less expensive
  • tighter coupling more lightweight IPC and
    switching

8
Thread
  • A thread is a lightweight process created in the
    context of a heavyweight process
  • only the threads in the context of the same
    heavyweight process can access the code and data
    of that process

9
Thread Management
  • by kernel
  • outside of kernel
  • hybrid developing trend!

10
1. Threads Managed by Kernel
  • kernel has two classes of processes
  • lightweight (thread) and heavyweight (process)
  • different services for each
  • threads of a process are autonomous
  • a thread may become blocked, but just that thread
    is blocked (not the entire process)

11
Kernel Managed Threads
  • heavyweight process does not really execute as a
    single thread of control
  • ? a container for managing threads
  • the process has a set of threads
  • the active elements of the process
  • kernel manages both process and thread scheduling

12
2. Threads Outside of Kernel
  • process has single thread of control
  • managed by kernel
  • single control thread is shared among threads
  • managed by thread manager
  • unknown to kernel!
  • this sort of thread called user-thread (fiber?)
  • thread manager resides outside of kernel
  • often a run-time library supplied by
    language/environment vendors

13
User Threads
  • if strict process model each process must have
    its own copy of thread manager (no code sharing!)
  • if a thread makes an IPC call via the kernel and
    becomes blocked
  • ? kernel blocks the process ! ?
  • (kernel has no knowledge of threads!) ?

14
3. Hybrid Threads
  • thread concept known to kernel, but user-threads
    are managed outside of kernel
  • thread scheduler and kernel cooperate scheduler
    thread for the process is known to the kernel
  • special interactions supported between scheduler
    thread and kernel

15
Hybridcont
  • when a thread invokes a kernel service and is
    blocked
  • kernel pseudo blocks thread records relevant
    blocking criteria, but instead of blocking
    process ...
  • kernel returns control to relevant scheduler
    thread
  • scheduler thread blocks the thread (outside of
    kernel!) and schedules a different thread
  • net result thread is blocked, process not
    blocked
  • when criteria met to unblock original thread
  • kernel informs relevant scheduler thread
  • scheduler thread unblocks the thread and makes
    thread scheduling decisions

16
Hybrid Thread Blocking
process
user threads
scheduler thread
blocking call
notify scheduler thread
kernel
save info
17
Thread Scheduling Issues
  • time-slice ?
  • suitability to real-time apps ?
  • preempt vs. non-preempt
  • voluntary relinquish?
  • all the same-old issues
  • priority? timed services? etc.

18
Extended Process Model with Threads
heavyweight kernel processes
user threads
? ? ?
? ? ?
? ? ?
lightweight processes (kernel threads)
19
Kernel-Mode Threads/Processes
  • common in large, general-purpose o/s
  • not as common in real-time applications
  • modern o/s often manage I/O subsystems
  • e.g. disk I/O subsystem
  • require supervisor permission to access
    restricted I/O devices
  • must execute in kernels supervisor context

20
O/S Layer Above Kernel
  • may include processes that are not visible
    outside of the o/s but exist inside the o/s
  • these processes are created (and run) in the
    kernels context to permit access to restricted
    h/w
  • called kernel-mode processes

21
Kernel-Mode Process Layer
application processes

kernel-mode processes
kernel
22
Similar Thread Trend
  • when process invokes kernel service kernel
    blocks process and creates a kernel-mode thread
    associated with the request
  • new thread has unique stack (in kernels space)
    shares access to kernel code and data
  • must have enough stack space reserved in kernel
    to permit a kernel-mode thread for each process ?
  • kernel-mode thread executes with supervisor
    privileges on behalf of the requesting process

23
Kernel-Mode Threads
  • kernel manages kernel-mode threads
  • kernel threads can be preempted
  • more concurrency
  • still need to protect access to kernels shared
    data structures!
  • has overheads! ?
  • hasnt hit real-time kernels in a big way (yet)

24
Threads ExampleCU Threads
  • developed by Prof. John Neilson, SCS, Carleton
    Univ.
  • POSIX-like threads
  • library of C functions that manage threads
  • allows concurrent threads running on a single CPU
  • preemptive or non-premptive priority
  • threads run-until-block/exit/yield
  • user-defined C functions provide thread
    functionality

25
CU Threads (more)
  • timed service sleep
  • must disable timer to do I/O
  • e.g. C printf implementation uses underlying
    run-time support (DOS ?)
  • DOS has no guarantee of re-entrant, protected I/O
    access ?
  • loss of timing accuracy?

26
Sync Comm
  • supports semaphores for synchronization
  • may use shared memory for thread communication
  • recall shared memory assumed by threads!

27
Partner Sync. Concept
  • can attach threads to create partnerships
  • each thread can have, at most, one attached
    partner
  • partners cooperate to accomplish objectives
  • additional synchronization support beyond
    semaphores

28
Some CU Thread Management Primitives
  • cu_thread_fork fork a thread from the current
  • thread starts a new unattached thread
  • new thread has no partners partnerless
  • cu_thread_attach thread becomes partner
  • cu_thread_detach thread becomes partnerless
  • any previously attached partner is
    disassociated
  • cu_thread_join merge with (i.e. wait for
    termination of) partner thread
  • ? synchronization !

29
Primitivescont
  • cu_thread_exit terminate thread and wait for
  • partner to terminate (LIMBO state)
  • cu_thread_yield voluntary yield of processor
  • cu_thread_priority dynamically change threads
    priority
  • cu_thread_sleep sleep for a specified duration
  • cu_sema_alloc create a semaphore
  • cu_sema_free delete a semaphore
  • cu_sema_wait wait on a semaphore
  • cu_sema_signal signal a semaphore

30
CU Thread State Machine (non-preemptive)
yield
exit detached
DONE
forced transitions
yield, sleep, exit, wait, join
fork
READY
RUNNING
join
exit ! detached
self transitions
wait
signal
LIMBO
join
WAIT
sleep
time resolution approx. 1/10 sec
exit
JOIN
timeout
SLEEP
31
CU Threads Implementation
  • threads managed in a fixed size array of control
    blocks
  • cu_thread_t thread_table Max_Threads
  • each thread control block (entry in thread_table)
    is a struct
  • thread id index of tcb in thread_table

32
Thread Control Block
FREE, RTR, etc. (recall other possible state
values)
state
critical flag
boolean
initially to a function with one integer
argument
code pointer
int arg
stack base pointer
context
context save buffer
priority
table index used to link control blocks in a
list
next
joiner
table index of thread to join
value
several purposes thread memory (sleep ticks,
return value, etc.)
queue
if blocked index into semaphore table where
thread is blocked
33
Other Manager Variables
  • int thread_count active thread count
  • cu_thread_t cpt pointer to active
    thread control block
  • int rtrq index of first thread in rtr
    queue
  • int sleepq index to first sleeping
    thread
  • int preempt flag indicates if preemption
    used

34
Semaphores
  • semaphores also managed in a fixed size array of
    control blocks
  • semaphore struct

state
FREE, USED
first
index of first thread blocked
last
index of last thread blocked
value
counter value
35
(Some) Thread Primitives In More Detail
  • int cu_thread_init( int preempt_flag )
  • must be called once when main code of process
    runs
  • initializes thread manager variables
  • converts main into a thread
  • creates an idle thread
  • busy waiting for each process ??
  • hooks in to timer interrupt interrupt 1/10
    second
  • returns status OK or SYSERR

36
Fork (Create) Thread
  • int cu_thread_fork( void (code )(int arg), int
    arg )
  • forks a new UNATTACHED thread
  • new thread is READY put into rtrq
  • finds a FREE thread control block
  • returns thread id or SYSERR
  • initializes control block for new thread
  • priority same as current thread

37
Forkcont
  • if stack not yet allocated (for control block),
    then get space from heap will reuse space!
    only allocated once all given back when process
    is destroyed
  • set stack pointer to bottom of stack space
  • new thread is placed in wrapper
  • ? ensures thread calls exit after termination
  • static void wrapper ( )
  • ( (ctp ? code ) ) (ctp ? arg ) ?
  • cu_thread_exit ( OK )

38
Thread Detach
  • int cu_thread_detach ( int tid )
  • thread (tid) is DETACHED
  • if thread already in LIMBO then delete it
  • thread control block is FREE to be re-used
  • stack already allocated reuse stack
  • returns OK or SYSERR

39
Thread Join
  • int cu_thread_join ( int tid )
  • merge with thread tid (wait for thread tid to
    exit)
  • if tid is already in LIMBO then cleanup tid and
    return tids value (termination code from
    control block)
  • (else) tids joiner (in control block) current
    thread id
  • and current thread state JOIN (blocked
    waiting)

40
Thread Exit
  • void cu_thread_exit ( int exit_status )
  • terminate thread and wait for partner (?) to
    terminate
  • if DETACHED this is call from wrapper done!
  • once DETACHED can never ATTACH again
  • if ATTACHED or UNATTACHED (possible later
    attachment?) go into LIMBO and save exit_status
  • save exit_status in value field of control block
  • must be explicitly called by process main
    before main terminates (why? main does not use
    wrapper!)

41
Yield Processor
  • void cu_thread_yield ( )
  • voluntary yield of processor
  • put process in rtrq
  • schedule new process from front of rtrq

42
Set Thread Priority
  • void cu_thread_priority ( int tid, int priority )
  • dynamically changes tids priority
  • if tid in rtrq may result in change in position
    in rtrq
  • if preemption used may result in thread context
    switch

43
Thread Sleep
  • void cu_thread_sleep ( int duration )
  • caller goes into sleepq (blocked)
  • duration of 1/10 of second ticks to sleep
  • duration 0 ? yield
  • thread is in (at most) one queue next field in
    control blocks used to link threads (regardless
    of which queue)
  • value field in control block used for relative
    time management in sleepq

44
Create Semaphore
  • int cu_sema_alloc ( int value )
  • create a semaphore find FREE one in semaphore
    table
  • initial counter value value
  • returns semaphore id (table index) or SYSERR

45
Semaphore Wait
  • void cu_sema_wait ( int sid )
  • wait on semaphore sid
  • if sids counter value gt 0 then decrement and
    continue
  • if sids counter value lt 0 then BLOCKED put
    thread into sids queue

46
Context Switching
  • must save some registers
  • high-level languages often require only a subset
    of registers be respected/protected
  • e.g. Borland C on 8086 (cu threads target)
  • must save CSIP, DS, SSSP, BP
  • SI and DI if use register variables
  • AX, BX, CX, DX no useful values maintained
    between C statements

47
Borland C Example
  • optimizations? assume non-preemptive
  • if compile in small memory model
  • CS, SS and DS never change
  • if no register variables
  • ? no need to save SI and DI
  • context switch, only need to save
  • BP, SP ? (IP saved in call to manager)

48
BUT . . . What about Timer Interrupts?
  • could interrupt at any point perhaps in the
    middle of a high-level language statement? (all
    registers might have useful values)
  • CU thread package provides only sleep as timed
    service when timeout, thread goes READY and
    into rtrq must protect sleepq rtrq access!
  • if preemption allowed context switch must be
    more thorough
  • if preemption allowed all thread package
    services must be protected

49
Timer and Protecting CU Thread Services
  • at start of each service current threads
    critical flag (field in control block) set TRUE
  • at end of each service critical flag set FALSE
  • thread timer ISR maintains a variable called
    missed
  • in ISR checks to see if current thread is in
    critical code if yes, increment missed (to
    indicate missed time service that tick) and exit
  • i.e. missed

50
CU Thread Time Resolution?
  • if timer not interrupting critical code
    decrement number of ticks left for first thread
    in sleepq by
  • 1 missed, then reset missed 0
  • relative time management issues?
  • ends up with sloppy timing, but minimal
    overhead
  •  
  • hmm . . . practical?
  • realistic timing resolution?
Write a Comment
User Comments (0)
About PowerShow.com