Hm. maybe I am missing a lot there, so I would be happy for people to correct me. But in my book a linked list is like a worst case to make "lock free". For me the first step to make something lock free is that all the frequent operations on a datastructure only need one item to change. A fixed size stack in this case. Once you have multiple things to keep in lock the old style lock is a necessity! You might invent one that works slightly better (like his sleep(250)..) under some benchmarks. But to me lock free means an algorithm where both producers and consumers have to only ever access one single atomic value.
As I put in the first sentence, I might be missing a lot there. Could you please point me to the definition you are referring to? I probably did not express myself very well. And I already learned a bit by thinking about this differently. You (and everybody else, so you are right!) define lock free as dead lock free. Which can be done with a carefully chosen lock. I was always thinking of lock free as a pure performance optimization which admittedly is different to the algorithmic property. Am I on the right track? If yes, it should answer your question why I got involved in the discussion: to learn.
This is classic test-then-act, isn't it? What happens if another thread bumps obj->rc after the comparison to 0, but before the deletion? That other thread could find itself referring to a suddenly-deleted object, or am I missing something?