1748060 Members
5734 Online
108758 Solutions
New Discussion юеВ

Timers

 
SOLVED
Go to solution
Richard W Hunt
Valued Contributor

Timers

I use DCL as a prototyping language for BASIC and other programs. In support of this method, I have some utilities written in BASIC that read the DCL symbol table for some pre-defined symbols that convey various information about what I really wanted to do with a system service call. The BASIC program does the appropriate system service call and returns (passes back from the svc call) status codes that DCL can trap. Of course, once the prototype works, I convert it to another language - but at least I know the right algorithm by that time. OK, that's the background. Now my problem.

I have a little gizmo that does a SETIMR function to set an EFN. The args are an exact time of day (not delta-time, but absolute time) and an EFN. There is a non-zero timer ID number, the AST argument is nil, and the SETIMR option flag is set for clock-time rather than CPU time. I know the SETIMR call returns a success (+1) code from OVMS because I pass that status code back to DCL through the SYS$EXIT( status ) call.

The EFN in this case happens to be in a Common Event cluster. I have two ways to run the program. One way works; the other doesn't. The way that works is to set the timer, then do a WAITFR on the EFN inside the same program, and then and ONLY then, exit the image. No problem when I run it that way.

The other way is for the program to set the timer and then exit. Then I do a SEPARATE WAITFR. (Yes, I've got a tool for doing WAITFR operations in DCL. And a bunch of other tools as well. SETCEF, ASCEFC, DLCEFC, READEF, WFLAND, WFLOR, etc. etc.)

So anyway, I set my process to have PRMCEB, run the ASCEFC on EFN 65, and then set the timer on EFN 65, all in the same .COM file, so that means that I still have the same exact process, same PID. I know the CEB still exists because from another process that doesn't have PRMCEB I can still read the event flags. So that means there is a CEB to read.

If I manually set EFN 65 using the SETCEF program, I can read it back as having been set as seen from the non-privileged process. But when the timer SHOULD expire, it does NOT set the declared flag.

Now, here's the kicker. I know the timer is created because if I run the SETIMR program in the mode that waits before it exits, that other process can see the flag get set at the right time. It is only when I let the image exit without waiting. BUT remember that the process is still there so a process rundown has not occurred.

When I look through my dusty old VMS internals manual, image rundown doesn't say anything about doing an implicit CANTIM. The system timer services, when handling the TQE that has become due, check for the process to have exited, but at the time in question, it has not exited. It is in supervisor mode, but it has not exited.

The problem manifests itself in INTERACTIVE mode whether I manually run the SETIMR process or let the script have its way.

So here is the question: Does anyone have any clue as to where to look for this bug-a-boo? Am I missing something obvious? Or is there an undocumented "feature" of OV 7+ that does an implicit CANTIM on image rundown?
Sr. Systems Janitor
5 REPLIES 5
Hein van den Heuvel
Honored Contributor
Solution

Re: Timers

You may have been looking too deep (internals).
It is documented right in the "OpenVMS Programming Concepts Manual"
See below.

Also.... What were you thinking!
:-)

Actually, your plan is kinda cute. It is the one thing a timer could conceivably do outside image context.
Think of it differenty though: After an image exists, would you want an AST to fire at an address it specified? No!
Would you want a local EFN to be set? No!
So for both is makes sense to cancel.
Would it make sense to make an exception for CEF? Probably not.

Cheers,
Hein.


---- Programming Concepts ---

4.9.3.1 Performing Image Rundown
The operating system performs image rundown functions that release system resources obtained by a process while it is executing in user mode. These activities occur in the following order:

Any outstanding I/O requests on the I/O channels are canceled, and I/O channels are deassigned.
Memory pages occupied or allocated by the image are deleted, and the working set size limit of the process is readjusted to its default value.
All devices allocated to the process at user mode are deallocated (devices allocated from the command stream in supervisor mode are not deallocated).
Timer-scheduled requests, including wakeup requests, are canceled.
:
:
John Gillings
Honored Contributor

Re: Timers

Richard,

As Hein points out, all TQEs and other user mode stuff must be cancelled at image run down. There's really no other way! I'm not certain what would happen if you queued the TQE in exec or kernel mode, but I'm not about to recommend it! (for one thing I'd expect the CEF association to be undone at image run down, so what flag would get set? ...)

If you're going to use CEFs from DCL, it probably makes sense to have a detached "keeper" process that creates and associates the cluster, then hangs around to keep the cluster live ($HIBER). If you have the PRMCEB privilege, you can create a permanent cluster, but a detached process is a non-privileged way to do the same thing. It would also give you a permenent process content to keep your TQEs. Instead of $HIBER, have the process create a command mailbox to wait on and design a little language to request timer entries to set flags in the cluster.

A crucible of informative mistakes
Richard W Hunt
Valued Contributor

Re: Timers

Thanks for the answers, guys. Since I'm working from the documentation CD, it is often quite difficult to cross-reference from volume to volume unless there was a handy little link somewhere. So when I look in the DCL Dictionary, it doesn't mention that process exit clears a timer and doesn't provide a link.

I might take a different approach, though. I can let the process live longer. If I do a SPAWN /NOWAIT on the SETIMR process, I can prepare the system for an asynchronous, time-triggered action, which is all I was trying to do in the first place. After all, when a member flag in a CEB is set, any number of processes would be released by the single SET operation. At least as long as no process clears the flag before the last interested process released its WAITFR. And that, I can manage.

As an aside, I know an AST should not be delivered after an image EXIT and never really wanted to do that in the first place. Further, in that case, if the SETIMR was queued in user mode, the image user-mode exit would have trashed that right away.

But yes, I DO believe that a SETIMR of a CEB should still fire correctly even after the exit of the process that triggered the timer. Otherwise, the cooperative nature of a CEB is not as extensive as it might have been. It seems sort of "brain-damaged" to disallow the SETIMR from doing this. Somehow it limits what you can do to trigger asynchronous operations. Further, this problem would have occurred even with compiled code since in this case I am trying to synchronize multiple processes. Oh, well, one more workaround in my program won't kill me. Thanks again, folks!
Sr. Systems Janitor
John Gillings
Honored Contributor

Re: Timers

Richard,

>But yes, I DO believe that a SETIMR of a CEB should still fire correctly even after the exit of the process that triggered the timer. Otherwise, the cooperative nature of a CEB is not as extensive as it might have been. It seems sort of "brain-damaged" to disallow the SETIMR from doing this.

You're saying the $SETIMR should still work even if the *process* terminates before the timer expires? Yikes! Which process context should it execute in? Recall that CEBs are GROUP context. What if there are no available processes in the appropriate group?

It's universal throughout OpenVMS that all User Mode pending events are cancelled at image run down, and all pending events for all modes are cancelled at process run down. This is a fairly simple way to ensure that all asynchronous events are "supervised" in that there is a consistent and predictable context in which they occur. To have any exceptions to this would be a very fundamental violation of OpenVMS architecture, and would open a myriad of potential issues & loopholes. Just a simple case, suppose the ACL of the CEB changes between the $SETIMR and its expiry. How much context needs to be stored with the TQE to be able to check that access is still permitted?

There's nothing to stop you from having the same effect - you just need a process context for it to execute in. One way of achieving that is to use the "server" or "keeper" process model as suggested earlier. It's not difficult to implement and allows you maximum flexibility in controlling your CEBs.
A crucible of informative mistakes
Richard W Hunt
Valued Contributor

Re: Timers

John, I can still wish, can't I? :)

Seriously, I was not attempting to do anything with the AST, and the process had not yet exited. Just the image.

I understand about the AST context requirements and fully expected that if I had been silly enough to declare one, it would never have fired. But my counter argument is simply that the process HAD NOT run down and the CEB was still attached to it. I would have expected it to not work if the process exited. My contention was that enough context remained for the CEB to be modified. But, as was pointed out, that assumption was incorrect. What the heck, I have a workaround:

$ SPAWN /NOWAIT /SYMBOLS /INPUT=NL: -
RUN SYS$TOOLS:DCL_SETIMR

Works like a champ, and has never missed a beat so far, about 60+ hours into the test. I gave it 100 hours as a batch process in my lowest-priority queue just to see what would happen. The thing I'm eventually going to build will need the ability to fire off a bunch of timers for some special event scheduling for applications that need to be checked every so often.

Rapid prototyping is something I take seriously. BASIC so closely matches DCL's string and file paradigms that I use DCL all the time for putting together things that can easily be converted to BASIC later. If you think this was tricky, you should see what I do with floating-point math and DCL.

Sr. Systems Janitor