I came across an interesting thing yesterday where waiting was avoided in some instances without creating a race condition. I didn't understand the process initially but now it makes sense.
Once upon a time, back in history, the TAO OS was touted as the way forward for Amiga. Sadly, alack, there were a lot of things in Tao that would have made this very difficult to achieve. Despite that, it does have a lot of interesting things within it. For example, whereas Amiga has libraries, Tao simply has tools.
Now, the situation that revealed this 'waiting shortcut' was its static data implementation. Static data allows a tool (which as mentioned is similar to an Amiga library) to retain a value between calls for a particular execution. So you can call the tool multiple times and the static data will not be forgotten by that tool between calls.
That static data has to basically be tied to a process and that tool. It is tied to a process by checking if the global pointer equals the current check value. If it does equal then you already have the static data and don't need to do any more. If it doesn't then you have to go looking for the static data (whereby it is found or initially created).
Here is example code:
cpy [pCache.sc_Data], pStatics ; Get the statics data hopefuly if [pCache.sc_Check] != gp ; Check if it belongs to our process? qcall sys/kn/statics/statics_get,(pCache,[pControl.sc_Tool],pControl,pUserData: pStatics,iError) ; If it doesn't, go find it. endif
There is no visible waiting in the first two lines when we get the static data. It is certain that there is a wait in the 3rd line tool because it will be dealing with a shared list.
I wasn't aware CPUs have atomic operations meaning they don't get interrupted until they complete. That was the answer to the puzzle for me.
Basically we want the statics when we enter this code but we don't want to slow down if we already have them; only if we don't have them. So we grab the statics data pointer. We then check if the last one to update the statics pointer was our process. If it was then no more to do as our statics pointer is correct. Otherwise it may not be and we go find it using the shared list under lock.
This works because the statics pointer won’t change while we are getting it and even though sc_check might change after we get the statics pointer, the only process that will change it to our gp will be our process during a lock. So if it still equals gp then no other process has changed the gp value meaning the statics pointer had not been changed at that point.
I hope that makes sense? Maybe someone else can explain it better than me… That’s if anyone reads this post seeing it won’t go on the main page! Anyhow, hope that is of interest to someone else as well.
I was curious if that happens in any other code that anyone might know of? Last edited by gonegahgah on 06-Dec-2022 at 08:23 AM. Last edited by gonegahgah on 06-Dec-2022 at 08:23 AM.
|