log in | register | forums
Show:
Go:
Forums
Username:

Password:

User accounts
Register new account
Forgot password
Forum stats
List of members
Search the forums

Advanced search
Recent discussions
- Elsear brings super-fast Networking to Risc PC/A7000/A7000+ (News:)
- Latest hardware upgrade from RISCOSbits (News:)
- RISC OS London Show Report 2024 (News:1)
- Announcing the TIB 2024 Advent Calendar (News:1)
- Code GCC produces that makes you cry #12684 (Prog:39)
- RISCOSbits releases a new laptop solution (News:)
- Rougol November 2024 meeting on monday (News:)
- Drag'n'Drop 14i1 edition reviewed (News:)
- WROCC November 2024 talk o...ay - Andrew Rawnsley (ROD) (News:2)
- October 2024 News Summary (News:3)
Latest postings RSS Feeds
RSS 2.0 | 1.0 | 0.9
Atom 0.3
Misc RDF | CDF
 
View on Mastodon
@www.iconbar.com@rss-parrot.net
Site Search
 
Article archives
Acorn Arcade forums: Programming: OS_AddCallBack vs OS_CallAfter
 
  OS_AddCallBack vs OS_CallAfter
  sirbod (10:58 24/4/2012)
  Phlamethrower (13:07 24/4/2012)
    sirbod (13:36 24/4/2012)
      Phlamethrower (22:07 24/4/2012)
        sirbod (06:28 25/4/2012)
          Phlamethrower (12:31 25/4/2012)
            sirbod (14:07 25/4/2012)
              sirbod (13:03 28/4/2012)
                Phlamethrower (16:56 28/4/2012)
                  sirbod (18:05 28/4/2012)
    swirlythingy (15:38 24/4/2012)
      sirbod (16:18 24/4/2012)
 
Jon Abbott Message #120182, posted by sirbod at 10:58, 24/4/2012
Member
Posts: 563
Can someone explain the differences, in the way the code called via these should behave and what it can/can't do.

Code called via OS_AddCallBack works, but when called via OS_CallAfter it fails - it looks like its some SWI's that are failing.

Also, is there a way to force a CallBack to occur?

I have some poorly behaved games which are hammering MiscOp 1 for a disc change, not giving any time to RISC OS to service transient callbacks.

EDIT: staying in SVC and calling OS_ReadC triggers a transient callback - sometimes - but it's not elegant. Doesn't seem to be any need to call OS_SetCallBack!

The obvious one was to use call OS_SetCallBack and call OS_Byte 19 - wait for vertical sync - in USR mode, but the callback doesn't trigger.

EDIT2: inserting a character into the keyboard buffer and then calling OS_ReadC never triggers a transient callback.

[Edited by sirbod at 13:51, 24/4/2012]
  ^[ Log in to reply ]
 
Jeffrey Lee Message #120183, posted by Phlamethrower at 13:07, 24/4/2012, in reply to message #120182
PhlamethrowerHot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot stuff

Posts: 15100
It looks like there are two callback systems in place - the old callback environment handler, and the new OS_AddCallBack system for registering one-shot callbacks.

The old environment handler callback will only trigger in the following situations:
  • The OS is returning from a SWI to user mode with interrupts enabled
  • The SWI isn't about to generate an error (i.e. no error is being returned, or it was an X SWI)
  • OS_SetCallBack has been called to request a callback
  • The SWI that's being returned from isn't OS_SetCallBack
  • The SVC stack is empty
OS_AddCallBack callbacks will trigger only if the following conditions are met:
  • The OS is returning from a SWI to user mode with interrupts enabled
  • The SWI isn't about to generate an error (i.e. no error is being returned, or it was an X SWI)
How this compares with OS_CallAfter and OS_CallEvery is as follows:
  • OS_CallAfter/OS_CallEvery routines are called from an interrupt context - they get called by the 100Hz ticker interrupt handler. Because the CPU could have been doing pretty much anything at the time, you're only allowed to use re-entrant SWIs.
  • The old-style callback handler will only ever be called when the system is returning to the foreground; i.e. no SWIs are active so it's safe to call non-reentrant SWIs, or to call SWIs which will block for long amounts of time waiting for disc access.
  • New-style OS_AddCallBack routines will also get called when the system is returning to the foreground. However they can also be triggered manually if code running in SVC mode switches to user mode and then calls a dummy SWI. This is useful for SVC mode code which needs to block for a long time waiting for hardware devices to respond (especially since underlying driver layers may be dependent on callbacks for some of their operation). On RISC OS 5 (or on earlier OS versions of the right version of CallASWI is loaded) the "switch to user mode and call a dummy SWI" can be implemented in one go by calling OS_LeaveOS. But the important thing to remember is the the code should only trigger callbacks in this manner if it can be sure that everything further up the call stack is aware callbacks could occur
As you've spotted there are a couple of places in the kernel where callbacks get triggered manually - but I've run out of time to track that down this lunchtime!
  ^[ Log in to reply ]
 
Jon Abbott Message #120184, posted by sirbod at 13:36, 24/4/2012, in reply to message #120183
Member
Posts: 563
Thanks, that explains the problems with OS_CallAfter - which rules that route out. I'll have to find a way to reliable trigger a transient callback.

I found "OS_LeaveOS" - which seems like it might do the job (the documentation isn't specific about transients - but I don't see how it could call any other callback). It's supposed to be in CallASWI 0.03 - however SWI "OS_LeaveOS" isn't translated when CallASWI is loaded, and it doesn't trigger the transient callback!
The OS is returning from a SWI to user mode with interrupts enabled
I'm not certain this is true, as I've managed to trigger it in SVC with interrupts disabled.
they can also be triggered manually if code running in SVC mode switches to user mode and then calls a dummy SWI
This doesn't seem to be the case.

EDIT:OS_LeaveOS doesn't seem to return!

[Edited by sirbod at 14:57, 24/4/2012]
  ^[ Log in to reply ]
 
Martin Bazley Message #120185, posted by swirlythingy at 15:38, 24/4/2012, in reply to message #120183

Posts: 460
However they can also be triggered manually if code running in SVC mode switches to user mode and then calls a dummy SWI.
The classic example of such an SWI is XOS_GenerateError, which the StrongHelp manual says can be called to force a callback to occur.
  ^[ Log in to reply ]
 
Jon Abbott Message #120186, posted by sirbod at 16:18, 24/4/2012, in reply to message #120185
Member
Posts: 563
XOS_GenerateError, which the StrongHelp manual says can be called to force a callback to occur.
It certainly doesn't work on transients.

I've spent the best part of 8 hours trying different methods and come to conclusion you can't reliable trigger a transient callback...a glaring omission in the OS if you ask me.

I've switched the code to cancel the callback if it's not called within a second and then manually call it. This will break on physical tin, due to FileCore re-entrancy, but there's no other choice at the minute.

The only option left is to insert a handler onto the SWI vector and trigger them on exit manually. I can't face any more testing today though!
  ^[ Log in to reply ]
 
Jeffrey Lee Message #120188, posted by Phlamethrower at 22:07, 24/4/2012, in reply to message #120184
PhlamethrowerHot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot stuff

Posts: 15100
EDIT:OS_LeaveOS doesn't seem to return!
Hmm, so I see! It looks like it's a blatant copy & paste error - it acts as if the kernel SWI dispatcher uses R14 to store the SPSR (as it does on 32bit OS's), so just knocks the bottom four bits off of the register. But judging by the CVS history it looks like 26bit versions of the OS have only ever used R14 for storing the 26bit PSR+return address, so it will end up corrupting the return address and often return to a point just before the SWI call!
  ^[ Log in to reply ]
 
Jon Abbott Message #120189, posted by sirbod at 06:28, 25/4/2012, in reply to message #120188
Member
Posts: 563
That explains a lot!

Whilst you're there, do the later versions have the SWI translation text? 0.03 certainly doesn't, haven't managed to get hold of 0.05 to see if it's been fixed.

More to the point, will it forcibly action transient callbacks if the callback flag is set? Or do I still need to code this myself, off the SWI vector?
  ^[ Log in to reply ]
 
Jeffrey Lee Message #120191, posted by Phlamethrower at 12:31, 25/4/2012, in reply to message #120189
PhlamethrowerHot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot stuff

Posts: 15100
Whilst you're there, do the later versions have the SWI translation text?
No, they don't. There's no direct way of adding it, but I guess the module could hook onto the name <---> number conversion SWIs and handle conversion of the extra SWIs itself.

More to the point, will it forcibly action transient callbacks if the callback flag is set? Or do I still need to code this myself, off the SWI vector?
The SWIs return via the exit code in the kernel, the same as any other SWI. I'm not sure why you're having so much trouble triggering callbacks; are you sure you're calling the dummy SWI with interrupts enabled? I can't see any other code that would restrict when callbacks are triggered.
  ^[ Log in to reply ]
 
Jon Abbott Message #120193, posted by sirbod at 14:07, 25/4/2012, in reply to message #120191
Member
Posts: 563
Here's the code I'm using. This is entered if a disc change has been pending for at least 40 entries to MiscOp 1. It's then entered on every subsequent call to MiscOp 1, if the disc change is still pending - this is several hundred times a second.

TEQ PC, PC
MRSEQ R0, CPSR
MOVNE R0, PC
MOV R1, R0
BICEQ R0, R0, #%10001111
BICNE R0, R0, #%11 + 1<<27
MSREQ CPSR_c, R0
TEQNEP R0, #0
NOP

STMFD R13!, {R1-R2, R14}
MOV R0, #19
SWI "XOS_Byte"
LDMFD R13!, {R1-R2, R14}

TEQ PC, PC
MSREQ CPSR_c, R1
TEQNEP R1, #0
NOP


EDIT: Obviously replace the SWI with the one of choice, I've tried XOS_GenerateError as well.

[Edited by sirbod at 15:17, 25/4/2012]
  ^[ Log in to reply ]
 
Jon Abbott Message #120223, posted by sirbod at 13:03, 28/4/2012, in reply to message #120193
Member
Posts: 563
I'm hoping the lack of responses is down to my code being okay smile

It's not the end of the world. As ADFFS already hooks onto the SWI hardware vector, I can check for a pending callback on entry and redirect the OS exit back via my code.

I'm still curious to know why the code above does work though.
  ^[ Log in to reply ]
 
Jeffrey Lee Message #120225, posted by Phlamethrower at 16:56, 28/4/2012, in reply to message #120223
PhlamethrowerHot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot stuff

Posts: 15100
I'm hoping the lack of responses is down to my code being okay smile
Or possibly I haven't had enough time to look into it yet smile (But for what it's worth, that code does look OK - hence me needing time to look into it)

I'm still curious to know why the code above does work though.
I'm assuming that's a typo?
  ^[ Log in to reply ]
 
Jon Abbott Message #120226, posted by sirbod at 18:05, 28/4/2012, in reply to message #120225
Member
Posts: 563
Predictive text fail!
  ^[ Log in to reply ]
 

Acorn Arcade forums: Programming: OS_AddCallBack vs OS_CallAfter