Acorn Arcade forums: Programming: Self-terminating a module
|
Self-terminating a module |
|
sirbod (19:51 19/4/2012) Phlamethrower (12:41 20/4/2012) sirbod (16:00 21/4/2012) qUE (15:40 20/4/2012) swirlythingy (16:38 21/4/2012) Phlamethrower (18:24 21/4/2012) sirbod (08:05 22/4/2012)
|
|
Jon Abbott |
Message #120151, posted by sirbod at 19:51, 19/4/2012 |
Member
Posts: 563
|
Is there a defined way for a module to remove itself from memory?
I'm guessing calling OS_Module with yourself as the module to delete isn't best practice! |
|
[ Log in to reply ] |
|
Jeffrey Lee |
Message #120169, posted by Phlamethrower at 12:41, 20/4/2012, in reply to message #120151 |
Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot stuff
Posts: 15100
|
I don't think there's an easy way of doing it, unless the module is currently running as a task, in which case OS_ExitAndDie can be used.
The easiest method I can think of would be to register a callback and then within the callback copy a bit of code to the stack which kills the module. By having the termination code held in the stack you can be sure the code won't get overwritten when the module dies. And the stack is the only bit of memory I can think of (except perhaps scratch space?) which can free itself and return to the caller in one atomic operation without leaving some registers corrupt. You'd probably want a construct similar to the following:
Stack frame layout:
sp+0 SWI XOS_Module sp+4 LDMIA r2,{r0-r2,sp,pc} sp+8 (stacked r0) sp+12 (stacked r1) sp+16 (stacked r2) sp+20 (value to restore sp to, i.e. sp+28) sp+24 (lr on entry)
Code to do this from within the callback:
STMFD sp!,{r0-r3,lr} ADR r0,killcode LDMIA r0,{r0-r1} STMDB sp!,{r0-r1} ADD r2,sp,#28 STR r2,[sp,#20] ; Update stacked sp MOV r0,#1 MOV r1,sp ADD r2,r1,#8 SWI XOS_SynchroniseCodeAreas MOV r0,#4 ADR r1,ModuleTitle MOV pc,sp .killcode SWI XOS_Module LDMIA r2,{r0-r2,sp,pc}
[Edited by Phlamethrower at 13:46, 20/4/2012] |
|
[ Log in to reply ] |
|
qUE |
Message #120172, posted by qUE at 15:40, 20/4/2012, in reply to message #120151 |
Posts: 187
|
IIRC, if the module has it implemented there's a Finalise entry in the module header. In there you should clean up any allocated memory and then return, the RMA handler should then assume the module is unchained, afaik. |
|
[ Log in to reply ] |
|
Jon Abbott |
Message #120175, posted by sirbod at 16:00, 21/4/2012, in reply to message #120169 |
Member
Posts: 563
|
I don't think there's an easy way of doing it, unless the module is currently running as a task, in which case OS_ExitAndDie can be used. It's the Filer module that I want to kill when the user wants to quit ADFFS, I think I tried OS_ExitAndDie a while back with little success - even though it should have worked. The stack option should do the trick, if not I won't lose any sleep over it!
Thanks |
|
[ Log in to reply ] |
|
Martin Bazley |
Message #120177, posted by swirlythingy at 16:38, 21/4/2012, in reply to message #120151 |
Posts: 460
|
I'm guessing calling OS_Module with yourself as the module to delete isn't best practice! Why can't you just do this?
I mean, modules do have a 'Finalise' entry in the header, so even if you do need to distinguish it from an ordinary *RMKill, you could always set a flag word in private memory somewhere... |
|
[ Log in to reply ] |
|
Jeffrey Lee |
Message #120178, posted by Phlamethrower at 18:24, 21/4/2012, in reply to message #120177 |
Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot stuff
Posts: 15100
|
I'm guessing calling OS_Module with yourself as the module to delete isn't best practice! Why can't you just do this? When the module gets killed the kernel will free the memory that the module code was held in. So after the OS_Module SWI completes the kernel will attempt to resume execution of the now-freed module code; most of the time this will probably work (RISC OS doesn't wipe the contents of heap blocks when they're freed), but every so often you'll run into a case where an interrupt process allocates some memory just after the module is killed and tramples all over the code that's about to be executed.
Jon - if it's the filer (running as a task) which is trying to kill itself, be careful not to register the callback from user mode. Otherwise the callback will trigger as soon as the OS_AddCallback SWI completes, so the module will still be active when it gets killed. |
|
[ Log in to reply ] |
|
Jon Abbott |
Message #120179, posted by sirbod at 08:05, 22/4/2012, in reply to message #120178 |
Member
Posts: 563
|
Thanks for the info, SVC mode it is then.
I need to tidy the startup and exit of the Filer next week, along with its communication with the ADFFS module |
|
[ Log in to reply ] |
|
|
Acorn Arcade forums: Programming: Self-terminating a module |