Duncan
Duncan

Reputation: 990

Cache Not updating for MCS Lock in Java

I'm getting some really odd cache behavior for an MCS Lock in Java. Basically, it will work for up to four threads (the number of cores on my machine), but will get stuck for more. When I debug, I see that the program is getting stuck on the line

while (qnode.locked);

Inside of the lock() function. When debugging, I can see that one of the thread's QNode has locked set to false, but I'm guessing that's because the debugger causes the cache to update. I just threw "volatile" onto all variables as a desperate attempt to no avail. Here's the class that I'm using:

class MCSLock
{
private volatile AtomicReference<QNode> tail;
private volatile ThreadLocal<QNode> myNode;

public MCSLock()
{
    tail = new AtomicReference<QNode>(null);
    myNode = new ThreadLocal<QNode>()
            {
                protected QNode initialValue() { return new QNode(); }
            };
}

public void lock()
{
    QNode qnode = myNode.get();
    QNode pred = tail.getAndSet(qnode);
    if (pred != null)
    {
        qnode.locked = true;
        pred.next = qnode;
        while (qnode.locked);
    }
}

public void unlock()
{
    QNode qnode = myNode.get();
    if (qnode.next == null)
    {
        if (tail.compareAndSet(qnode, null)) return;
        while (qnode.next == null);
    }
    qnode.next.locked = false;
    qnode.next = null;
}

private class QNode
{
    volatile boolean locked = false;
    volatile QNode next = null;
}
}

Upvotes: 1

Views: 477

Answers (3)

Ilia Baziukov
Ilia Baziukov

Reputation: 11

I have got the same problem. There is a small error into unlock() method. Before setting the false value into locked variable for the next node we need to wait untill this value gets true into lock method. I added

 
while (!qnode.next.locked) {}
    
before

    qnode.next.locked = false;
    
into unlock() method and the problem ran away!

Upvotes: 1

dinojrrr
dinojrrr

Reputation: 16

Your code works! However, my guess is that your system isn't good enough to do >4 threads quickly.

Running on a dual-core i5, execution hung on 5 threads

Running on a quad-core overclocked i7, execution completed on 5 threads as expected. Woo!

Upvotes: 0

clinton
clinton

Reputation: 612

while (qnode.locked); doesn't do anything as far as i can see . Maybe you mean

    do {
        pred.next = qnode;
        // update qnode
       } while (qnode.locked);

Upvotes: 0

Related Questions