CS452 - Real-Time Programming - Fall 2011
Lecture 33 - CSP Servers
Public Service Annoucements
- Final demo: Tuesday, 6 December, 2011; Wednesday, 7 December, 2011
- Demo I starts at 10.00 on Tuesday
- Demo I ends at 13.00 on Tuesday, say 14.00 because we often run
overtime.
- Demo II starts at 10.00 on Wednesday
- Demo II groups have 20 hours of exclusive track use from end of
Demo I to the start of Demo II
- Therefore, Demo I groups should have 20 hours of exclusive track
use.
- From 14.00 on Monday to 10.00 on Tuesday only groups showing their
demos during Demo I may use the trains lab.
- Final exam: 10.30, Friday, 9 December, 2011 to 13.30, Saturday, 10
December, 2011.
CSP
Basics
Primitives
In CSP there are two communication primitives. In the notation of occam
2/Go, they are
- read
keyboard ? ch
ch = <- keyboard
- reads from an input channel called
keyboard and
assigns what it reads to the variable ch
- the channel must have an associated type, and the type must match
the type of the variable.
- That is, the channel and the variable must be in the same
scope.
- read blocks until input is available on the channel
- write
keyboard ! duh
keyboard <- duh
- writes the value of the variable
duh into the channel
keyboard
- write does not block
- Thus, a read/write pair guarantess that read in the reading process
occurs simultaneously with or after the corresponding write in the
writing process.
The communication primitives require something new, called a channel.
CHAN OF CHAR keyboard
keyboard chan char
- A channel is a first in/first out silo.
- Each channel has a protocol that states the type that messages it
handles must have.
- Knowing the name of a channel is essential for using it.
- Applications control who can be on the other end of a channel,
which is essential for security, by controlling who knows the name of
the channel.
How are these primitives provided?
- By the operating system
- Usable by all
- Can have efficient implementation
But
- Abstraction boundary overhead
- No static type checking
- By a programming language
- No abstraction boundary
- Type safety by scoping
But
- Elaborate run-time system needed, which is a layer between the
application and the operating system.
The Transputer
Use many co-operating, medium capability microCPUs to do a big job.
- An idea whose time has now come.
- Google
Problem is communication
Communication requires either
- a common bus, star topology
- system bus (= shared memory)
- LAN
- a common channel, over which users pass messages in real-time
- wasteful of bandwidth
- analogue telephony
- passing messages along
- emphasizes the switches (bridges) that connect common buses
- really more like a hybrid, which is classified differently based on
the level of abstraction.
What about real-time?
- lots of timer (countup) hardware
- interaction of countdown and countup to make your clock server
- Instances of timers are not guaranteed to be synchronized
- How could two timers be synchronized?
The transputer was an early, now vanished, example of a real-time system
based on plentiful small granularity communication. Your kernel is another
example.
- Your kernel: communication based on shared memory, which is easy to
program, hard to make secure.
- The transputer: communication based on switch mediated packets, which
is hard to program, easy to make secure.
Transputer hardware
- CPU, memory, switch on one chip
- chips connected in an array
- presumably a run-time system decides where tasks will go in order to
- maximize CPU throughput
- minimize communication overhead
Occam 2
Basic idea
- processes (tasks)
- may be named, take arguments and return values
- may be combined
- CSP channels
- time
Combining processes
- sequential
- conditional
- if/then
- selection by case
- looping
- without test/break
- with test/break
- parallel
- initiated when the keyword PAR occurs.
- alternation
- guarded alternatives
- if more than one guard is true then select at random
Time
Can you Build a Server with Type-Checking?
Outer
Scope
|
| CHAN OF REQUEST request
|
| Server
| Scope
| |
| | REQUEST sreq
| | CHAN OF REPLY srep
| |
| | request ? sreq
| | srep := sreq.reply
| |
| | srep ! sresult
| |
| |
| |
| Client
| Scope
| |
| | REQUEST creq
| | CHAN OF REPLY crep
| |
| | creq.reply := crep
| | request ! creq
| |
| | crep ? cresult
| |
The Result
You can write a type-safe server, BUT
- all possible clients must be in the same scope in order to get static
type checking
- with dynamic, structural type checking you only need to have the tasks
written in languages having the same type system
BUT
- with this structure excessive code in the client wekens
synchronization, which might not be what you want.
Return to: