Search in sources :

Example 1 with OffheapReadWriteLock

use of org.apache.ignite.internal.util.OffheapReadWriteLock in project ignite by apache.

the class IgniteOffheapReadWriteLockSelfTest method testLockUpgradeMultipleLocks.

/**
 * @throws Exception if failed.
 */
public void testLockUpgradeMultipleLocks() throws Exception {
    final int numPairs = 100;
    final Pair[] data = new Pair[numPairs];
    final OffheapReadWriteLock lock = new OffheapReadWriteLock(16);
    final long ptr = GridUnsafe.allocateMemory(OffheapReadWriteLock.LOCK_SIZE * numPairs);
    for (int i = 0; i < numPairs; i++) {
        data[i] = new Pair();
        lock.init(ptr + i * OffheapReadWriteLock.LOCK_SIZE, TAG_0);
    }
    final AtomicInteger reads = new AtomicInteger();
    final AtomicInteger writes = new AtomicInteger();
    final AtomicInteger successfulUpgrades = new AtomicInteger();
    final AtomicBoolean done = new AtomicBoolean(false);
    IgniteInternalFuture<Long> fut = GridTestUtils.runMultiThreadedAsync(new Callable<Object>() {

        /**
         * {@inheritDoc}
         */
        @Override
        public Object call() throws Exception {
            ThreadLocalRandom rnd = ThreadLocalRandom.current();
            while (!done.get()) {
                int idx = rnd.nextInt(numPairs);
                long lPtr = ptr + idx * OffheapReadWriteLock.LOCK_SIZE;
                boolean locked = lock.readLock(lPtr, TAG_0);
                boolean write = false;
                try {
                    assert locked;
                    Pair pair = data[idx];
                    assertEquals("Failed check for index: " + idx, pair.a, -pair.b);
                    write = rnd.nextInt(10) < 2;
                    if (write) {
                        // TAG fail will cause NPE.
                        boolean upg = lock.upgradeToWriteLock(lPtr, TAG_0);
                        writes.incrementAndGet();
                        if (upg)
                            successfulUpgrades.incrementAndGet();
                        int delta = rnd.nextInt(100_000);
                        pair.a += delta;
                        pair.b -= delta;
                    }
                } finally {
                    if (write)
                        lock.writeUnlock(lPtr, TAG_0);
                    else
                        lock.readUnlock(lPtr);
                }
                reads.incrementAndGet();
            }
            return null;
        }
    }, 32, "tester");
    for (int i = 0; i < 30; i++) {
        Thread.sleep(1_000);
        info("Reads=" + reads.getAndSet(0) + ", writes=" + writes.getAndSet(0) + ", upgrades=" + successfulUpgrades.getAndSet(0));
    }
    done.set(true);
    fut.get();
    validate(data);
}
Also used : OffheapReadWriteLock(org.apache.ignite.internal.util.OffheapReadWriteLock) BrokenBarrierException(java.util.concurrent.BrokenBarrierException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom)

Example 2 with OffheapReadWriteLock

use of org.apache.ignite.internal.util.OffheapReadWriteLock in project ignite by apache.

the class IgniteOffheapReadWriteLockSelfTest method checkTagIdUpdate.

/**
 * @throws Exception if failed.
 */
private void checkTagIdUpdate(final boolean waitBeforeSwitch) throws Exception {
    final int numPairs = 100;
    final Pair[] data = new Pair[numPairs];
    for (int i = 0; i < numPairs; i++) data[i] = new Pair();
    final OffheapReadWriteLock lock = new OffheapReadWriteLock(16);
    final long ptr = GridUnsafe.allocateMemory(OffheapReadWriteLock.LOCK_SIZE);
    lock.init(ptr, TAG_0);
    final AtomicInteger reads = new AtomicInteger();
    final AtomicInteger writes = new AtomicInteger();
    final AtomicBoolean done = new AtomicBoolean(false);
    final int threadCnt = 32;
    final CyclicBarrier barr = new CyclicBarrier(threadCnt);
    IgniteInternalFuture<Long> fut = GridTestUtils.runMultiThreadedAsync(new Callable<Object>() {

        /**
         * {@inheritDoc}
         */
        @Override
        public Object call() throws Exception {
            try {
                ThreadLocalRandom rnd = ThreadLocalRandom.current();
                int tag = TAG_0;
                long lastSwitch = System.currentTimeMillis();
                while (true) {
                    boolean write = rnd.nextInt(10) < 2;
                    boolean locked;
                    boolean switched = false;
                    if (write) {
                        locked = lock.writeLock(ptr, tag);
                        if (locked) {
                            try {
                                assertTrue(lock.isWriteLocked(ptr));
                                assertFalse(lock.isReadLocked(ptr));
                                int idx = rnd.nextInt(numPairs);
                                int delta = rnd.nextInt(100_000);
                                data[idx].a += delta;
                                data[idx].b -= delta;
                            } finally {
                                switched = System.currentTimeMillis() - lastSwitch > 1_000 || !waitBeforeSwitch;
                                if (switched && waitBeforeSwitch)
                                    info("Switching...");
                                int tag1 = (tag + (switched ? 1 : 0)) & 0xFFFF;
                                if (tag1 == 0)
                                    tag1 = 1;
                                lock.writeUnlock(ptr, tag1);
                            }
                            writes.incrementAndGet();
                        }
                    } else {
                        locked = lock.readLock(ptr, tag);
                        if (locked) {
                            try {
                                assert locked;
                                assertFalse(lock.isWriteLocked(ptr));
                                assertTrue(lock.isReadLocked(ptr));
                                for (int i1 = 0; i1 < data.length; i1++) {
                                    Pair pair = data[i1];
                                    assertEquals("Failed check for index: " + i1, pair.a, -pair.b);
                                }
                            } finally {
                                lock.readUnlock(ptr);
                            }
                            reads.incrementAndGet();
                        }
                    }
                    if (!locked || switched) {
                        try {
                            barr.await();
                        } catch (BrokenBarrierException ignore) {
                            // Done.
                            return null;
                        }
                        tag = (tag + 1) & 0xFFFF;
                        if (tag == 0)
                            tag = 1;
                        if (waitBeforeSwitch || (!waitBeforeSwitch && tag == 1))
                            info("Switch to a new tag: " + tag);
                        if (done.get()) {
                            barr.reset();
                            return null;
                        }
                        lastSwitch = System.currentTimeMillis();
                    }
                }
            } catch (Throwable e) {
                e.printStackTrace();
            }
            return null;
        }
    }, threadCnt, "tester");
    for (int i = 0; i < 30; i++) {
        Thread.sleep(1_000);
        info("Reads: " + reads.getAndSet(0) + ", writes=" + writes.getAndSet(0));
    }
    done.set(true);
    fut.get();
    validate(data);
}
Also used : BrokenBarrierException(java.util.concurrent.BrokenBarrierException) OffheapReadWriteLock(org.apache.ignite.internal.util.OffheapReadWriteLock) BrokenBarrierException(java.util.concurrent.BrokenBarrierException) CyclicBarrier(java.util.concurrent.CyclicBarrier) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom)

Example 3 with OffheapReadWriteLock

use of org.apache.ignite.internal.util.OffheapReadWriteLock in project ignite by apache.

the class IgniteOffheapReadWriteLockSelfTest method testConcurrentUpdatesMultipleLocks.

/**
 * @throws Exception if failed.
 */
public void testConcurrentUpdatesMultipleLocks() throws Exception {
    final int numPairs = 100;
    final Pair[] data = new Pair[numPairs];
    final OffheapReadWriteLock lock = new OffheapReadWriteLock(16);
    final long ptr = GridUnsafe.allocateMemory(OffheapReadWriteLock.LOCK_SIZE * numPairs);
    for (int i = 0; i < numPairs; i++) {
        data[i] = new Pair();
        lock.init(ptr + i * OffheapReadWriteLock.LOCK_SIZE, TAG_0);
    }
    final AtomicInteger reads = new AtomicInteger();
    final AtomicInteger writes = new AtomicInteger();
    final AtomicBoolean done = new AtomicBoolean(false);
    IgniteInternalFuture<Long> fut = GridTestUtils.runMultiThreadedAsync(new Callable<Object>() {

        /**
         * {@inheritDoc}
         */
        @Override
        public Object call() throws Exception {
            ThreadLocalRandom rnd = ThreadLocalRandom.current();
            while (!done.get()) {
                boolean write = rnd.nextInt(10) < 2;
                int idx = rnd.nextInt(numPairs);
                long lPtr = ptr + idx * OffheapReadWriteLock.LOCK_SIZE;
                if (write) {
                    lock.writeLock(lPtr, TAG_0);
                    try {
                        assertTrue(lock.isWriteLocked(lPtr));
                        assertFalse(lock.isReadLocked(lPtr));
                        int delta = rnd.nextInt(100_000);
                        data[idx].a += delta;
                        data[idx].b -= delta;
                    } finally {
                        lock.writeUnlock(lPtr, TAG_0);
                    }
                    writes.incrementAndGet();
                } else {
                    lock.readLock(lPtr, TAG_0);
                    try {
                        assertFalse(lock.isWriteLocked(lPtr));
                        assertTrue(lock.isReadLocked(lPtr));
                        Pair pair = data[idx];
                        assertEquals("Failed check for index: " + idx, pair.a, -pair.b);
                    } finally {
                        lock.readUnlock(lPtr);
                    }
                    reads.incrementAndGet();
                }
            }
            return null;
        }
    }, 32, "tester");
    for (int i = 0; i < 30; i++) {
        Thread.sleep(1_000);
        info("Reads: " + reads.getAndSet(0) + ", writes=" + writes.getAndSet(0));
    }
    done.set(true);
    fut.get();
    validate(data);
}
Also used : OffheapReadWriteLock(org.apache.ignite.internal.util.OffheapReadWriteLock) BrokenBarrierException(java.util.concurrent.BrokenBarrierException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom)

Example 4 with OffheapReadWriteLock

use of org.apache.ignite.internal.util.OffheapReadWriteLock in project ignite by apache.

the class IgniteOffheapReadWriteLockSelfTest method testConcurrentUpdatesSingleLock.

/**
 * @throws Exception if failed.
 */
public void testConcurrentUpdatesSingleLock() throws Exception {
    final int numPairs = 100;
    final Pair[] data = new Pair[numPairs];
    for (int i = 0; i < numPairs; i++) data[i] = new Pair();
    final OffheapReadWriteLock lock = new OffheapReadWriteLock(16);
    final long ptr = GridUnsafe.allocateMemory(OffheapReadWriteLock.LOCK_SIZE);
    lock.init(ptr, TAG_0);
    final AtomicInteger reads = new AtomicInteger();
    final AtomicInteger writes = new AtomicInteger();
    final AtomicBoolean done = new AtomicBoolean(false);
    IgniteInternalFuture<Long> fut = GridTestUtils.runMultiThreadedAsync(new Callable<Object>() {

        /**
         * {@inheritDoc}
         */
        @Override
        public Object call() throws Exception {
            try {
                ThreadLocalRandom rnd = ThreadLocalRandom.current();
                while (!done.get()) {
                    boolean write = rnd.nextInt(10) < 2;
                    if (write) {
                        boolean locked = lock.writeLock(ptr, TAG_0);
                        try {
                            // No tag change in this test.
                            assert locked;
                            assertTrue(lock.isWriteLocked(ptr));
                            assertFalse(lock.isReadLocked(ptr));
                            int idx = rnd.nextInt(numPairs);
                            int delta = rnd.nextInt(100_000);
                            data[idx].a += delta;
                            data[idx].b -= delta;
                        } finally {
                            lock.writeUnlock(ptr, TAG_0);
                        }
                        writes.incrementAndGet();
                    } else {
                        boolean locked = lock.readLock(ptr, TAG_0);
                        try {
                            assert locked;
                            assertFalse(lock.isWriteLocked(ptr));
                            assertTrue(lock.isReadLocked(ptr));
                            for (int i1 = 0; i1 < data.length; i1++) {
                                Pair pair = data[i1];
                                assertEquals("Failed check for index: " + i1, pair.a, -pair.b);
                            }
                        } finally {
                            lock.readUnlock(ptr);
                        }
                        reads.incrementAndGet();
                    }
                }
            } catch (Throwable e) {
                e.printStackTrace();
            }
            return null;
        }
    }, 32, "tester");
    for (int i = 0; i < 30; i++) {
        Thread.sleep(1_000);
        info("Reads: " + reads.getAndSet(0) + ", writes=" + writes.getAndSet(0));
    }
    done.set(true);
    fut.get();
    validate(data);
}
Also used : OffheapReadWriteLock(org.apache.ignite.internal.util.OffheapReadWriteLock) BrokenBarrierException(java.util.concurrent.BrokenBarrierException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom)

Aggregations

BrokenBarrierException (java.util.concurrent.BrokenBarrierException)4 ThreadLocalRandom (java.util.concurrent.ThreadLocalRandom)4 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4 OffheapReadWriteLock (org.apache.ignite.internal.util.OffheapReadWriteLock)4 CyclicBarrier (java.util.concurrent.CyclicBarrier)1