Question: suppose I have xml inside an html document like

```
<html>
  <body>
     <xml>
        <foo>
          <bar />
          <baz />
        </foo>
     </xml>
   </body>
 </html>

```

What is the best way to apply xslt to the xml node?

Answer: 
It looks to me like this is an attempt at optimisation gone slightly wrong. I *suspect* it's trying for "TATAS" - "Test-and-test-and-set", where it doesn't even try to do the TestAndSet if it can see the lock is already taken.

In a [post about spin locks for .NET](http://www.bluebytesoftware.com/blog/CommentView,guid,72aaa68e-4cbd-41db-a7ce-ddc64411eafa.aspx), Joe Duffy writes this TATAS code as:

```
class SpinLock {
    private volatile int m_taken;

    public void Enter() {
        while (true) {
            if (m_taken == 0 &&
                    Interlocked.Exchange(ref m_taken, 1) == 0)
                break;
        }
    }

    public void Exit() {
        m_taken = 0;
    }
}

```

(Note that Joe is using 1 to mean locked and 0 to mean unlocked, unlike the code project sample - either is fine, just don't get confused between the two!)

Note that here the call to Interlocked.Exchange *is conditional on `m_taken` being 0*. This reduces contention - the relatively expensive (I guess) test-and-set operation is avoided there it's unnecessary. I *suspect* that's what the author was aiming at, but didn't quite get it right.

This is also mentioned in the [Wikipedia article about spinlocks](http://en.wikipedia.org/wiki/Spin_locking) under "significant optimisations":

> 
> To reduce inter-CPU bus traffic, when
>  the lock is not acquired, the code
>  should loop reading without trying to
>  write anything, until it reads a
>  changed value. Because of MESI caching
>  protocols, this causes the cache line
>  for the lock to become "Shared"; then
>  there is remarkably no bus traffic
>  while a CPU is waiting for the lock.
>  This optimization is effective on all
>  CPU architectures that have a cache
>  per CPU, because MESI is so
>  ubiquitous.
> 
> 
> 

That "loop reading" is exactly what the while loop does - until it sees `m_taken` change, it only reads. When it sees the change (i.e. when the lock is released) it has another go at locking.

Of course it's very possible that I'm missing something important - issues like this are very subtle.
Actually someone may call `TestAndSet(&m_s, 1)` i.e. `Leave()` from another thread just after `TestAndSet(&m_s, 0)` and before `if` test in `Enter()`. That way lock will not be obtained and `m_s` will not be equal to `0`. Therefore such check is needed.