package linkedlists.lockbased; import java.util.Collection; import java.util.Random; import java.util.Stack; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import contention.abstractions.AbstractCompositionalIntSet; /** * Linked list implementation of integer set using * optimistic locking except for the contains. * * @author Vincent Gramoli * */ public class OptimisticListSortedSetWaitFreeContains extends AbstractCompositionalIntSet { /** The first node of the list */ final private Node head; public OptimisticListSortedSetWaitFreeContains() { Node min = new Node(Integer.MIN_VALUE); Node max = new Node(Integer.MAX_VALUE); min.setNext(max); head = min; } private boolean validate(Node pred, Node curr) { Node node = head; while (node.getValue() <= pred.getValue()) { if (node == pred) return pred.getNext() == curr; node = node.getNext(); } return false; } public boolean addInt(int value) { while (true) { Node pred = head; Node curr = pred.getNext(); while (curr.getValue() < value) { pred = curr; curr = curr.getNext(); } pred.lock(); curr.lock(); try { if (validate(pred,curr)) { if (curr.getValue() == value) { return false; } else { Node node = new Node(value, curr); pred.setNext(node); return true; } } } finally { pred.unlock(); curr.unlock(); } } } public boolean removeInt(int value) { while (true) { Node pred = head; Node curr = pred.getNext(); while (curr.getValue() < value) { pred = curr; curr = curr.getNext(); } pred.lock(); curr.lock(); try { if (validate(pred,curr)) { if (curr.getValue() == value) { pred.setNext(curr.getNext()); return true; } else { return false; } } } finally { pred.unlock(); curr.unlock(); } } } /** * The contains does not use any locks * It is wait-free provided that not an infinite * number of insertions are concurrent */ public boolean containsInt(int value) { Node pred = head; Node curr = pred.getNext(); while (curr.getValue() < value) { pred = curr; curr = curr.getNext(); } return (curr.getValue() == value); } /** * This method cannot be supported with * such locking mechanism */ @Override public boolean addAll(Collection<Integer> c) { throw new UnsupportedOperationException(); } /** * This method cannot be supported with * such locking mechanism */ @Override public boolean removeAll(Collection<Integer> c) { throw new UnsupportedOperationException(); } /** * This method is not thread-safe. It cannot * be made atomic with such locking mechanism */ public int size() { int n = 0; Node node = head; while (node.getNext().getValue() < Integer.MAX_VALUE) { n++; node = node.getNext(); } return n; } public void clear() { Node max = new Node(Integer.MAX_VALUE); head.setNext(max); } @Override public Object getInt(int x) { throw new UnsupportedOperationException(); } @Override public Object putIfAbsent(int x, int y) { throw new UnsupportedOperationException(); } public class Node { final private int value; private volatile Node next; final private Lock lock; public Node(int value, Node next) { this.value = value; this.next = next; this.lock = new ReentrantLock(); } public Node(int value) { this(value, null); } public int getValue() { return value; } public void setNext(Node next) { this.next = next; } public Node getNext() { return next; } public void lock() { this.lock.lock(); } public void unlock() { this.lock.unlock(); } } }