CS452 - Real-Time Programming - Fall 2008
Lecture 12 - Servers, Nameserver
Questions & Comments
- Copying the message
Servers
What this amounts to is
- Server should be lean and hungry
- do as little as possible
- always be receive blocked
Example of a server
Proprietor
Controls a resource
- data structure
- hardware
- etc.
Provides mutual exclusion by having the only code that accesses the
resource
- That is, the only way to access the resource is by making a request to
the server
- sequential code
- ergo, easy to get right
Proprietor provides service to clients
- nameserver is an example.
- one client is receiving service (REPLY-BLOCKED)
- the others are waiting (RECEIVE-BLOCKED)
- in this respect, like a monitor
- code executed by server,
- code executed in address space of server,
- less likely to be a bug, which is very important for the
waiters
Typical proprietor code
InitializeResource( ... );
RegesterAs( ... ); // What if you are the nameserver?
FOREVER {
len = Receive( tidptr, ... );
// Handle errors from Receive
// Do work. Handle errors that arise during work
error = Reply( *tidptr, ... );
// Handle errors from Reply
}
Typical client code
...
WhoIs( proprietor );
...
len = Send( proprietor, request, response );
// Handle errors from Send
...
Like a subroutine call to the client
- does not facilitate concurrency
- proprietor must fail requester if anything is missing
Generic Problem: Local Delay
Proprietor begins processing
- discovers that it cannot complete
Can other requests be processed? Possible strategies
- refusal
- siblings
- pass requests along
- how does a client find the free one?
- nested receive
- can block proprietor
- don't know that another client is waiting
- early reply
- create worker to do work
- reply Pid of worker
Nameserver
Tasks need to get the Task IDs of tasks they don't know.
Done using a task outside the kernel, called the Nameserver
Basic functionality
int RegisterAs( char* name )
Pid WhoIs( char *name )
This creates a global name-space of task names
Semantics of name-space
- One task can have two names
- No two tasks can have the same name.
Implementation
Code is trivial, and doesn't matter very much how it is written. Why?
Only used during
- initialization
- error recovery
But do the best you can anyway.
The interesting question. How does a task find out the Pid of the
NameServer? Possible solutions.
- Every NameServer had the same Pid.
- Kernel knows the Pid of the NameServer and inserts it into WhoIs( ),
&c
- Kernel puts the Pid of the NameServer into the TD of every task it
creates
- Kernel provides a WhoIsNameServer( ) system call.
Return to: