static ParkEvent initializeOnce(AtomicReference<ParkEvent> ref, boolean resetEventBeforeWait) { ParkEvent result = ref.get(); if (result == null) { ParkEvent newEvent = ParkEvent.acquire(); /* * Assign a *new* cons-cell for this ParkEvent, whether it was acquired from the * free-list or allocated. */ newEvent.consCell = new ParkEventConsCell(newEvent); newEvent.event = false; newEvent.resetEventBeforeWait = resetEventBeforeWait; if (ref.compareAndSet(null, newEvent)) { /* We won the race. */ result = newEvent; } else { /* * We lost the race. We have one extra ParkEvent now, which we put back on the * queue, so that it is reused later on. */ ParkEvent.release(newEvent); result = ref.get(); } } return result; }
/** * Push an element onto the list. May be called by many threads simultaneously, so it uses a * compareAndSet loop. */ public static PinnedObjectImpl pushPinnedObject(PinnedObjectImpl newHead) { final Log trace = Log.noopLog().string("[PinnedObject.pushPinnedObject:").string(" newHead: ").object(newHead); final HeapImpl heap = HeapImpl.getHeapImpl(); final AtomicReference<PinnedObjectImpl> pinHead = heap.getPinHead(); PinnedObjectImpl sampleHead; do { sampleHead = pinHead.get(); newHead.setNext(sampleHead); } while (!pinHead.compareAndSet(sampleHead, newHead)); trace.string(" returns: ").object(newHead).string("]").newline(); return newHead; }
/** Return the head of the free-list, or null. */ public ParkEvent pop() { ParkEventConsCell sampleHead; ParkEventConsCell sampleNext; do { sampleHead = freeList.get(); if (sampleHead == null) { return null; } sampleNext = sampleHead.getNext(); } while (!freeList.compareAndSet(sampleHead, sampleNext)); return sampleHead.getElement(); } }
@Uninterruptible(reason = "Called from uninterruptible code.") private boolean compareAndSetHead(FeebleReference<? extends T> expect, FeebleReference<? extends T> update) { return head.compareAndSet(expect, update); }
/** Push an element on to the free-list. */ protected void push(ParkEvent element) { ParkEventConsCell sampleHead; /* Use up the cons-cell for each attempted push to avoid the ABA problem on pops. */ ParkEventConsCell nextHead = element.consumeConsCell(); do { sampleHead = freeList.get(); nextHead.setNext(sampleHead); } while (!freeList.compareAndSet(sampleHead, nextHead)); }