Package co.paralleluniverse.strands

Examples of co.paralleluniverse.strands.Strand


        for (int spins = SPINS;;) {
            WNode np, pp;
            int ps;
            long s, ns;
            Strand w;
            while ((np = node.prev) != p && np != null)
                (p = np).next = node;   // stale
            if (whead == p) {
                for (int k = spins;;) { // spin at head
                    if (((s = state) & ABITS) == 0L) {
View Full Code Here


        WNode node = null, group = null, p;
        for (int spins = -1;;) {
            for (;;) {
                long s, m, ns;
                WNode h, q;
                Strand w; // anti-barging guard
                if (group == null && (h = whead) != null
                        && (q = h.next) != null && q.mode != RMODE)
                    break;
                if ((m = (s = state) & ABITS) < RFULL
                        ? U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT)
                        : (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L)) {
                    if (group != null) {  // help release others
                        for (WNode r = group;;) {
                            if ((w = r.strand) != null) {
                                r.strand = null;
                                w.unpark();
                            }
                            if ((r = group.cowait) == null)
                                break;
                            U.compareAndSwapObject(group, WCOWAIT, r, r.cowait);
                        }
                    }
                    return ns;
                }
                if (m >= WBIT)
                    break;
            }
            if (spins > 0) {
                if (ThreadLocalRandom.current().nextInt() >= 0)
                    --spins;
            } else if ((p = wtail) == null) {
                WNode h = new WNode(WMODE, null);
                if (U.compareAndSwapObject(this, WHEAD, null, h))
                    wtail = h;
            } else if (spins < 0)
                spins = (p == whead) ? SPINS : 0;
            else if (node == null)
                node = new WNode(WMODE, p);
            else if (node.prev != p)
                node.prev = p;
            else if (p.mode == RMODE && p != whead) {
                WNode pp = p.prev;  // become co-waiter with group p
                if (pp != null && p == wtail
                        && U.compareAndSwapObject(p, WCOWAIT,
                        node.cowait = p.cowait, node)) {
                    node.strand = Strand.currentStrand();
                    for (long time;;) {
                        if (interruptible && Strand.interrupted())
                            return cancelWaiter(node, p, true);
                        if (deadline == 0L)
                            time = 0L;
                        else if ((time = deadline - System.nanoTime()) <= 0L)
                            return cancelWaiter(node, p, false);
                        if (node.strand == null)
                            break;
                        if (p.prev != pp || p.status == CANCELLED
                                || p == whead || p.prev != pp) {
                            node.strand = null;
                            break;
                        }
                        if (node.strand == null) // must recheck
                            break;
                        park(time);
                    }
                    group = p;
                }
                node = null; // throw away
            } else if (U.compareAndSwapObject(this, WTAIL, p, node)) {
                p.next = node;
                break;
            }
        }

        for (int spins = SPINS;;) {
            WNode np, pp, r;
            int ps;
            long m, s, ns;
            Strand w;
            while ((np = node.prev) != p && np != null)
                (p = np).next = node;
            if (whead == p) {
                for (int k = spins;;) {
                    if ((m = (s = state) & ABITS) != WBIT) {
                        if (m < RFULL
                                ? U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT)
                                : (ns = tryIncReaderOverflow(s)) != 0L) {
                            whead = node;
                            node.prev = null;
                            while ((r = node.cowait) != null) {
                                if (U.compareAndSwapObject(node, WCOWAIT,
                                        r, r.cowait)
                                        && (w = r.strand) != null) {
                                    r.strand = null;
                                    w.unpark(); // release co-waiter
                                }
                            }
                            return ns;
                        }
                    } else if (ThreadLocalRandom.current().nextInt() >= 0
View Full Code Here

     * @param interrupted if already interrupted
     * @return INTERRUPTED if interrupted or Strand.interrupted, else zero
     */
    private long cancelWaiter(WNode node, WNode group, boolean interrupted) {
        if (node != null && group != null) {
            Strand w;
            node.status = CANCELLED;
            node.strand = null;
            // unsplice cancelled nodes from group
            for (WNode p = group, q; (q = p.cowait) != null;) {
                if (q.status == CANCELLED)
                    U.compareAndSwapObject(p, WNEXT, q, q.next);
                else
                    p = q;
            }
            if (group == node) {
                WNode r; // detach and wake up uncancelled co-waiters
                while ((r = node.cowait) != null) {
                    if (U.compareAndSwapObject(node, WCOWAIT, r, r.cowait)
                            && (w = r.strand) != null) {
                        r.strand = null;
                        w.unpark();
                    }
                }
                for (WNode pred = node.prev; pred != null;) { // unsplice
                    WNode succ, pp;        // find valid successor
                    while ((succ = node.next) == null
                            || succ.status == CANCELLED) {
                        WNode q = null;    // find successor the slow way
                        for (WNode t = wtail; t != null && t != node; t = t.prev)
                            if (t.status != CANCELLED)
                                q = t;     // don't link if succ cancelled
                        if (succ == q || // ensure accurate successor
                                U.compareAndSwapObject(node, WNEXT,
                                succ, succ = q)) {
                            if (succ == null && node == wtail)
                                U.compareAndSwapObject(this, WTAIL, node, pred);
                            break;
                        }
                    }
                    if (pred.next == node) // unsplice pred link
                        U.compareAndSwapObject(pred, WNEXT, node, succ);
                    if (succ != null && (w = succ.strand) != null) {
                        succ.strand = null;
                        w.unpark();       // wake up succ to observe new pred
                    }
                    if (pred.status != CANCELLED || (pp = pred.prev) == null)
                        break;
                    node.prev = pp;        // repeat if new pred wrong/cancelled
                    U.compareAndSwapObject(pp, WNEXT, pred, succ);
View Full Code Here

             * 3. Otherwise, this strand is eligible for lock if
             *    it is either a reentrant acquire or
             *    queue policy allows it. If so, update state
             *    and set owner.
             */
            Strand current = Strand.currentStrand();
            int c = getState();
            int w = exclusiveCount(c);
            if (c != 0) {
                // (Note: if c != 0 and w == 0 then shared count != 0)
                if (w == 0 || current != getExclusiveOwnerStrand())
View Full Code Here

            setExclusiveOwnerStrand(current);
            return true;
        }

        protected final boolean tryReleaseShared(int unused) {
            Strand current = Strand.currentStrand();
            if (firstReader == current) {
                // assert firstReaderHoldCount > 0;
                if (firstReaderHoldCount == 1)
                    firstReader = null;
                else
                    firstReaderHoldCount--;
            } else {
                HoldCounter rh = cachedHoldCounter;
                if (rh == null || rh.tid != current.getId())
                    rh = readHolds.get();
                int count = rh.count;
                if (count <= 1) {
                    readHolds.remove();
                    if (count <= 0)
View Full Code Here

             *    the more typical non-reentrant case.
             * 3. If step 2 fails either because strand
             *    apparently not eligible or CAS fails or count
             *    saturated, chain to version with full retry loop.
             */
            Strand current = Strand.currentStrand();
            int c = getState();
            if (exclusiveCount(c) != 0 &&
                getExclusiveOwnerStrand() != current)
                return -1;
            int r = sharedCount(c);
            if (!readerShouldBlock() &&
                r < MAX_COUNT &&
                compareAndSetState(c, c + SHARED_UNIT)) {
                if (r == 0) {
                    firstReader = current;
                    firstReaderHoldCount = 1;
                } else if (firstReader == current) {
                    firstReaderHoldCount++;
                } else {
                    HoldCounter rh = cachedHoldCounter;
                    if (rh == null || rh.tid != current.getId())
                        cachedHoldCounter = rh = readHolds.get();
                    else if (rh.count == 0)
                        readHolds.set(rh);
                    rh.count++;
                }
View Full Code Here

         * Performs tryLock for write, enabling barging in both modes.
         * This is identical in effect to tryAcquire except for lack
         * of calls to writerShouldBlock.
         */
        final boolean tryWriteLock() {
            Strand current = Strand.currentStrand();
            int c = getState();
            if (c != 0) {
                int w = exclusiveCount(c);
                if (w == 0 || current != getExclusiveOwnerStrand())
                    return false;
View Full Code Here

         * Performs tryLock for read, enabling barging in both modes.
         * This is identical in effect to tryAcquireShared except for
         * lack of calls to readerShouldBlock.
         */
        final boolean tryReadLock() {
            Strand current = Strand.currentStrand();
            for (;;) {
                int c = getState();
                if (exclusiveCount(c) != 0 &&
                    getExclusiveOwnerStrand() != current)
                    return false;
                int r = sharedCount(c);
                if (r == MAX_COUNT)
                    throw new Error("Maximum lock count exceeded");
                if (compareAndSetState(c, c + SHARED_UNIT)) {
                    if (r == 0) {
                        firstReader = current;
                        firstReaderHoldCount = 1;
                    } else if (firstReader == current) {
                        firstReaderHoldCount++;
                    } else {
                        HoldCounter rh = cachedHoldCounter;
                        if (rh == null || rh.tid != current.getId())
                            cachedHoldCounter = rh = readHolds.get();
                        else if (rh.count == 0)
                            readHolds.set(rh);
                        rh.count++;
                    }
View Full Code Here

        final int getReadHoldCount() {
            if (getReadLockCount() == 0)
                return 0;

            Strand current = Strand.currentStrand();
            if (firstReader == current)
                return firstReaderHoldCount;

            HoldCounter rh = cachedHoldCounter;
            if (rh != null && rh.tid == current.getId())
                return rh.count;

            int count = readHolds.get().count;
            if (count == 0) readHolds.remove();
            return count;
View Full Code Here

         * followed by the {@linkplain Strand#getName name} of the owning strand.
         *
         * @return a string identifying this lock, as well as its lock state
         */
        public String toString() {
            Strand o = sync.getOwner();
            return super.toString() + ((o == null) ?
                                       "[Unlocked]" :
                                       "[Locked by strand " + o.getName() + "]");
        }
View Full Code Here

TOP

Related Classes of co.paralleluniverse.strands.Strand

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.