I wanted to make a library and found this thread, so I'm resurrecting it regarding my question(s):
The idltool writes dummy Quote:
_manager_Obtain
and Quote:
_manager_Release
function which contains embedded assembler. Personal I'm no fan of having asm code embedded in c/c++ code. So i lookup what the meaning of the asm code is. Basically it is an atomic inc/der of the RefCount field.
So a little bit of google I found that at least gcc offers the Quote:
atomic_fecth_...
family of functions. So wouldn't it be possible to write the Quote:
That's interesting. I've used the SDK IDLTool to generate template code and didn't notice this at all. It was a number of years ago.
The GCC function is more portable than pure ASM. Being part of a standard C lib would be better. I can see this avoids using a Forbid lock which would use the same mechanism. Because of how PPC atomics work it works like a spinlock. I think any kind of busy waiting is inappropriate for AmigaOS but it's common elsewhere and on PPC, being RISC, it needs a spinlock for atomics. However, it is unlikely to be stuck in a loop, even for a few iterations.
I don't see much difference. Apart from the GCC code using an extra register and an isync. The embedded code looks slightly more optimised using only one register, but I have seen GCC generate strange looking code with random looking or odd register usage. Good job.
I think any kind of busy waiting is inappropriate for AmigaOS but it's common elsewhere and on PPC, being RISC, it needs a spinlock for atomics. However, it is unlikely to be stuck in a loop, even for a few iterations.
I hate busy waiting too. I learned programming on the Amiga, and thus to avoid busy waiting/loops. I kept that habit all the years and on all platform, for which developed software. But in this case I think wouldn't think of it as a busy loop, but it seems that's the way to make an atomic update on a ppc platform (as you said). Even that it could run endless (in theory), the practically circumstances doesn't trigger the endless run.
I have another question regarding the vector tables for the Obtain/Release/Expunge/Clone methods. They are only needed to be provided in the manager interface? I'm correct? The function interfaces like "main" don't need them? And in the functional interface sometimes they are left NULL (Expunge/Clone), sometimes a dummy method (for Obtain/Release) is set which just returns 0. Must this be? Or can I just replace the dummy methods with NULL?
I hate busy waiting too. I learned programming on the Amiga, and thus to avoid busy waiting/loops. I kept that habit all the years and on all platform, for which developed software.
It taught you well then. There are some examples on the Amiga where busy waiting was the norm but I still don't like the idea. One example is music modules. Common music interrupts set the audio playing, then busy wait inside an interrupt until a couple of raster lines have passed before setting a loop. I don't know why the loop isn't set on the next interrupt. If a 50 FPS interrupt was too slow how would anyone hear the samples? Some players did use two timers to avoid the busy waiting.
Quote:
But in this case I think wouldn't think of it as a busy loop, but it seems that's the way to make an atomic update on a ppc platform (as you said). Even that it could run endless (in theory), the practically circumstances doesn't trigger the endless run.
It is but still different to how AmigaOS usually works. For example a Forbid lock will increase counter and then wait if it isn't the first to lock. But this PPC example loops around until it's freed. So although it can work the same way, as it just needs to divide the add into primitives, the proper AmigaOS way would put the task into a wait state immediately if the reservation failed to store. At least as I see it.
Quote:
I have another question regarding the vector tables for the Obtain/Release/Expunge/Clone methods. They are only needed to be provided in the manager interface? I'm correct? The function interfaces like "main" don't need them?
After looking into this it looks like they need to be present for all interfaces. This makes sense as it also needs to track "main" access. See this as an example. Would help if it included links to facts it states. It mentioned required but not where this is stated.
And in the functional interface sometimes they are left NULL (Expunge/Clone), sometimes a dummy method (for Obtain/Release) is set which just returns 0. Must this be? Or can I just replace the dummy methods with NULL?
Some can be NULL but required ones need filling in. They should maintain counters and return counts. According to this here.
The idltool writes dummy _manager_Obtain and _manager_Release function which contains embedded assembler.
That's interesting. Every example library source I've looked at, including the skeleton library that comes with the clib2 source, the library code generated by Enhancer's LDCK, and apparently even older versions of IDLTool, generate this code (or something essentially the same) for _manager_Obtain():
That's not atomic, though the window of vulnerability is very small (just a few instructions). To get it to malfunction you'd have to have two different programs manipulating the interface at exactly the same time, and then have a task switch occur during those few instructions. That would be very difficult to arrange even if you were trying, let alone having it happen by chance. Which is fortunate, as there would appear to be a lot of libraries out there that use this code.
Thats interesting, I'm using a old sdk, and have not seen that macro.
I think might been added due to experimental SMP support, Is not L1 cache that’s per core? Keeping that in sync can be important.
This means that will be major problem for all amiga libraries, and perhaps other parts, unless isync is added, to keep public data in sync.
The parts I guess be affected, is chained lists, and we love this on Amiga.
I wonder however, won’t it better to warp functions in a dcbf and isync, inside a function pointers. instead of inserting maco, that only effect new functions.
void (*old_bla) () = NULL; // set on patch, or lib init.
Some stuff can perhaps be done using shadow memory creating some kind exception, so that, so that it can be hidden, out of sight. in the exception call itself. however that only good as fallback, not ideal for new code.
And I see problem, with fact that Amiga programs, like to manage their own memory.
Edited by LiveForIt on 2024/9/21 9:30:18 Edited by LiveForIt on 2024/9/21 9:32:33 Edited by LiveForIt on 2024/9/21 10:44:45 Edited by LiveForIt on 2024/9/21 10:58:08
(NutsAboutAmiga)
Basilisk II for AmigaOS4 AmigaInputAnywhere Excalibur and other tools and apps.
If my memory doesn’t failed. The strange thing is that the Obtain an d Releaee function generated by the idltool for the main interface are pure c. Like your posted code.
@LiveForIt
Learning ppc Sam is not my priority number one. But as you stated the risk for a race condition is really pretty low. And if smb ever comes to life, my opinion is that the os should take care that obtain/etc is protected by mutex/senphare/… so that 5he implementation does need to care care, resp. Doesn’t need to be update to work on updated oses.