/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2012.
*/
package x10.core;
import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicLong;
import x10.rtt.Type;
import x10.serialization.X10JavaDeserializer;
import x10.serialization.X10JavaSerializable;
import x10.serialization.X10JavaSerializer;
/**
* Implementation of PlaceLocalHandle service for Java-based runtime.
*/
public final class PlaceLocalHandle<T> implements java.io.Serializable, X10JavaSerializable {
private static final long serialVersionUID = 1L;
private static final HashMap<java.lang.Long,Object> data = new HashMap<java.lang.Long,Object>();
private static final int placeShift = 48;
private static final AtomicLong lastId = new AtomicLong(0L);
transient private boolean initialized = false;
transient private Object myData = null;
private java.lang.Long id;
// TODO: The X10 code currently ensures that PlaceLocalHandle's are only
// created at Place 0 by doing an at. We've contemplated moving to
// more of a SVD style implementation where each place would be able to
// create place local handles by either encoding the place in the id like we
// did here or by having the places get ids in "chunks" from the master id server
// at place 0.
// Since we are thinking about making this change, I went ahead and did a poor-man's
// version of it here instead of asserting nextId is only called at place 0
// (which would have been true currently).
private static long nextId() {
long here = Thread.currentThread().home().id;
long newId = lastId.incrementAndGet();
assert newId < (1L << placeShift);
newId |= (here << placeShift);
return newId;
}
private Object readResolve() {
initialized = false;
return this;
}
// constructor just for allocation
public PlaceLocalHandle(java.lang.System[] $dummy, Type<T> T) {
}
public final PlaceLocalHandle x10$core$PlaceLocalHandle$$init$S() {
id = nextId();
return this;
}
// not used
// public PlaceLocalHandle(Type<T> T) {
// id = nextId();
// }
// zero value constructor
public PlaceLocalHandle(Type<T> T, java.lang.System $dummy) {
id = nextId();
}
public T $apply$G() {
if (!initialized) {
synchronized(data) {
myData = data.get(id);
initialized = true;
}
}
return (T) myData;
}
public void set__0x10$lang$PlaceLocalHandle$$T(T value) {
synchronized(data) {
Object old = data.put(id, value);
assert old == null : "Set called on already initialized local object";
}
}
@Override
public String toString() {
return "PlaceLocalHandle(" + this.id + ")";
}
public void $_serialize(X10JavaSerializer $serializer) throws IOException {
$serializer.write((long) id);
}
public static X10JavaSerializable $_deserialize_body(PlaceLocalHandle $_obj, X10JavaDeserializer $deserializer) throws IOException {
$_obj.id = (java.lang.Long) $deserializer.readLong();
return $_obj;
}
public static X10JavaSerializable $_deserializer(X10JavaDeserializer $deserializer) throws IOException {
PlaceLocalHandle $_obj = new PlaceLocalHandle((java.lang.System[]) null, (Type<?>) null);
$deserializer.record_reference($_obj);
return $_deserialize_body($_obj, $deserializer);
}
}