home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-07-15 | 14.7 KB | 409 lines | [TEXT/MPS ] |
- Unit SchedulerUnit;
- { Copyright The NetWork Project, StatLab Heidelberg 1989-1991
- Copyright G. Sawitzki, StatLab Heidelberg 1989-1991}
- {------------------
- use:
- the generic scheduler for asynchronous iterations.
- You have to create a scheduler with New(Scheduler)
- and to initialize it with Scheduler.Init.
-
- For a compute server (slave) you have to customize
- Msgusable and MsgEvaluation of the TaskHandler,
- create a TaskHandler, and install it using
- Scheduler.InitTaskHandler.
-
- For a compute client (master) you have to prepare a
- receiver, you have to customize NewTask of the
- TaskGenerator, create a TaskGenerator, and install it
- using Scheduler.InitTaskGenerator.
-
- updating history:
- 1.1-0B renamed .inc to .inc.p
- 1.1-0A name changes, UNIV pointers, var messages
- 1.1-09 additional checks added
- 1.1-08 clean up
- 1.1-07 dynamic buffer handling
- 1.1-06 event-based
- 1.1-05 added USES NetWorkLookup
- 1.1-04 removed default message.
- cohandlers introduced.
- -------------------}
-
- Interface
-
- USES
- Types, ObjIntf, Errors, Memory,
- NetWork, NetWorkLookup;
-
-
- {$Setc Debugging=false} {set true to have additional debugging information, using MacsBug}
- {$Setc MemberKludge=true} {the member function of MPW 3.2 may run into a bus error instead
- of reporting false when the first argument is not an object. If
- MemberKludge is true, special cautions are taken to avoid this
- problem. If the environment is tested, set MemberKludge=false.}
- {$Setc paranoia=true} {test for conditions which simply should not happen. If message
- management is done by the scheduler and the environment is tested,
- set paranoia=false.}
-
- const
-
- {these are capability/message type flags. Move to global ??}
- {bit 0..15 are used by the scheduler, bits 16..31 by the message system.}
-
-
- {••••••• these are n o t the final codes •••••••}
- {••••••• a l l flags are reserved •••••••}
- {warning: the compiler does not know about hex numbers and may use
- a sign extension}
- {scheduler verbs}
-
- cAnyCapas = 0; {no known capabilities/no special capabilities required}
- cMsgReply = $00008000; {message is a reply}
- cMsgNAttention = $00004000; {special attention, eg. message starts a new context,
- contains a warning etc. May be delivered with priority
- by the message system. overrides context stamp information.}
-
- {message system flags}
-
- cUnknownFormat = $00010000; {reserved to mark future format extensions}
- cMustBeLaunched = $80000000; {recipient must be launched. Don't lauch}
-
- cNilError=memFullErr ; {nil error. ••••••• these are n o t the final codes •••••••}
-
-
- {====================================================================================}
-
- Type MessagePtr=MsgPtr; {we use the same data type as the message sytem,
- but we don't want to mix up with the communication
- system}
-
-
- {====================================================================================}
- {low level routines, interfacing to message system. Messages are delt with
- by message handlers. Typically, ther will be mesage handlers handling incoming
- tasks, and those generating tasks going out.}
-
-
- {---------------------------------------------------------------}
- { This is an abstract handler which will never be created.
- It is here to define default capabilities and calling convetions
- of message handlers. }
-
- Type tMessageHandler=object(tObject)
- {$IFC MemberKludge}
- MemberKludgeMagic: longint;
- {a magic word spelling longint('tMHd') with tMessageHandlers.
- May be used to avoid bus errors caused be the MPW 3.2
- implementation of member if the first argument is not an
- object}
- {$ENDC}
- ContextStamp:longint;
- {a 32bit flag to verify context continuity. 0:neutral.
- To be matched with MsgReference in the MsgRec. This flag
- is specific to a message handler. Multiple concurrent
- message handlers may have differing context stamps.}
-
- NrPendingMessages:longint;
- {number of pending messages for this message handler. Do not
- free the message handler unless NrPendingMessages is zero}
-
- {--------- standard methods ------------------------------------ }
-
- procedure tMessageHandler.init;
- {once only initialization. Set NrPendingMessages to zero and
- calls restart.}
-
- procedure tMessageHandler.restart; {use this for a first start of the
- message handler within a context. Set a new ContextStamp.}
-
- {--------- message handling ------------------------------------------------ }
-
- procedure tMessageHandler.Stamp(Msg:MsgPtr);
- {Set identificator fields in msg record. Should set
- MsgUserRefCon to longint(self).
- Increases NrPendingMessages by one.}
-
- function tMessageHandler.DisposMsg(var Msg:MsgPtr):OsErr;
- {Release Msg and all buffers associated with Msg.
- Reduce NrPendingMessages by one.}
-
- {--------- low level buffer and message handling ---------------------------- }
-
- function tMessageHandler.NewPrioPtr(var PrioSize:longint):ptr;
- {Allocate a new buffer for priority data.
- Entry: PrioSize=Requested size;
- Exit: PrioSize=Allocated size;}
-
- function tMessageHandler.NewCorePtr(var CoreSize:longint):ptr;
- {Allocate a new buffer for core data.
- Entry: PrioSize=Requested size;
- Exit: PrioSize=Allocated size;}
-
- procedure tMessageHandler.DisposPrioPtr(var PrioPtr:UNIV Ptr);
- {Dispose buffer for priority data.}
-
- procedure tMessageHandler.DisposCorePtr(var CorePtr:UNIV Ptr);
- {Dispose buffer for core data.}
-
- function tMessageHandler.Destroy(var Msg:MsgPtr):OsErr;
- {Destroy the message record, and set Msg to nil.
- Decreases NrPendingMessages by one, but does not dispose buffers.}
-
- end;
-
-
- {====================================================================================}
- {These handlers are called by the scheduler. They inherit the fields of
- the default message handler and add their own extensions. }
-
-
- {The TaskHandler may be used by both compute servers and compute clients.}
-
- Type tTaskHandler=object(tMessageHandler)
-
- {--------- working space for Msgusable ---------------------------- }
-
-
- {"Master" address is PrivilegedAddr.
- If PrivilegedTimeout is not
- zero, and master is not timed out, only
- messages from this origin will be accepted}
-
- PrivilegedInterval: longint;
- {timeout interval for master. approximate
- lifetime of faithfulness to PrivilegedAddr}
-
- PrivilegedTimeout: longint;
- {next timeout point
- =last encounter+PrivilegedInterval
- 0: no privileged defined}
-
- PrivilegedAddr: MsgAddr;
- {address of privileged user. valid if
- PrivilegedTimeout≠0}
-
- usableCapas: longint;
-
-
- {--------- standard methods ------------------------------------ }
-
- procedure tTaskHandler.init; override;
- {once only initialization. will be called by
- the scheduler on installation.}
- procedure tTaskHandler.restart;override;
- {restart the receiver. Sets ContextStamp to a neutral identifier.}
-
-
- {--------- problem specific methods ------------------------------------ }
-
-
-
- function tTaskHandler.MsgHeaderusable(var msg:MsgPtr):boolean;
- {--------- This function may be customized -------------------------}
- {check incoming message whether it is in context. This procedure should
- filter out all stray messages which may result from multiple users
- of the network communication system.
- The default does a pre-check of the master, and updates the master
- info if appropriate.
-
- Customization should verify the context word as well.
- Returns true if the message is acceptable for further processing.}
-
- function tTaskHandler.MsgUsable(var msg:MsgPtr):boolean;
- {--------- This function may be customized -------------------------}
- {check incoming message whether it is usable. Will be called after the
- context has beeen checked. This procedure should
- filter out all outdated messages.}
-
-
- procedure tTaskHandler.MsgEvaluation(var msg:MsgPtr);
- {--------- This function must be customized -------------------------}
- {evaluate information. Do not generate new task as a response.}
- end;
-
-
-
- {====================================================================================}
-
- {The TaskGenerator will be used only by compute clients.}
-
- Type tTaskGenerator=object(tMessageHandler)
-
- {--------- timing information for scheduler ----------------------------- }
-
- WaitInterval:longint; {approximate interval to wait before new task}
- TickleInterval:longint; {approximate interval for trying for a new
- random partner approximately (in ticks)}
-
-
-
- {--------- working space for NewMsg ---------------------------- }
-
-
- DefaultCapasVerb: longint;
- {Defaults for CapasVerb}
-
- {--------- standard methods ------------------------------------ }
-
- procedure tTaskGenerator.init;override;
- {once only initialization. will be called by the
- scheduler on installation.}
-
- procedure tTaskGenerator.restart;override;
- {Restart for a new context. Sets ContextStamp to a
- new random identifier. }
-
- procedure tTaskGenerator.Stamp(Msg:MsgPtr); override;
- {Set MsgReference to a unique identifier.}
-
- {--------- This function must be customized -------------------------}
- function tTaskGenerator.NewTask(var Msg:MsgPtr):boolean;
- {If a new message can be defined, set up buffers,
- adjust the fields of Msg^ as appropriate, stamp the
- message and return true. If no new message
- should be defined, return false}
-
- end;
-
- {====================================================================================}
-
-
- {---------------------------------------------------------------}
- { Cohandler
- This is a courtesy entry to allow experiments with smart schedulers
- dynamically without changing the Scheduler itself. It may run its
- statistics on incoming tasks, and adapt the TaskGenerator's iterations
- and task id as appropriate.}
-
- Type tSchedulerPhase=(pUndefined,pUsable,pUnUsable,
- pStartNewTask,pNewTaskDone,pNoNewTask,pSendMessage,pReplyMessage,
- pHousekeepingDestroy,pInit,pFree,
- pAcceptMsg);
-
- Type tSchedulerCohandler=object(tObject)
- procedure tSchedulerCohandler.CoHandle(cmd:tSchedulerPhase;msg:MsgPtr);
-
- procedure tSchedulerCohandler.reset;
- end;
-
- {====================================================================================}
- Type
- tScheduler=object(tObject)
-
- MySelf:MsgAddr; {the address and type this scheduler is installed at}
- MyTransport:TransportPtr; {the transport system corresponding to this address}
-
- receiving:boolean; {receiving is supported place receiving is true.
- A TaskHandler must be installed}
-
- sending:boolean; {TaskGeneration and sending is supported
- if sending is true.A TaskGenerator must be
- installed.
- Reply-Messages does not require sending to
- be active.}
-
- {--------- cohandler to allow for experimental implementations --------- }
-
- CoHandler:tSchedulerCohandler; {for experimental use}
-
- {--------- working space for Cohandler ------------------------------------ }
- {Scheduler and cohandler may fill these entries with proposals. NewTask is free to
- use or neglect them. However to allow for adaptive schedulers, NewTask should
- note its choices here. }
-
- TaskAddr: MsgAddr; {the effective address of the task server}
- TaskId: longint; {a stamp to identify the task.}
- TaskIterations: longint; {the number of elementary actions to perform}
-
- {--------- schedulers information about the receiver and its world --------- }
-
- TaskHandler: tTaskHandler; {will be called whenever a packet comes in}
-
- {--------- schedulers information about the TaskGenerator and its world ---- }
-
- TaskGenerator: tTaskGenerator; {will be called whenever scheduler wants to send a packet}
- NextTickle: Longint; {next time to make a try call}
- NextWait: Longint; {do not call before this time}
- PrevDest: MsgAddr; {the last destination a task was sent to}
-
- {--------- error latch--------------- ------------------------------------ }
-
- Err: OsErr; {latch error code here to allow for silent implementations}
- ErrQuiet: Boolean; {no error reporting}
- ErrFrom: tSchedulerPhase;
- procedure tScheduler.handleError(from:tSchedulerPhase;which:OsErr);
- {errors during Scheduler activity.
- should be customized.}
-
- {--------- main control of scheduler -------------------------------------- }
-
- procedure tScheduler.init; {the once-only initialization}
-
- procedure tScheduler.reset; {reset to no error, not sending, not receiving.}
-
- procedure tScheduler.free; override;
-
- procedure tScheduler.setSending(onoff:boolean);
- procedure tScheduler.setReceiving(onoff:boolean);
-
- {--------- installation of handlers -------------------------------------- }
-
- Procedure tScheduler.InitTaskHandler(newTaskHandler:tTaskHandler);
-
- Procedure tScheduler.InitTaskGenerator(newTaskGenerator:tTaskGenerator);
-
-
- {--------- schedulers task routine -------------------------------------- }
-
- procedure tScheduler.HandleMsg (Msg : MsgPtr);
- {take a message and handle it. The appropriate action is
- determined by the message staus and action code.}
-
- procedure tScheduler.PeriodicTask;
- {the periodic task. should be called from the event loop.
- Performs housekeeeping actions.}
-
- function tScheduler.GetSleep: longint;
- { returns the delay until the next activation, in ticks}
-
- {--------- schedulers kickOff -------------------------------------- }
- procedure tScheduler.kickOff(maxcount,maxticks:integer);
- {initiates a round of at most maxcount scheduler
- tasks for a total time of maxticks (whatever comes
- first). The usual send interval limitations do not
- apply during kick off}
-
- {--------- internal routines. put here to allow easy customization ------ }
- procedure tScheduler.DoNewTask(addr:MsgAddr;Transport:TransportPtr);
- {call NewTask, with all support, for addr}
-
- procedure tScheduler.sendmessage(msg:MessagePtr);
- {send the message indicated by msg, and note in
- schedulers queue.}
-
- procedure tScheduler.replymessage(msg:MessagePtr;flagsToAdd:longint);
- {send the message indicated by msg, but to msg
- target}
-
-
- end;
-
-
- var
- NetWorkScheduler:tScheduler;
-
-
- {====================================================================================}
-
-
- Implementation
- {------------------------------------------------------------}
-
- const
- unitversion='1.1-0B';
- unitId='SchedulerUnit';
-
- {$I SchedulerUnit.inc.p}
-
- end. { SchedulerUnit unit }
-