Wimp_PollIdle with R2 = now
Matthew Phillips (473) 721 posts |
I’ve come across a weird effect with Wimp_PollIdle which does not seem to be documented. R2 is supposed to be the earliest time you would like a null event to be returned. You’re supposed to use OS_ReadMonotonicTime, add an offset (e.g. 25 centiseconds) and pass that in R2 when calling Wimp_PollIdle. If you do that, the Wimp pages in other tasks in the meantime as you would expect. However, if you pass in R2 the exact same value you just got back from OS_ReadMonotonicTime then the Wimp seems to return to you immediately with a null reason code, and does not even pass any other reason codes to you. If you loop, waiting ten seconds, say, and call Wimp_PollIdle like this inside the loop, then the other Wimp tasks on the machine do not get a look-in until you’ve finished the loop. I am wondering whether this effect is responsible for some perplexing behaviour I have seen in other applications, where they appear to update their windows, but otherwise seem to be single-tasking? Is this expected behaviour? |
Jean-Michel BRUCK (3009) 359 posts |
From PRM3 p.191 If you don’t need Null Events you can prevent them with event_set_mask () |
Chris Mahoney (1684) 2165 posts |
event_set_mask() is part of the Toolbox, I believe. |
Matthew Phillips (473) 721 posts |
Well, it wasn’t what I expected. When you call the ordinary Wimp_Poll, the Wimp returns to you when there is an event for you, or with a null reason code if there’s nothing specific to be done (providing you have not masked out nulls, of course). But in the meantime, it will probably have paged in other tasks, particularly if any of them want null polls as well. With Wimp_PollIdle I have always assumed it was a way of saying that you don’t want control back ASAP, but only after an interval. The time you give in R2 is the earliest time that you would want to receive a null, but there’s no guarantee you’ll get one after that precise interval, because another task might get paged in and might take a while before it polls the Wimp. If calling Wimp_PollIdle with R2 equal to the current time immediately returns control to you and does not allow other tasks a look-in, that’s quite a special meaning. It’s the only situation in which Wimp_PollIdle would return sooner than Wimp_Poll would. This probably ought to be documented. It isn’t in my printed PRMs or the RISC OS Ltd Wimp PRM. |
Steve Fryatt (216) 2105 posts |
The fact that you observe it returning immediately with a null event in preference to other pending events would also be contrary to the documented comments on event priority (page 3-116). |
Stuart Swales (8827) 1357 posts |
The PRM is accurate for PollIdle: R2 = earliest time for return with Null_Reason_Code event. Not after. It is a bug, if true, that higher priority events are not being delivered. |
Rick Murray (539) 13840 posts |
Hmm, I just threw together this: REM >PollIdleTest DIM b% 255 b%!0 = 0 SYS "DADebug_GetWriteCAddress" TO dwc% SYS "Wimp_Initialise", 300, &4B534154, "Poll Idle Test", b% TO h% REPEAT t% = TIME SYS "Wimp_PollIdle", 0, b%, t%, 1 TO e% v$ = RIGHT$("00"+STR$(e%), 2) A% = ASC(LEFT$(v$, 1)) : CALL dwc% A% = ASC(RIGHT$(v$, 1)) : CALL dwc% A% = 13 : CALL dwc% : A% = 10 : CALL dwc% IF ( (e% = 17) OR (e% = 18) ) THEN IF b%!16 = 0 THEN SYS "Wimp_CloseDown", h%, &4B534154 : END ENDIF UNTIL FALSE The result was 17, 17, 18, lots of zeros, and 18, 17 as I quit (from Switcher). Otherwise, the program pretty much just behaved as if I had called Wimp_Poll. Changing the flags to zero (don’t block null) didn’t alter anything. Making t% be TIME-1 had no effect either. |
Stuart Swales (8827) 1357 posts |
Curious – I wonder whether Matthew observed this on RISC OS 5 or some other branch? |
Martin Avison (27) 1494 posts |
What evidence is there for this? On VRPC+RO4.39, if I run Rick’s program using PollIdle and another version using Wimp_Poll at the same time, each program gets alternate Null Reason Codes to process – which is what I would expect. |
Stuart Swales (8827) 1357 posts |
Ah, but BASIC’s TIME uses OS_Word to read the system clock, not OS_ReadMonotonicTime, and the two are not the same. [Except when they are :-) But the system clock is writeable, so may be different.] |
Martin Avison (27) 1494 posts |
So I changed the test program to use OS_ReadMonotonicTime, and got the same results. |
Matthew Phillips (473) 721 posts |
The situation in which I observed the unexpected behaviour is rather involved, so it will take a bit more effort for me to extract a brief example. I was writing some automated tests for the Impact database and in the course of this trying some fairly weird things that people probably wouldn’t usually do. Impact has a scripting language built in, and the test script I was using involves the “Message” command which puts up a message using Wimp_ReportError. The scripting language includes a “WimpPoll” command, which takes an optional parameter in centiseconds. The parameter (or zero if not supplied) is added to the OS_ReadMonotonicTime value and the scripting engine then calls Wimp_PollIdle with R2 set to the current time plus the parameter. In fact, the WimpPoll script command calls Wimp_PollIdle repeatedly, adjusting R2, until the given time has elapsed — that was how it was documented in the Impact manual, but it had never actually done that until I corrected the behaviour in January this year. (The purpose of the WimpPoll command is so that the user can kick off a separate process, for example via Filer_Run, and leave time for it to finish.) The test script was testing what happens if the user makes changes to a database field while the action script is running. If I use the WimpPoll command with a value of ten seconds: Message "In the next ten seconds, alter field 1"; WimpPoll 10*100; then after clicking to close the message box, the message box disappears, the clock on Organizer carries on ticking, and I can interact with Impact and with other applications. On the other hand, if I use WimpPoll with no parameter and build the delay into the action script: Message "In the next ten seconds, alter field 1"; Local "t"; t = Secs(Today()+60*Mins(Today()); While (t+10 > Secs(Today())+60*Mins(Today())) { WimpPoll; } then when I click to dismiss the message box, the button depresses, but the box stays on the screen. The mouse is not confined to the message box area and can move across the whole screen, but the Organizer clock remains stuck on the same time for ten seconds, and my mouse clicks have no effect on Impact or on any other application. Pressing F12 has no effect either. Typing up the above made me wonder if this effect only occurs immediately after an error box is dismissed, but I removed the Message command from the action script and I get much the same effect. This time the button on the record card which I click to kick off the action script remains depressed, and I am unable to interact with any applications till the ten seconds is up. I appreciate there are all sorts of unanswered questions: how does Impact’s Wimp poll loop work, etc. I will need to do some more investigation and try to come up with a short example in BASIC to reproduce it. I’m using RISC OS 5.16 on an Iyonix and 5.23 (18-Feb-18) on an ARMX6. Haven’t tried a more up to date OS on the RPi yet, but I’m not expecting something like this to have changed fundamentally. |
Matthew Phillips (473) 721 posts |
Sorry for wasting everyone’s time. I’ve now realised what the problem is and I’m feeling very stupid at not seeing what was under my nose all the time.
This loop was the cause of the problem. If the parameter value was zero then Wimp_PollIdle was not being called at all, which is why the symptoms were exactly like an application single-tasking for ten seconds, because that’s what Impact was doing! Ah well, another thing to fix in the next release, and a demonstration of the importance of having test scripts. |
Stuart Swales (8827) 1357 posts |
Phew! |
Jean-Michel BRUCK (3009) 359 posts |
@ Rick REPEAT the delta t is missing, so the loop returns immediately. t% += delta_t Working example in C (extract)
From PRM3-181(191)
In summary the wimp ‘sleep’ during delta_t, does not respond to the null event, but will react if it is another event, for example a mouse click. Sorry for my English and the timme to edti this post. |
David J. Ruck (33) 1635 posts |
Don’t worry this happens to me all the time, as soon as you ask the question in public, you realise where you should have been looking for the answer, and find it. |
Rick Murray (539) 13840 posts |
That was the point – to see if the Wimp was somehow misbehaving if the time on entry was “now”.
That’s why it’s useful when you get stuck to explain things to a rubber duck. Sometimes just talking through it brings another perspective. I also found mom useful for that (more interactive), but not the cat. The Furry Goddess has already debugged it, knows exactly what the problem is, and tells me there’s nothing wrong, it’s a compiler bug. |