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);
}
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);
}
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);
}
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);
}
Aggregations