Multitasking Scenario
There are two categories of multitasking server applications, those that use CMS threads and those that implement their own subdispatching scheme. For these cases, the approach to using a DMSCWAIT replacement is similar. The CMS multithreaded application can use semaphores to wait, thus allowing other threads to be dispatched. It would associate a semaphore with each work unit and wait on the corresponding semaphore. A thread that finds that the request is complete would signal the semaphore to awaken the thread, which would return to the caller of DMSCWAIT. The subdispatching application would suspend the task that was called for the DMSCWAIT and dispatch another.
Below is a simple scenario that applies to both and uses the generic term task to refer to either a CMS thread or an application managed dispatchable unit. Your multitasking application gets a work unit for a task and dispatches it. When the task reaches a sync point (for example, it issues a commit), the SPM gets control so it can provide coordination if necessary. Because you previously issued DMSSSPTO with ASYNC specified, the SPM calls DMSCWAIT when waiting for asynchronous events. Your replacement for DMSCWAIT is actually called, so it can suspend the task making the request and associate the request ID passed on DMSCWAIT with that task. Before your program dispatches another task, however, it should issue a DMSCHECK NOWAIT for the request ID passed on DMSCWAIT. If the request has completed, the task just suspended can be resumed. Otherwise, another task can be dispatched. If no tasks are ready, your program should issue a DMSCHECK WAIT, specifying 0 for the requestid parameter.
Figure 1 illustrates the flow of control between a multitasking application and the SPM.
Multitasking Application
Work unit for each task
Dispatch Task1
do some processing
issue a commit ------------------------> SPM
issue DMSCWAIT
<-----------------------------------------
Suspend Task1
Dispatch Task2
do some processing
issue a commit ------------------------> SPM
issue DMSCWAIT
<-----------------------------------------
Suspend Task2
Dispatch Task3
⋮
Dispatch Task1 (after its request ID is returned on DMSCHECK)
⋮
The following steps outline the operation of a replacement for the DMSCWAIT CSL routine for a subdispatching application. See Figure 2.
- Call the application's context switching routine passing the request ID received as an input parameter on the call to your replacement for DMSCWAIT.
- If Suspend_Task was OK, then return OK.
- Otherwise, return an "invalid request ID" code.
- The application must maintain a one-to-one-to-one relationship between tasks and CMS work units and request IDs. Therefore, the application (dispatcher) will have to get a work unit for each task that it dispatches.
- The application should map one of its tasks to the request ID passed as input on DMSCWAIT. Note that more than one task may become ready before the request completes.
- For a subdispatching application, its Dispatcher must eventually:
- Issue a check (DMSCHECK) with NOWAIT specifying this SPM request ID for the requestid parameter, or
- Receive this SPM request ID as output from DMSCHECK with requestid specified as 0 (any).
For an application using multiple CMS threads, at processing breakpoints it should also issue the check (DMSCHECK) as above and signal the semaphore corresponding to the request ID. This resumes the thread on which DMSCWAIT was entered, which returns an OK return code.
Context_Switcher
Suspend_Task
1. Save caller's registers and return address
2. Associate request ID with suspended task
3. Call Dispatcher -------->
Dispatcher
1. Issue DMSCHECK with NOWAIT and
the request ID from DMSCWAIT specified
to see if the request has completed.
2. CASE of
1) Request completed
Continue task just suspended
2) Request not completed, but ready task
Dispatch it
3) No ready tasks
Call DMSCHECK with WAIT option
and request ID of 0
Dispatch ready task
end case.
3. Return
4. Return <-----------------