All you need to do is read the location that pointer points to as an atomic operation. So allocating a 50kb string would work in the same way as long as you could store it in a specific processes memory.
PX a=(0x00010001) //which points to 5
P0 x0=a=(0x00010001) //which points to 5
P1 y0=a
P1 pointer y1=0
P1 y1 = malloc(sizeof(int))
P2 x1=a=(0x00010001) //which points to 5
P1 *y = *y0 + 1 //aka 6
p3 x2=a=(0x00010001) //which points to 5
P1 a=y //you could do a lock to verify that a == (0x00010001) but if you don't care about dirty writes then then you can also do this as an atomic operation.
p3 x3=a=(0x00030001)//which points to 6
And once x0,x1,x2 stop pointing to (0x00010001) you can free that memory. The assumption is xN and yN is a process specific local variable preferably a register.
I couldn't really follow your example. I can't see how this solves race conditions where multiple threads can intermingle those instructions at will.
That's the basic problem with lock-free algorithms.
Did you maybe suggest to add one more indirection so all variables in a transaction are in one memory block behind a single pointer which can be atomically updated to newly allocated code?
I wonder what the overhead of that would be. All the allocations plus either keeping track of references or doing garbage collection...
Sorry, I will try and be more clear there are some good descriptions of this technique on the web but I can't remember what it's called. Still you have the basic idea and it's downsides. Still normally your dealing with larger objects so the overhead is a little different.
Just think about how a you normally work with objects. Normally you have a pointer to some allocated memory locationObjectPointer = (x00100) which points to a chunk of memory the size of 3 floats (x,y,z). Now normally when you update x and y you overwrite their memory locations which is fast in single threaded programming but you need to worry about something reading after you update x at (x00100) but before you update y (x00104).
However, if instead of updating in that memory block you created a new object locationObjectPointer2 = (x00600) copy'd what was in the original object and then when your done changed the pointer from the old object to your new one. Well, as you say you have the overhead of keeping track of references or doing garbage collection, but at the same time you can do a vary fast lock when you want to change the pointer and test to see if the object was changed. That test is actually hard to do with most types of memory management systems and normally creates a lot of overhead so it's a trade off.