Re: Timer module for interpreter
- From: Rory McLean <rory@xxxxxxxxxxxxxxxxxx>
- Date: Sun, 19 Feb 2006 00:56:27 +0000
In article <1140143457.369153.68170@xxxxxxxxxxxxxxxxxxxxxxxxxxxx>,
<URL:mailto:cs99cjb@xxxxxxxxx> wrote:
Rory McLean wrote:
I'm trying to put together a interpreter which will cooperatively
multi-task with the WIMP.
This is written in C with the intention of running on RISC OS 3.1
upwards, and preferably also on the Iyonix. It is planned to port
this to Windows and Linux in due course, with the intention that
all three interpreter environments behave the same.
What I'd like to do is have a fall-back timer so that if some
code runs wild this will set a flag to halt the main interpreter
loop which is running the code. Conceivably this might make use
of longjmp.
I've googled but not found anything that looks likely. If I
understand things correctly the main interpreter loop needs to
call a module which sets up a timer, and that timer when it goes
off needs to set a value which is tested in the loop.
Why does it have to be a module? Presumably because you are worried
about your application code being paged out (inadvertantly or
otherwise) when the timer goes off. However I implemented a system that
sounds similar to what you propose without using a module.
Yes, as I understood it the application code could be paged out,
so I would need to ensure the timer function was in a module
which would not be paged out. Presumably the flag set by the
module and checked by the main interpreter loop would also have
to be in non-paged memory.
Several of my applications use SWI OS_CallAfter to set a routine to be
called after a certain time interval has elapsed since control last
returned from SWI Wimp_Poll. This interval is configurable and it
dictates the granularity of multi-tasking and the amount of CPU time my
task gets compared to other tasks. (10 centiseconds is normal and
causes it to run at the same priority as a program in a TaskWindow.)
The ticker timer routine is called in SVC mode with interrupts
disabled. It is tiny and out of necessity written in assembly language;
it simply sets a flag at the address passed in R12. Because my ticker
event routine is in application space I also set up an atexit()
function so that the C run-time system will make a last-ditch effort to
remove it (SWI OS_RemoveTickerEvent) even if my program terminates
unexpectedly. The only reason the atexit() function might not get
called would be a 'No stack for trap handler' type error, but even then
it is extremely likely the ticker timer will go off before the user
dismisses the error report.
The only reason for all of this is that it is much more efficient to
check a boolean value in every loop where the number of iterations is
unknown (or known to be high) than it would be to repeatedly call SWI
OS_ReadMonotonicTime and compare the returned value with that recorded
after the last Wimp_Poll. The poll-wimp-now flag must be type-qualified
as 'volatile' so that the C compiler does not optimise away repeated
accesses.
If you are interested, the relevant code is c.RoundRobin, c.LoadSaveMT
and s.timer in CBLibrary:
http://starfighter.acornarcade.com/mysite/programming.htm#cblibrary
Thank you! I've fetched this, and though disappointed that I
can't do it all in C (I've had a number of bad experiences with
assembler over the years), the 'timer' function looks as though
it should do the trick.
As an example client, my application SFtoSpr:
http://starfighter.acornarcade.com/utils.htm#sftospr
background are written as state machines (with some functions that know
how to return prematurely when their time is up). However I don't see
why the ticker flag scheme outlined above couldn't instead be used to
determine the appropriate time to call SWI Wimp_Poll (or equivalent)
directly from within a deeply nested function. Of course you would then
have to guard against potential problems caused by re-entrancy.
I'd prefer to have all the Wimp_Poll calls in a single place, to
simplify things. It looks as though the ticker flag scheme could
also be used to do simple threading for the interpreter, as well.
The main interpreter loop is also calling Wimp_Poll at reasonable
intervals to allow cooperatively multi-task to continue. If the
code runs OK then the timer will be disabled, so that it doesn't
go off, and maybe reset and reenabled again later.
If the main interpreter loop is already calling Wimp_Poll then
presumably you are talking about some code running wild in such a way
that prevents it returning to the main loop within a reasonable time
period. AFAIK The only way to force a premature return without using
interrupts is to insert checks at strategic points.
If there is a risk of code not returning to the main loop, and I
can avoid re-entrancy issues with any system calls, then a
combination of some interrupting timer code, combined with a
status flag and a longjmp to clear out the C stack back to the
main loop, is the only way I can see to handle this.
HTH,
Again, thanks for your assistance!
--
Rory McLean, Dreamer
rory@xxxxxxxxxxxxxxxxxx
http://www.romsys.demon.co.uk/
.
- References:
- Timer module for interpreter
- From: Rory McLean
- Re: Timer module for interpreter
- From: cs99cjb
- Timer module for interpreter
- Prev by Date: Re: Timer module for interpreter
- Next by Date: Re: Writing 32 bit apps / Castle SCL
- Previous by thread: Re: Timer module for interpreter
- Next by thread: Re: Timer module for interpreter
- Index(es):
Relevant Pages
|