Merge pull request #189 from jentfoo/interface_improvements

interface improvements and LockSupport implementation
This commit is contained in:
Joshua Warner 2014-03-07 20:48:40 -07:00
commit 492294bfe6
9 changed files with 451 additions and 9 deletions

View File

@ -14,6 +14,9 @@ import java.util.Map;
import java.util.WeakHashMap; import java.util.WeakHashMap;
public class Thread implements Runnable { public class Thread implements Runnable {
// set and accessed from within LockSupport
protected volatile Object parkBlocker;
private long peer; private long peer;
private volatile boolean interrupted; private volatile boolean interrupted;
private volatile boolean unparked; private volatile boolean unparked;

View File

@ -0,0 +1,31 @@
/* Copyright (c) 2008-2014, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.util;
public interface Deque<T> extends Queue<T> {
public boolean offerFirst(T e);
public void push(T e);
public void addFirst(T element);
public boolean offerLast(T e);
public void addLast(T element);
public T peekFirst();
public T getFirst();
public T peekLast();
public T getLast();
public T pollFirst();
public T removeFirst();
public T pop();
public T pollLast();
public T removeLast();
public Iterator<T> descendingIterator();
public boolean removeLastOccurrence(Object o);
public boolean removeFirstOccurrence(Object o);
}

View File

@ -10,7 +10,7 @@
package java.util; package java.util;
public class LinkedList<T> extends AbstractSequentialList<T> { public class LinkedList<T> extends AbstractSequentialList<T> implements Deque<T> {
private Cell<T> front; private Cell<T> front;
private Cell<T> rear; private Cell<T> rear;
private int size; private int size;
@ -85,14 +85,17 @@ public class LinkedList<T> extends AbstractSequentialList<T> {
} }
} }
@Override
public int size() { public int size() {
return size; return size;
} }
@Override
public boolean contains(Object element) { public boolean contains(Object element) {
return find(element) != null; return find(element) != null;
} }
@Override
public int indexOf(Object element) { public int indexOf(Object element) {
int i = 0; int i = 0;
for (Cell<T> c = front; c != null; c = c.next) { for (Cell<T> c = front; c != null; c = c.next) {
@ -104,6 +107,7 @@ public class LinkedList<T> extends AbstractSequentialList<T> {
return -1; return -1;
} }
@Override
public int lastIndexOf(Object element) { public int lastIndexOf(Object element) {
int i = size; int i = size;
for (Cell<T> c = rear; c != null; c = c.prev) { for (Cell<T> c = rear; c != null; c = c.prev) {
@ -115,16 +119,24 @@ public class LinkedList<T> extends AbstractSequentialList<T> {
return -1; return -1;
} }
@Override
public boolean offer(T element) {
return add(element);
}
@Override
public boolean add(T element) { public boolean add(T element) {
addLast(element); addLast(element);
return true; return true;
} }
@Override
public boolean addAll(Collection<? extends T> collection) { public boolean addAll(Collection<? extends T> collection) {
for (T t: collection) add(t); for (T t: collection) add(t);
return true; return true;
} }
@Override
public void add(int index, T element) { public void add(int index, T element) {
if (index == 0) { if (index == 0) {
addFirst(element); addFirst(element);
@ -135,10 +147,31 @@ public class LinkedList<T> extends AbstractSequentialList<T> {
} }
} }
@Override
public boolean offerFirst(T e) {
addFirst(e);
return true;
}
@Override
public void push(T e) {
addFirst(e);
}
@Override
public void addFirst(T element) { public void addFirst(T element) {
addFirst(new Cell(element, null, null)); addFirst(new Cell(element, null, null));
} }
@Override
public boolean offerLast(T e) {
addLast(e);
return true;
}
@Override
public void addLast(T element) { public void addLast(T element) {
addLast(new Cell(element, null, null)); addLast(new Cell(element, null, null));
} }
@ -147,6 +180,7 @@ public class LinkedList<T> extends AbstractSequentialList<T> {
return find(index).value; return find(index).value;
} }
@Override
public T set(int index, T value) { public T set(int index, T value) {
Cell<T> c = find(index); Cell<T> c = find(index);
T old = c.value; T old = c.value;
@ -154,6 +188,21 @@ public class LinkedList<T> extends AbstractSequentialList<T> {
return old; return old;
} }
@Override
public T peek() {
return peekFirst();
}
@Override
public T peekFirst() {
if (front != null) {
return front.value;
} else {
return null;
}
}
@Override
public T getFirst() { public T getFirst() {
if (front != null) { if (front != null) {
return front.value; return front.value;
@ -161,7 +210,17 @@ public class LinkedList<T> extends AbstractSequentialList<T> {
throw new NoSuchElementException(); throw new NoSuchElementException();
} }
} }
@Override
public T peekLast() {
if (rear != null) {
return rear.value;
} else {
return null;
}
}
@Override
public T getLast() { public T getLast() {
if (rear != null) { if (rear != null) {
return rear.value; return rear.value;
@ -170,27 +229,57 @@ public class LinkedList<T> extends AbstractSequentialList<T> {
} }
} }
@Override
public T remove(int index) { public T remove(int index) {
Cell<T> c = find(index); Cell<T> c = find(index);
remove(c); remove(c);
return c.value; return c.value;
} }
@Override
public boolean isEmpty() { public boolean isEmpty() {
return size() == 0; return size() == 0;
} }
public T removeFirst() { @Override
public T poll() {
return pollFirst();
}
@Override
public T pollFirst() {
if (front != null) { if (front != null) {
T v = front.value; T v = front.value;
remove(front); remove(front);
return v; return v;
} else { } else {
throw new NoSuchElementException(); return null;
} }
} }
public T removeLast() { @Override
public T removeFirst() {
T result = pollFirst();
if (result == null) {
throw new NoSuchElementException();
} else {
return result;
}
}
@Override
public T pop() {
return removeFirst();
}
@Override
public T remove() {
return removeFirst();
}
@Override
public T pollLast() {
if (rear != null) { if (rear != null) {
T v = rear.value; T v = rear.value;
remove(rear); remove(rear);
@ -200,6 +289,18 @@ public class LinkedList<T> extends AbstractSequentialList<T> {
} }
} }
@Override
public T removeLast() {
T result = pollLast();
if (result == null) {
throw new NoSuchElementException();
} else {
return result;
}
}
@Override
public boolean remove(Object element) { public boolean remove(Object element) {
Cell<T> c = find(element); Cell<T> c = find(element);
if (c == null) { if (c == null) {
@ -210,15 +311,23 @@ public class LinkedList<T> extends AbstractSequentialList<T> {
} }
} }
@Override
public void clear() { public void clear() {
front = rear = null; front = rear = null;
size = 0; size = 0;
} }
@Override
public Iterator<T> iterator() { public Iterator<T> iterator() {
return listIterator(); return listIterator();
} }
@Override
public ListIterator<T> listIterator() {
return listIterator(0);
}
@Override
public ListIterator<T> listIterator(int index) { public ListIterator<T> listIterator(int index) {
MyIterator it = new MyIterator(); MyIterator it = new MyIterator();
for (int i = 0; i < index; ++i) { for (int i = 0; i < index; ++i) {
@ -227,14 +336,67 @@ public class LinkedList<T> extends AbstractSequentialList<T> {
return it; return it;
} }
public ListIterator<T> listIterator() { @Override
return listIterator(0); public Iterator<T> descendingIterator() {
final ListIterator<T> li = listIterator(size());
return new Iterator<T>() {
@Override
public T next() {
return li.previous();
}
@Override
public boolean hasNext() {
return li.hasPrevious();
}
@Override
public void remove() {
li.remove();
}
};
} }
@Override
public String toString() { public String toString() {
return Collections.toString(this); return Collections.toString(this);
} }
@Override
public T element() {
T result = peek();
if (result == null) {
throw new NoSuchElementException();
} else {
return result;
}
}
@Override
public boolean removeFirstOccurrence(Object o) {
int index = indexOf(o);
if (index > 0) {
remove(index);
return true;
} else {
return false;
}
}
@Override
public boolean removeLastOccurrence(Object o) {
int lastIndex = lastIndexOf(o);
if (lastIndex > 0) {
remove(lastIndex);
return true;
} else {
return false;
}
}
private static class Cell<T> { private static class Cell<T> {
public T value; public T value;
public Cell<T> prev; public Cell<T> prev;

View File

@ -1,8 +1,13 @@
package java.util.concurrent; package java.util.concurrent;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Queue;
import avian.Atomic; import avian.Atomic;
public class ConcurrentLinkedQueue<T> { public class ConcurrentLinkedQueue<T> implements Queue<T> {
private static final long QueueHead; private static final long QueueHead;
private static final long QueueTail; private static final long QueueTail;
private static final long NodeNext; private static final long NodeNext;
@ -25,11 +30,20 @@ public class ConcurrentLinkedQueue<T> {
private volatile Node<T> head = new Node<T>(null, null); private volatile Node<T> head = new Node<T>(null, null);
private volatile Node<T> tail = head; private volatile Node<T> tail = head;
@Override
public void clear() { public void clear() {
// todo: can we safely make this O(1)? // TODO - can we safely make this O(1)?
while (poll() != null) { } while (poll() != null) { }
} }
@Override
public boolean offer(T element) {
add(element);
return true;
}
@Override
public boolean add(T value) { public boolean add(T value) {
Node<T> n = new Node<T>(value, null); Node<T> n = new Node<T>(value, null);
while (true) { while (true) {
@ -48,14 +62,36 @@ public class ConcurrentLinkedQueue<T> {
return true; return true;
} }
@Override
public T peek() { public T peek() {
return poll(false); return poll(false);
} }
@Override
public T element() {
T result = peek();
if (result == null) {
throw new NoSuchElementException();
} else {
return result;
}
}
@Override
public T poll() { public T poll() {
return poll(true); return poll(true);
} }
@Override
public T remove() {
T result = poll();
if (result == null) {
throw new NoSuchElementException();
} else {
return result;
}
}
private T poll(boolean remove) { private T poll(boolean remove) {
while (true) { while (true) {
Node<T> h = head; Node<T> h = head;
@ -90,4 +126,63 @@ public class ConcurrentLinkedQueue<T> {
this.next = next; this.next = next;
} }
} }
@Override
public int size() {
// TODO - implement
throw new UnsupportedOperationException();
}
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public boolean contains(Object element) {
// TODO - implement
throw new UnsupportedOperationException();
}
@Override
public boolean containsAll(Collection<?> c) {
// TODO - implement
throw new UnsupportedOperationException();
}
@Override
public boolean addAll(Collection<? extends T> collection) {
// TODO - implement
throw new UnsupportedOperationException();
}
@Override
public boolean remove(Object element) {
// TODO - implement
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(Collection<?> c) {
// TODO - implement
throw new UnsupportedOperationException();
}
@Override
public Object[] toArray() {
// TODO - implement
throw new UnsupportedOperationException();
}
@Override
public <S> S[] toArray(S[] array) {
// TODO - implement
throw new UnsupportedOperationException();
}
@Override
public Iterator<T> iterator() {
// TODO - implement
throw new UnsupportedOperationException();
}
} }

View File

@ -0,0 +1,24 @@
/* Copyright (c) 2008-2014, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.util.concurrent.locks;
import java.util.Date;
import java.util.concurrent.TimeUnit;
public interface Condition {
public void await();
public boolean await(long time, TimeUnit unit);
public long awaitNanos(long nanosTimeout);
public void awaitUninterruptibly();
public boolean awaitUntil(Date deadline);
public void signal();
public void signalAll();
}

View File

@ -0,0 +1,22 @@
/* Copyright (c) 2008-2014, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.util.concurrent.locks;
import java.util.concurrent.TimeUnit;
public interface Lock {
public void lock();
public void lockInterruptibly() throws InterruptedException;
public Condition newCondition();
public boolean tryLock();
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
public void unlock();
}

View File

@ -0,0 +1,89 @@
/* Copyright (c) 2008-2014, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.util.concurrent.locks;
import sun.misc.Unsafe;
public class LockSupport {
private LockSupport() {
// can't construct
}
private static final Unsafe unsafe;
private static final long parkBlockerOffset;
static {
unsafe = Unsafe.getUnsafe();
try {
parkBlockerOffset = unsafe.objectFieldOffset(java.lang.Thread.class.getDeclaredField("parkBlocker"));
} catch (Exception ex) {
throw new Error(ex);
}
}
private static void setBlocker(Thread t, Object arg) {
unsafe.putObject(t, parkBlockerOffset, arg);
}
public static void unpark(Thread thread) {
if (thread != null) {
unsafe.unpark(thread);
}
}
public static void park(Object blocker) {
doParkNanos(blocker, 0L);
}
public static void parkNanos(Object blocker, long nanos) {
if (nanos <= 0) {
return;
}
doParkNanos(blocker, nanos);
}
private static void doParkNanos(Object blocker, long nanos) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
unsafe.park(false, nanos);
setBlocker(t, null);
}
public static void parkUntil(Object blocker, long deadline) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
unsafe.park(true, deadline);
setBlocker(t, null);
}
public static Object getBlocker(Thread t) {
if (t == null) {
throw new NullPointerException();
}
return unsafe.getObjectVolatile(t, parkBlockerOffset);
}
public static void park() {
unsafe.park(false, 0L);
}
public static void parkNanos(long nanos) {
if (nanos > 0) {
unsafe.park(false, nanos);
}
}
public static void parkUntil(long deadline) {
unsafe.park(true, deadline);
}
}

View File

@ -0,0 +1,16 @@
/* Copyright (c) 2008-2014, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.util.concurrent.locks;
public interface ReadWriteLock {
public Lock readLock();
public Lock writeLock();
}

View File

@ -52,7 +52,7 @@ class MyClasspath : public Classpath {
const unsigned NormalPriority = 5; const unsigned NormalPriority = 5;
return vm::makeThread return vm::makeThread
(t, 0, 0, 0, 0, NewState, NormalPriority, 0, 0, 0, (t, 0, 0, 0, 0, 0, NewState, NormalPriority, 0, 0, 0,
root(t, Machine::AppLoader), 0, 0, group, 0); root(t, Machine::AppLoader), 0, 0, group, 0);
} }