1 9 package javolution.context; 10 11 import j2mex.realtime.MemoryArea; 12 import javolution.JavolutionError; 13 import javolution.text.Text; 14 import javolution.text.TextBuilder; 15 16 45 public abstract class RealtimeObject implements Realtime { 46 47 50 private transient RealtimeObject _next; 51 52 56 private transient Factory.Pool _pool; 57 58 61 private transient RealtimeObject _previous; 62 63 66 private transient int _preserved; 67 68 71 protected RealtimeObject() { 72 } 73 74 82 public final boolean isLocal() { 83 if (_pool == null) 84 return false; 85 if (!_pool._inUse) 86 throw new JavolutionError("Reference to inner pool object detected"); 87 if (!_pool._isStack) return false; 89 return (_pool._user == Thread.currentThread()); 90 } 91 92 99 public final String toString() { 100 return (this instanceof TextBuilder) ? ((TextBuilder) this).stringValue() 102 : toText().stringValue(); 103 } 104 105 110 public Text toText() { 111 return Text.valueOf(getClass().getName()).concat(Text.valueOf('@')) 112 .concat(Text.valueOf(System.identityHashCode(this), 16)); 113 } 114 115 128 public finalObject export() { 129 move(ObjectSpace.OUTER); 130 return (Object ) this; 131 } 132 133 139 public finalObject moveHeap() { 140 move(ObjectSpace.HEAP); 141 return (Object ) this; 142 } 143 144 152 public finalObject preserve() { 153 move(ObjectSpace.HOLD); 154 return (Object ) this; 155 } 156 157 166 public finalObject unpreserve() { 167 move(ObjectSpace.STACK); 168 return (Object ) this; 169 } 170 171 public boolean move(ObjectSpace os) { 173 if (_pool == null) 174 return false; if (!_pool._inUse) 176 throw new JavolutionError("Reference to inner pool object detected"); 177 if (os == ObjectSpace.OUTER) { if (!_pool._isStack) 179 return false; if (_pool._user == null) 181 return false; if (_pool._user != Thread.currentThread()) throw new JavolutionError( 184 "Cannot export objects from another thread stack"); 185 LocalPools outerPools = PoolContext.current().getOuter() 186 .getLocalPools(); 187 Factory.Pool outer = (Factory.Pool) outerPools.getPool(_pool 188 .getFactory(), false); 189 detach(); 191 RealtimeObject outerObj = (RealtimeObject) outer.next(); 192 if (outerObj._pool != null) { 193 outerObj.detach(); 194 } 195 outerObj.insertBefore(_pool._activeTail); outerObj._pool = _pool; 197 insertBefore(outer._next); _pool = outer; 199 return true; 200 201 } else if (os == ObjectSpace.HEAP) { if (!_pool._isStack) 203 return false; if ((_pool._user != null) 205 && (_pool._user != Thread.currentThread())) throw new JavolutionError( 207 "Cannot move to the heap objects form another thread stack"); 208 detach(); 209 _pool._size--; _pool = null; 211 _next = null; 212 _previous = null; 213 return true; 214 215 } else if (os == ObjectSpace.HOLD) { if (!_pool._isStack) 217 return false; if ((_pool._user != null) 219 && (_pool._user != Thread.currentThread())) throw new JavolutionError( 221 "Cannot preserve objects from another thread stack"); 222 if (_preserved++ == 0) { 223 detach(); 224 insertBefore(_pool._holdTail); 225 return true; 226 } else { 227 return false; 228 } 229 230 } else if (os == ObjectSpace.STACK) { if ((_preserved != 0) && (--_preserved == 0)) { 232 detach(); 233 insertBefore(_pool._next); 234 _pool._next = this; 235 return true; 236 } else { 237 return false; 238 } 239 240 } else { 242 return true; } 244 } 245 246 251 final void insertBefore(RealtimeObject next) { 252 _previous = next._previous; 253 _next = next; 254 _next._previous = this; 255 _previous._next = this; 256 } 257 258 263 final void detach() { 264 _next._previous = _previous; 265 _previous._next = _next; 266 } 267 268 272 public static abstract class Factoryextends 273 ObjectFactory{ 274 275 278 protected Factory() { 279 } 280 281 public final Object object() { 283 final Pool pool = _lastActivated; 286 return (pool._user == Thread.currentThread()) ? pool.next() 287 : currentPool().next(); 288 } 289 290 public final void recycle(Object obj) { 292 Pool pool = ((RealtimeObject) obj)._pool; 293 if (pool == null) { 294 currentPool().recycle(obj); 295 } else { 296 pool.recycle(obj); 297 } 298 } 299 300 public final ObjectPoolcurrentPool() { 302 final Pool pool = (Pool) _currentPool.get(); 303 return (pool._user != null) ? pool : activatePool(); 304 } 305 306 private final Pool activatePool() { 307 LocalPools pools = Context.current().getLocalPools(); 308 Pool pool = (Pool) pools.getPool(this, true); 309 _currentPool.set(pool); 310 _lastActivated = pool; 311 return pool; 312 } 313 314 private Pool _lastActivated = (Pool) newHeapPool(); 316 protected ObjectPoolnewStackPool() { 318 return new Pool(true); 319 } 320 321 protected ObjectPoolnewHeapPool() { 323 return new Pool(false); 324 } 325 326 330 public final class Pool extends ObjectPool{ 331 332 335 private RealtimeObject _next; 336 337 340 private final boolean _isStack; 341 342 345 private final MemoryArea _memoryArea; 346 347 350 private int _size; 351 352 355 private final RealtimeObject _activeHead; 356 357 360 private final RealtimeObject _activeTail; 361 362 365 private final RealtimeObject _holdHead; 366 367 370 private final RealtimeObject _holdTail; 371 372 377 private Pool(boolean isStack) { 378 _isStack = isStack; 379 _memoryArea = MemoryArea.getMemoryArea(this); 380 381 _activeHead = new Bound(); 382 _activeTail = new Bound(); 383 _activeHead._next = _activeTail; 384 _activeTail._previous = _activeHead; 385 386 _holdHead = new Bound(); 387 _holdTail = new Bound(); 388 _holdHead._next = _holdTail; 389 _holdTail._previous = _holdHead; 390 391 _next = _activeTail; 392 } 393 394 ObjectFactory getFactory() { 395 return Factory.this; 396 } 397 398 public int getSize() { 400 return _size; 401 } 402 403 public void setSize(int size) { 405 for (; _size < size; _size++) { 406 RealtimeObject obj = (RealtimeObject) create(); 407 obj.insertBefore(_next); _next = _next._previous; 409 obj._pool = Pool.this; 410 } 411 } 412 413 public Object next() { 415 final RealtimeObject next = _next; 416 return ((_next = next._next) != null) ? (Object ) next 417 : allocate(); 418 } 419 420 private Object allocate() { 421 _next = _activeTail; if (_isStack) 423 return stackAllocate(); 424 if (_size != 0) 426 removeUse(); return create(); 428 } 429 430 private Object stackAllocate() { 431 _memoryArea.executeInArea(_allocate); 432 return (Object ) _activeTail._previous; 433 } 434 435 private final Runnable _allocate = new Runnable () { 436 public void run() { 437 RealtimeObject obj = (RealtimeObject) create(); 438 _size++; 439 obj.insertBefore(_activeTail); 440 obj._pool = Pool.this; 441 } 442 }; 443 444 private void removeUse() { 446 RealtimeObject rtObj = _activeHead._next; 447 if (rtObj == _activeTail) 448 throw new JavolutionError("Empty pool with non-zero size"); 449 rtObj.detach(); 450 rtObj._next = null; 451 rtObj._previous = null; 452 rtObj._pool = null; 453 _size--; 454 } 455 456 public void recycle(Object obj) { 458 if (doCleanup()) { 459 cleanup(obj); 460 } 461 RealtimeObject rtObj = (RealtimeObject) obj; 462 Pool pool = rtObj._pool; 463 if (pool == this) { 464 rtObj.detach(); 465 rtObj.insertBefore(_next); 466 _next = _next._previous; 467 return; 468 } 469 if (pool == null) { if (MemoryArea.getMemoryArea(rtObj) != _memoryArea) 471 return; rtObj.insertBefore(_next); 473 rtObj._pool = this; 474 _next = _next._previous; 475 _size++; 476 return; 477 } 478 throw new IllegalArgumentException ( 479 "Cannot recycle object belonging to a different context"); 480 } 481 482 protected void recycleAll() { 484 for (RealtimeObject rt = _activeHead._next; rt != _next;) { 486 if (!doCleanup()) 487 break; 488 cleanup((Object ) rt); 489 rt = rt._next; 490 } 491 _next = _activeHead._next; 492 } 493 494 protected void clearAll() { 496 _activeHead._next = _activeTail; 497 _activeTail._previous = _activeHead; 498 _holdHead._next = _holdTail; 499 _holdTail._previous = _holdHead; 500 } 501 502 public String toString() { 504 String str = _isStack ? "Stack Pool for " : "Heap Pool for "; 505 return str + Factory.this.getClass() + " (Size: " + _size + ")"; 506 } 507 508 } 509 510 514 private static final class Bound extends RealtimeObject { 515 } 516 } 517 } | Popular Tags |