Why are you causing DSI exceptions (handled by the kernel, but all exceptions are very slow) by using SysBase = *((struct ExecBase **) 4);
I don't have any DSIs there for those ones (and i am on debug kernel with munge). Or you mean they invisibly ?
This is exactly what Jörg wrote. Peeking at address 4 is in fact causing a DSI exception, but this is handled silently by the kernel. The point is that exceptions cause a major performance penalty, even if they don't become visible.
Peeking at address 4 must be supported, because this was documented to be valid since day zero of Amiga history. But there are lots of other ways to get a valid ExecBase address which don't require this kind of a big wooden hammer and hence don't cause any further performance penalty.
Please, better to understand why we need to replace it at all and not remove it :)
After talking with Thore in mail, suitable there is not have it at all as startup code already deal with. I also do search on all the os4codes i have, and on wiki/os4coding/hp forum, and no one assign Sysbase directly at all, everyone just have "extern struct ExecBase *SysBase;" and leave it to system to decide what is it.
Yes, this is suitable and the (IMHO) best solution.
We needed to replace it, because SysBase = *((struct ExecBase **) 4); does a zeropage access (from "user space"), which shouldn´t have been done at all...
Removing is impossible, because sometimes you need an anchor to access OS functions. On other systems this is done e.g. using an interrupt.
I don´t know why it is used in this part of code, but I don´t think that it´s done just for fun
“extern” does not make sense, this is what you use when, you want to tell the compiler that we have variable, but sense its a global, we can't declare it here. But its declared else where.
So drop the "extern", it does not make sense inside TimerFunc()
When you have more then one .o file, you can get linking error, saying the variable is declared more then once, this when you use “extern”.
besides, processes created by CreateNewProc, should call functions and it this agreements.
Removing is impossible, because sometimes you need an anchor to access OS functions. On other systems this is done e.g. using an interrupt.
Removing from os ? From odyssey we can remove it (i assume) because startup code already deal with SysBase, its always on the need it value, and no needs to set it at all for us.
Quote:
I don´t know why it is used in this part of code, but I don´t think that it´s done just for fun
Like i know it :) All i know that SysBase automatically initialized by the startup code, and there no needs for us to have that "SysBase = anything".
What i mean is that even if Fab put it here for reason, for us it not need it as startup code deal with it already.
@LveForIt
Yeah, already removed it all and already tested all is fine.
What i mean is that even if Fab put it here for reason, for us it not need it as startup code deal with it already.
Since it's not explicity referenced, the only reason must be allow exec.library calls, but that seems odd as if this is in the main code you allready have it set up (even in Morphos I would guess) perhaps it's just got coppied over from another project by accident?
If this were in a loadable module of somekind with no startup code then it would need to be followed by code obtaining IExec from it, but doesn't appear to be the case.
One way you can manage the process is by a counter.
Count up when process start, count down when process ends, so at end of program you can see if count is 0 or not, and you know if process has stoped, then maybe you should do a IDOS->Delay(5), to make shore they are really stooped.
“extern” does not make sense, this is what you use when, you want to tell the compiler that we have variable, but sense its a global, we can't declare it here. But its declared else where.
So drop the "extern", it does not make sense inside TimerFunc()
Hmm... if it´s the SysBase defined by the startup code, the "extern" makes perfect sense here. SysBase is defined "elsewhere", and it should not be a local (automatic) variable of TimerFunc(). That´s what "extern" means here.
But what about this code running outside the main code´s scope?
I think that´s the reason for the "SysBase = *((struct ExecBase **) 4);" thingie. SysBase is declared inside the function (as a local, and here the "extern" indeed doesn´t make any sense. "static" would be the better choice, maybe) and must therefore be initialized with something that makes sense...
But if this is a function running within the main code´s scope only, it´s total nonsense to declare SysBase over and over. Bad coding practice
Sometimes it depends on the source code organization. If the files containing the whole code are organized in static modules, (global) variables like SysBase might not be visible within a certain file if they are not declared "extern".
If you don´t want to mix machine dependend code with "portable" code, it´s best practice not to mess up the "portable" code with machine dependend globals.
Locals must be initialized local, if you don´t declare them "extern" (and define the variable containing the needed value elsewhere). If the "local" variable is declared "extern", this does indeed mean that it´s a global. That´s what SysBase is in most cases. A global. For OS4, it´s a variable defined by the startup code.
Here (in this function TimerFunc() ) it is a question of context, if "extern" makes sense or if the local declaration of SysBase is meant for "clean" code.
If the function is running within the scope of the startup module, "extern" makes perfect sense (and it would lead most certainly to a crash, if you discard the "extern" qualifier). But in this case the initialization is unnecessary. SysBase is initialized already (by the startup module).
If it´s running outside this scope, the correct value of SysBase should be provided by parameter and could be used directly then.
Back in 68k times it was quite usual to initialize a local SysBase by "SysBase = *((struct ExecBase **) 4); " (although most today´s compiler´s startup code provides for SysBase), but with the advent of zeropage protection, this is bad practice.
For me, this function´s code looks a bit messy. On the one hand, global SysBase is used (MOS and OS4 port), on the other hand, "bootstrap" initialization of SysBase is used (obviously, meant for 68k systems). The scope is quite unclear here...
Edit: If the code compiles without the "extern" AND without the initialization, there must be a global SysBase already somewhere within the source file. But then it should throw at least a warning about redefinition... weird.
When i exit, all of them exit too. All seems fine.
Then i run second instance from shell : dsi, ignoring of which run those processes again fine and browser works. Just after i ignore DSI i have on serial:
Quote:
Task 0x65E793E0 (Shell Process) bad access @ 0x63B94608, pc = 0x018200A8, lr = 0x0182012C,
Also do check this way: i just run odyssey from shell, exit, close that shell window, spawn new one, run odyssey : all works (but that expected, as it kind of new instance).
Running second time in new tab : works too. Running third time in another tab: works too.
"endcli" in all tabs after i run second or third instance works fine, i can exit from them, etc (so no locked or whatever).
Only problem is exactly in the same shell window run/exit/run again.
Quote:
Have you tried running this from gdb? I know it has it's limitations but it might still catch something...
Well , as it will be inside of gdb, it will spawn for every new run new process and there will be no crash :) (as it didn't crashes for as in all places, only direct run from the same shell window in the same tab). Or you mean attach to gdb when its already crashed ? Tried as well, backtrace / bt just show some mess. Or if you mean to do so because dind't see crashlog : nope, our reaper catch it fine, i even post it before and recopy it in that post again.
Edit: If the code compiles without the "extern" AND without the initialization, there must be a global SysBase already somewhere within the source file. But then it should throw at least a warning about redefinition... weird.
It'll quite happily compile without error that way under OS4 as the SysBase variable is not access directly ( functuion calls are using IExec) (if -wall is in use it might throw up an warning about it being unused)
Probably your threading backend has an issue with the startup/end message handling. It might only appear now in 1,23 because more threads are involved (garbage collector thread, localstorage thread and, all the mediaplayer threads and so on...).
But it just happens when i only run odyssey , do nothing (so only about: page), quit, and run it again. At thise moment imho only few threads involved (those which was in 1.16 as well) ?