Skip to content

Commit

Permalink
[Truffle] Finish encapsulating JDK-specific classes in platform.
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisseaton committed Feb 11, 2016
1 parent df75a85 commit b435b4f
Show file tree
Hide file tree
Showing 11 changed files with 171 additions and 72 deletions.
Expand Up @@ -9,45 +9,16 @@
*/
package org.jruby.truffle.core.queue;

import java.lang.invoke.MethodHandle;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ArrayBlockingQueueLocksConditions<T> extends DelegatingBlockingQueue<T> {
public interface ArrayBlockingQueueLocksConditions<T> extends BlockingQueue<T> {

private static final MethodHandle LOCK_FIELD_GETTER = MethodHandleUtils.getPrivateGetter(ArrayBlockingQueue.class, "lock");
private static final MethodHandle NOT_EMPTY_CONDITION_FIELD_GETTER = MethodHandleUtils.getPrivateGetter(ArrayBlockingQueue.class, "notEmpty");
private static final MethodHandle NOT_FULL_CONDITION_FIELD_GETTER = MethodHandleUtils.getPrivateGetter(ArrayBlockingQueue.class, "notFull");
ReentrantLock getLock();

private final ReentrantLock lock;
private final Condition notEmptyCondition;
private final Condition notFullCondition;
Condition getNotEmptyCondition();

public ArrayBlockingQueueLocksConditions(int capacity) {
super(new ArrayBlockingQueue<T>(capacity));

final ArrayBlockingQueue<T> queue = (ArrayBlockingQueue<T>) getQueue();

try {
lock = (ReentrantLock) LOCK_FIELD_GETTER.invokeExact(queue);
notEmptyCondition = (Condition) NOT_EMPTY_CONDITION_FIELD_GETTER.invokeExact(queue);
notFullCondition = (Condition) NOT_FULL_CONDITION_FIELD_GETTER.invokeExact(queue);
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}

public ReentrantLock getLock() {
return lock;
}

public Condition getNotEmptyCondition() {
return notEmptyCondition;
}

public Condition getNotFullCondition() {
return notFullCondition;
}
Condition getNotFullCondition();

}
Expand Up @@ -9,38 +9,14 @@
*/
package org.jruby.truffle.core.queue;

import java.lang.invoke.MethodHandle;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class LinkedBlockingQueueLocksConditions<T> extends DelegatingBlockingQueue<T> {
public interface LinkedBlockingQueueLocksConditions<T> extends BlockingQueue<T> {

private static final MethodHandle TAKE_LOCK_FIELD_GETTER = MethodHandleUtils.getPrivateGetter(LinkedBlockingQueue.class, "takeLock");
private static final MethodHandle NOT_EMPTY_CONDITION_FIELD_GETTER = MethodHandleUtils.getPrivateGetter(LinkedBlockingQueue.class, "notEmpty");
ReentrantLock getLock();

private final ReentrantLock lock;
private final Condition notEmptyCondition;

public LinkedBlockingQueueLocksConditions() {
super(new LinkedBlockingQueue<T>());

final LinkedBlockingQueue<T> queue = (LinkedBlockingQueue<T>) getQueue();

try {
lock = (ReentrantLock) TAKE_LOCK_FIELD_GETTER.invokeExact(queue);
notEmptyCondition = (Condition) NOT_EMPTY_CONDITION_FIELD_GETTER.invokeExact(queue);
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}

public ReentrantLock getLock() {
return lock;
}

public Condition getNotEmptyCondition() {
return notEmptyCondition;
}
Condition getNotEmptyCondition();

}
Expand Up @@ -27,11 +27,8 @@
import org.jruby.truffle.language.objects.AllocateObjectNode;
import org.jruby.truffle.language.objects.AllocateObjectNodeGen;

import java.lang.invoke.MethodHandle;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

@CoreClass(name = "Queue")
Expand All @@ -49,7 +46,7 @@ public AllocateNode(RubyContext context, SourceSection sourceSection) {

@Specialization
public DynamicObject allocate(DynamicObject rubyClass) {
return allocateNode.allocate(rubyClass, new LinkedBlockingQueueLocksConditions<Object>());
return allocateNode.allocate(rubyClass, getContext().getNativePlatform().createLinkedBlockingQueueLocksConditions());
}

}
Expand Down
Expand Up @@ -25,10 +25,7 @@
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.control.RaiseException;

import java.lang.invoke.MethodHandle;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
Expand Down Expand Up @@ -66,7 +63,7 @@ public DynamicObject initialize(DynamicObject self, int capacity) {
throw new RaiseException(getContext().getCoreLibrary().argumentError("queue size must be positive", this));
}

final ArrayBlockingQueueLocksConditions<Object> blockingQueue = new ArrayBlockingQueueLocksConditions<Object>(capacity);
final ArrayBlockingQueueLocksConditions<Object> blockingQueue = getContext().getNativePlatform().createArrayBlockingQueueLocksConditions(capacity);
Layouts.SIZED_QUEUE.setQueue(self, blockingQueue);
return self;
}
Expand All @@ -89,7 +86,7 @@ public int setMax(DynamicObject self, int newCapacity) {
}

final ArrayBlockingQueueLocksConditions<Object> oldQueue = Layouts.SIZED_QUEUE.getQueue(self);
final ArrayBlockingQueueLocksConditions<Object> newQueue = new ArrayBlockingQueueLocksConditions<Object>(newCapacity);
final ArrayBlockingQueueLocksConditions<Object> newQueue = getContext().getNativePlatform().createArrayBlockingQueueLocksConditions(newCapacity);

// TODO (eregon, 12 July 2015): racy and what to do if the new capacity is lower?
Object element;
Expand Down
Expand Up @@ -10,6 +10,8 @@
package org.jruby.truffle.platform;

import jnr.posix.POSIX;
import org.jruby.truffle.core.queue.ArrayBlockingQueueLocksConditions;
import org.jruby.truffle.core.queue.LinkedBlockingQueueLocksConditions;
import org.jruby.truffle.platform.signal.SignalManager;

public interface NativePlatform {
Expand All @@ -26,4 +28,8 @@ public interface NativePlatform {

RubiniusConfiguration getRubiniusConfiguration();

<T> ArrayBlockingQueueLocksConditions<T> createArrayBlockingQueueLocksConditions(int capacity);

<T> LinkedBlockingQueueLocksConditions<T> createLinkedBlockingQueueLocksConditions();

}
Expand Up @@ -13,8 +13,12 @@
import jnr.posix.POSIX;
import jnr.posix.POSIXFactory;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.queue.ArrayBlockingQueueLocksConditions;
import org.jruby.truffle.core.queue.LinkedBlockingQueueLocksConditions;
import org.jruby.truffle.platform.*;
import org.jruby.truffle.platform.java.JavaClockGetTime;
import org.jruby.truffle.platform.openjdk.OpenJDKArrayBlockingQueueLocksConditions;
import org.jruby.truffle.platform.openjdk.OpenJDKLinkedBlockingQueueLocksConditions;
import org.jruby.truffle.platform.signal.SignalManager;
import org.jruby.truffle.platform.sunmisc.SunMiscSignalManager;

Expand Down Expand Up @@ -68,4 +72,14 @@ public RubiniusConfiguration getRubiniusConfiguration() {
return rubiniusConfiguration;
}

@Override
public <T> ArrayBlockingQueueLocksConditions<T> createArrayBlockingQueueLocksConditions(int capacity) {
return new OpenJDKArrayBlockingQueueLocksConditions<>(capacity);
}

@Override
public <T> LinkedBlockingQueueLocksConditions<T> createLinkedBlockingQueueLocksConditions() {
return new OpenJDKLinkedBlockingQueueLocksConditions<>();
}

}
Expand Up @@ -12,9 +12,13 @@
import jnr.posix.POSIX;
import jnr.posix.POSIXFactory;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.queue.ArrayBlockingQueueLocksConditions;
import org.jruby.truffle.core.queue.LinkedBlockingQueueLocksConditions;
import org.jruby.truffle.platform.*;
import org.jruby.truffle.platform.darwin.DarwinRubiniusConfiguration;
import org.jruby.truffle.platform.linux.LinuxRubiniusConfiguration;
import org.jruby.truffle.platform.openjdk.OpenJDKArrayBlockingQueueLocksConditions;
import org.jruby.truffle.platform.openjdk.OpenJDKLinkedBlockingQueueLocksConditions;
import org.jruby.truffle.platform.signal.SignalManager;
import org.jruby.truffle.platform.sunmisc.SunMiscSignalManager;

Expand Down Expand Up @@ -68,4 +72,14 @@ public RubiniusConfiguration getRubiniusConfiguration() {
return rubiniusConfiguration;
}

@Override
public <T> ArrayBlockingQueueLocksConditions<T> createArrayBlockingQueueLocksConditions(int capacity) {
return new OpenJDKArrayBlockingQueueLocksConditions<>(capacity);
}

@Override
public <T> LinkedBlockingQueueLocksConditions<T> createLinkedBlockingQueueLocksConditions() {
return new OpenJDKLinkedBlockingQueueLocksConditions<>();
}

}
Expand Up @@ -13,8 +13,12 @@
import jnr.posix.POSIX;
import jnr.posix.POSIXFactory;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.queue.ArrayBlockingQueueLocksConditions;
import org.jruby.truffle.core.queue.LinkedBlockingQueueLocksConditions;
import org.jruby.truffle.platform.*;
import org.jruby.truffle.platform.java.JavaProcessName;
import org.jruby.truffle.platform.openjdk.OpenJDKArrayBlockingQueueLocksConditions;
import org.jruby.truffle.platform.openjdk.OpenJDKLinkedBlockingQueueLocksConditions;
import org.jruby.truffle.platform.signal.SignalManager;
import org.jruby.truffle.platform.sunmisc.SunMiscSignalManager;

Expand Down Expand Up @@ -68,4 +72,14 @@ public RubiniusConfiguration getRubiniusConfiguration() {
return rubiniusConfiguration;
}

@Override
public <T> ArrayBlockingQueueLocksConditions<T> createArrayBlockingQueueLocksConditions(int capacity) {
return new OpenJDKArrayBlockingQueueLocksConditions<>(capacity);
}

@Override
public <T> LinkedBlockingQueueLocksConditions<T> createLinkedBlockingQueueLocksConditions() {
return new OpenJDKLinkedBlockingQueueLocksConditions<>();
}

}
Expand Up @@ -7,7 +7,7 @@
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.core.queue;
package org.jruby.truffle.platform.openjdk;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
Expand Down
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.platform.openjdk;

import org.jruby.truffle.core.queue.ArrayBlockingQueueLocksConditions;
import org.jruby.truffle.core.queue.DelegatingBlockingQueue;

import java.lang.invoke.MethodHandle;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class OpenJDKArrayBlockingQueueLocksConditions<T> extends DelegatingBlockingQueue<T> implements ArrayBlockingQueueLocksConditions<T> {

private static final MethodHandle LOCK_FIELD_GETTER = MethodHandleUtils.getPrivateGetter(ArrayBlockingQueue.class, "lock");
private static final MethodHandle NOT_EMPTY_CONDITION_FIELD_GETTER = MethodHandleUtils.getPrivateGetter(ArrayBlockingQueue.class, "notEmpty");
private static final MethodHandle NOT_FULL_CONDITION_FIELD_GETTER = MethodHandleUtils.getPrivateGetter(ArrayBlockingQueue.class, "notFull");

private final ReentrantLock lock;
private final Condition notEmptyCondition;
private final Condition notFullCondition;

public OpenJDKArrayBlockingQueueLocksConditions(int capacity) {
super(new ArrayBlockingQueue<T>(capacity));

final ArrayBlockingQueue<T> queue = (ArrayBlockingQueue<T>) getQueue();

try {
lock = (ReentrantLock) LOCK_FIELD_GETTER.invokeExact(queue);
notEmptyCondition = (Condition) NOT_EMPTY_CONDITION_FIELD_GETTER.invokeExact(queue);
notFullCondition = (Condition) NOT_FULL_CONDITION_FIELD_GETTER.invokeExact(queue);
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}

@Override
public ReentrantLock getLock() {
return lock;
}

@Override
public Condition getNotEmptyCondition() {
return notEmptyCondition;
}

@Override
public Condition getNotFullCondition() {
return notFullCondition;
}

}
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.platform.openjdk;

import org.jruby.truffle.core.queue.DelegatingBlockingQueue;
import org.jruby.truffle.core.queue.LinkedBlockingQueueLocksConditions;

import java.lang.invoke.MethodHandle;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class OpenJDKLinkedBlockingQueueLocksConditions<T> extends DelegatingBlockingQueue<T> implements LinkedBlockingQueueLocksConditions<T> {

private static final MethodHandle TAKE_LOCK_FIELD_GETTER = MethodHandleUtils.getPrivateGetter(LinkedBlockingQueue.class, "takeLock");
private static final MethodHandle NOT_EMPTY_CONDITION_FIELD_GETTER = MethodHandleUtils.getPrivateGetter(LinkedBlockingQueue.class, "notEmpty");

private final ReentrantLock lock;
private final Condition notEmptyCondition;

public OpenJDKLinkedBlockingQueueLocksConditions() {
super(new LinkedBlockingQueue<T>());

final LinkedBlockingQueue<T> queue = (LinkedBlockingQueue<T>) getQueue();

try {
lock = (ReentrantLock) TAKE_LOCK_FIELD_GETTER.invokeExact(queue);
notEmptyCondition = (Condition) NOT_EMPTY_CONDITION_FIELD_GETTER.invokeExact(queue);
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}

@Override
public ReentrantLock getLock() {
return lock;
}

@Override
public Condition getNotEmptyCondition() {
return notEmptyCondition;
}

}

0 comments on commit b435b4f

Please sign in to comment.