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 | Easily adapted to multi-core |
| service structure | subroutine of client | independent task | Easily adapted to multi-core |
| 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 | Modern hardware works hard to support threads. |
Proprietor begins processing
Can other requests be processed? Possible strategies
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 );
switch( request.type ) {
case CLIENT:
parsedRequest = parse( request );
if ( happened( parsedRequest, DB ) ) Reply( requester );
else insert( db, parsedRequest );
break;
case WORKER:
updateDB ( request );
Reply( requester );
foreach ( queuedRequest )
if ( happened( parsedRequest, DB ) ) { delete( parsedRequest ); Reply( client ); }
break;
}
}
This is the code of a detective.
Initialize;
Synchronize with detective;
WhoIs( "clockserver" );
FOREVER {
Send( detective, {sequence-no, rrrrring}, {sequence-no, time}, ... );
Delay( time );
}
FOREVER {
Receive( requester, ... );
switch ( request-type ):
case CLIENT:
insert( db, {requester, event, time} );
if( !empty( evt-worker-Q ) ) Reply( dequeue( evt-worker-Q ), lookup-event( requester ) );
else { enqueue( evtQ, requester ); Create( event-worker ); }
if( !empty( alarm-worker-QQ ) ) Reply( dequeue( alarm-worker-Q ), lookup-time( requester ) );
else { enqueue( evtQ, requester ); Create( alarm-worker ); }
break;
case EVT_WORKER:
update( db, message );
enqueue( event-worker-Q, requester );
if( !empty( evtQ ) ) Reply( dequeue( event-worker-Q ), lookup-event( dequeue( evtQ ) ) );
break;
case ALARM_WORKER:
update( db, message );
enqueue( alarm-worker-Q, requester );
if( !empty( evtQ ) ) Reply( dequeue( alarm-worker-Q ), lookup-time( dequeue( alarmQ ) ) );
break;
}
while ( client = ready( db ) ) Reply( client, result );
}
.
Return to: