[gccsdk] Shared library code and modules

Ben Avison bavison at riscosopen.org
Tue Mar 8 15:09:36 PST 2016


On Tue, 08 Mar 2016 22:30:43 -0000, Theo Markettos <theo at markettos.org.uk> wrote:

> On Tue, Mar 08, 2016 at 06:33:23PM +0000, Lee Noar wrote:
>> If you wanted to execute the library code in USR mode after being called
>> in SVC mode from a SWI, then you would have to set up the C environment
>> first, ie, stack, sp, sl, fp, malloc, stdio, etc.
>
> Hmm, yes, it does look more complicated than I thought.  Unwinding the SVC stack to the point of SVC entry you could do (would have to know how
> far down it takes to call into your SWI handler, somewhat fragile)

Indeed - the layout of the SVC stack (effectively the stack frame layout
used by the kernel) has changed in the past and it's entirely possible that
it will have to change again in future. There's also the nasty complication
of what happens if you get nested SWI calls; the inner one can't be
expected how to unwind the outer one safely in order to flatten the SVC
stack and drop out to USR mode.

There's a more insidious problem with this approach though, and that's that
you'll end up skipping callbacks (both transient and non-transient) if you
attempt to drop out to USR mode directly within your SWI handler instead of
returning to the kernel and letting it do the return for you. Depending on
the nature of the code - particularly if it is spending most of the CPU
time making calls to that library - that could have a catastrophic effect
on callback latency, with all sorts of unpredictable side-effects.

A better way would be to use the non-transient callback handler to override
the USR mode registers that are restored at the end of the kernel's SWI and
IRQ dispatcher return code. But there's a drawback that RISC OS only
supports one of these being installed at once, so for example you would
experience trouble running such code under TaskWindow, or with code that
calls Wimp_Poll, both of which rely on non-transient callback handlers.
Ideally, the kernel shouldn't be farming out responsibility for USR mode
switching like that, because no single non-transient callback handler can
have knowledge of all other programs in the system that are also queuing up
for a context change. But to fix that would require the kernel to understand
process state, whilst at the moment that's all private to the Wimp. The
move started in RISC OS 3.7, with OS_AMBControl, but it remains unfinished
business.

If you want a degree of "kernel mode" threading, I'd point you at the
RTSupport module, which supports multiple threads each with their own stack
chunk chain, sl, sp etc. It does this using SYS mode though, so if your
main motivation is memory protection (which I think it is) then that won't
help you.

Ben




More information about the gcc mailing list