CS452 - Real-Time Programming - Winter 2017
Lecture 10 - Name Server
Public Service Annoucements
-
Due date for kernel 2: 30 January, 2017.
-
Updated k2.pdf
-
Reminder about performance measurements.
Inter-task Communication
Servers
What is a server?
Servers provide data and/or synchronization to clients. A server
is
-
a task that provides service to a client task , or
-
Tasks requesting service, clients, must know the Tid of
the server.
-
a task that owns a resource and provides synchronized access
to it.
-
The server owns the resource, but other tasks may do the
work.
How are servers implemented?
We usually try to make each service simple, so the code of the
server that provides it is simple.
-
Receive is the key to how a server works.
-
Receive a request.
-
Reply the response.
-
There are two reasons why a server cannot send.
-
It does not know in advance which tasks will be its
clients, so it can't send to them to find out if they
require service.
-
If it sends in order to get resources it needs to perform
a service, it remains blocked for an unpredictable length
of time, especially so if there is a low priority task
somewhere in the mix. If there is information it needs
it gets it by replying to a courier.
-
The sender (client, task that is making the request) blocks until
the response is available. That is, the sender is, in effect,
running at the priority of the server between the Send and
its corresponding Reply.
-
Server priority should be set according to the importance
of the service it supplies, which depends on the importance
of the resource it controls.
-
But client priority should be considered by the server.
For example, a server might have
-
one execution path for higher priority client, and
-
a different execution path for lower priority client
-
The natural code for notifiers and servers usually
does the right thing.
-
You should be able to count on your clients to be
well-behaved.
A typical server has a lot in common with a warehouse. (The result below
assumes that content may be provided in any order.)
initialize;
FOREVER
Receive( *tid, request );
switch( request.type ) {
case PRODUCER:
if ( consumer-queued )
Reply ( producer );
Reply ( dequeue( consumer ), request.content );
break;
if ( space-available )
insert( request.content );
Reply( producer );
break;
queue( producer );
break;
case CONSUMER:
if ( producer-queued )
Reply ( consumer, producer.content );
Reply ( dequeue( producer ) );
break;
if ( content-available )
Reply( consumer, extract( content ) );
break;
queue( consumer );
break;
}
Name Server
What is a name server?
-
There is a set of global execution-independent names.
-
There is a set tasks with execution-dependent tids that provide
services associated with the names.
-
A name server maintains an up-to-date table mapping names to
tids.
-
It accepts requests to update the table.
-
It accepts queries concerning the table.
Why Do We Need a Name Server
Names |
constant across applications
& executions |
interface |
Associated with a set of services, an API. |
Task Ids |
vary across applications
& executions |
implementation |
Associated with particular code
and data (an execution) |
How do You Get the Task Id of the Name Server?
Remember what you did when you were installing Linux?
-
You typed in the IP-address of the name server.
-
Make it a constant across executions.
-
Is there any other way that's not disgusting.
Name Server API
int RegisterAs( char *name );
-
One task can be registered under two names.
-
Each name is associated with a single task.
-
Name is
\000
terminated.
int WhoIs( char *name );
Name Server Semantics
RegisterAs
-
Errors, some supplied by the kernel, others supplied by the
name server.
-
Not a legal name.
-
It's up to you to decide what you will accept as legal
names.
-
Nameserver tid is not a task
-
Nameserver tid is not the Name Server.
-
Tid already registered with the given name.
-
Many-to-one mapping of names to tids
-
What does the caller do?
WhoIs
- Errors
-
Not a legal name.
-
Nameserver tid is not a task
-
Nameserver tid is not the Name Server
-
No task registered under that name
Comments
-
RegisterAs
overwrites.
-
Why? The rule is that the name -> task map is many to one.
-
A task may have many names
-
A name may have only one task
Analogy to Name Service on the Internet
-
Every computer on the internet has an IP number (tid)
-
Every computer that provides a service listens (receives) for
its IP number on the port for that service.
-
The port is bound to the daemon providing the service when the
daemon is initialized
Name Server Implementation
What does the client need to know in order to use the name server?
-
its taskid
-
the requests it services
-
its API: function signatures and type definitions
User Pseudo-Code
First we need a struct for requests and reponses.
-
A structure for the request received by the name server
- Must be known by client
- It must be declared explicitly somewhere
struct NSreq {
int type;
char name[MAXNAMESIZE];
int tid;
}
Using this struct send to the name server looks something like
Send( NSTid, (NSmsg *) msg, sizeof( NSmsg ), (NSmsg *) msg, sizeof ( NSmsg ) );
Name Server
- One service associates a taskid with a name
- The second service looks up the taskid and replys it to the
requestor
Questions
-
How much will this code run?
-
What should happen when a WhoIs request is made for an unregistered
name?
-
How would you implement insert & lookup?
- Figure out
- What deadlines does Nameserver have?
- How many names will be in NameServer?
- How many RegisterAs? and when?
- How many WhoIs? and when?
-
What should be allowable as a name?
Return to: