if (new < old[0]) then
old[0] => old[1], new ==> old[0]
else if (new < old[1]) then
new ==> old[1]

I want my whole algorithm code block to be executed in an atomic way, as a whole.

What are you trying to do (big picture that is, not per-fragment)? Per-fragment you're obviously just keeping the 2 lowest values.

If every fragment has their own unique old[0] and old[1], You could try: read old[0..1]; compute new old[0..1]; mem barrier; write old[0..1]. But don't know whether that'd be fast.

Another possibility is to ping-pong back and forth between two images (or image slices). Bind the buffer with the input old[0..1] as input. Bind the buffer with the output old[0..1] as output (as 1..2 MRTs on gl_FragData[0..1] for instance), and have the frag shader do similarly to before (read old[0..1]; compute new old[0..1]; write to gl_FragData[0..1]). No memory barrier sync required and likely to pipeline well.

What are you trying to do (big picture that is, not per-fragment)? Per-fragment you're obviously just keeping the 2 lowest values.

Thanks for your reply.
For the stuff I am interested in, I think I'm running into the general limitation of atomics for this problem. Basically, I would like to read a couple of uints (or vec4's, that really is what I want ultimately), do some stuff, then write these values back, all in an atomic fashion.
I wish GPU hardware and GLSL could provide "shader transactions" to atomically execute a block of code.