Controls a resource
Provides mutual exclusion by owning the code that accesses the resource
Proprietor provides service to clients
Like a subroutine call to the client
| Monitor | Proprietor | Comments | |
| access to resource | localized | localized | Means one at a time. |
| service model | self-service | full-service | |
| service structure | subroutine of client | independent task | |
| priority | client | probably different | Do we want client priority or resource priority? |
| address space | client | separate | Hardware vs software protection |
| permissions | client | different | Does client have permission to run certain instructions? |
| CPU | same | could be different | Do you need threading? |
Proprietor begins processing
Can other requests be processed? Possible strategies
Generalization of proprietor
Administrator maintains an array of records
Administrator works as he can on any one of the tasks.
Real administrators manage workers
Worker code
Worker( ) {
Initialize( );
Receiver ( serverPid, ... );
Reply( serverPiD )
// Avoid critical races
workResult = null;
FOREVER {
Send( administrator, workResult, workOrder );
doWork( workOrder );
}
}
Administrator code
Administrator( ) {
Initialize( );
for ( i = 0; i < NUM_WORKERS; i++ ) worker[i] = Create( workerCode );
for ( i = 0; i < NUM_WORKERS; i++ ) Send( worker[i], ... , ... );
// Initialize orderQueue, workerQueue
// RegisterAs
FOREVER {
error = Receive( requester, request );
switch( request.type ) {
case CLIENT:
workOrder = {client = requester, request};
if( worker = dequeue( workerQueue ) && dataAvailable( ) ) Reply( worker, workOrder );
else enqueue( orderQueue, workOrder );
break;
case NOTIFIER:
// Acquire data
// Update state
// for each queued client
// if complete data available && worker available
// workorder = {client, request}
// Reply( worker, workOrder );
// else enqueue client
break;
case WORKER:
Reply( request.client, request.result );
if( ( workOrder = deQueue( orderQueue) ) ) {
workOrder = {workOrder.client, workOrder.request};
Reply( requester, workOrder );
} else enqueue( workerQueue, requester );
}
}
}
Administrator( ) {
Initialize( );
for ( i = 0; i < NUM_WORKERS; i++ ) worker[i] = Create( workerCode );
for ( i = 0; i < NUM_WORKERS; i++ ) Send( worker[i], ... , ... );
// Initialize orderQueue, workerQueue
// RegisterAs
FOREVER {
error = Receive( requester, request );
switch( request.type ) {
case CLIENT:
workOrder = {client = requester, request};
if( worker = dequeue( workerQueue ) ) {
Reply( client, workerTid );
if ( data complete ) Reply( worker, workOrder );
else enqueue( client );
else Reply( client, sorry );
break;
case NOTIFIER:
// Acquire data
// Update state
// for each queued client
// if complete data available && worker available
// workorder = {client, request}
// Reply( worker, workOrder );
// else requeue client
break;
case WORKER:
if( ( workOrder = deQueue( orderQueue) ) ) {
workOrder = {workOrder.client, workOrder.request};
Reply( requester, workOrder );
} else enqueue( workerQueue, requester );
}
}
}
The notifier is a task that waits on events.
It has two features
FOREVER {
AwaitEvent( eventId );
Send( server );
}
You could call a notifier a detective,
In an application there is likely to be lots of waiting on combinations of events.
We use the detective to discover that a complex event has occurred.
Code could be
FOREVER {
Send( part1 );
Send( part2 );
...
Send( master );
}
Code above doesn't work! Try instead
// InitializeDB;
// Create workers and synchronize;
// Synchronize with client;
FOREVER {
Receive( *requester, request );
if ( request.type == CLIENT ) {
parsedRequest = parse( request );
if ( happened( parsedRequest, DB ) ) Reply( requester );
else enqueue( parsedRequest );
}
else if (request.type == WORKER ) {
updateDB ( request );
Reply( requester );
foreach ( queuedRequest )
if ( happened( parsedRequest, DB ) ) {
dequeue( parsedRequest );
Reply( client );
}
}
}
This is the code of a detective.
We can say that an event has not happened yet.
Only at the end of the universe can we say that an event simply has not happened.
Time-outs are needed for NOT
Who is the client of the detective
Return to: