runtime/realm/mem_impl.cc
// release storage associated with an instance
release storage associated with an instance
release storage associated with an instance
void MemoryImpl::release_instance_storage(RegionInstanceImpl *inst,
					      Event precondition)
    {
      NodeID target = ID(me).memory_owner_node();
      if(target != Network::my_node_id) {
	ActiveMessage<MemStorageReleaseRequest> amsg(target);
	amsg->memory = me;
	amsg->inst = inst->me;
	amsg->precondition = precondition;
	amsg.commit();
	return;
      }
      bool poisoned = false;
      bool triggered = precondition.has_triggered_faultaware(poisoned);
      if(triggered && poisoned)
	return;
      do { 
	AutoLock<> al(allocator_mutex);
	if(inst->metadata.inst_offset == RegionInstanceImpl::INSTOFFSET_DELAYEDALLOC) {
	  assert(!triggered);
	  inst->metadata.inst_offset = RegionInstanceImpl::INSTOFFSET_DELAYEDDESTROY;
	  break;
	}
	if(pending_allocs.empty()) {
	  if(triggered) {
	    if(inst->metadata.inst_offset != RegionInstanceImpl::INSTOFFSET_FAILED)
	      current_allocator.deallocate(inst->me);
	  } else {
	    pending_releases.push_back(PendingRelease(inst,
						      false ,
						      ++cur_release_seqid));
	  }
	} else {
	  if(triggered) {
	    if(inst->metadata.inst_offset == RegionInstanceImpl::INSTOFFSET_FAILED) {
	    } else {
	      release_allocator.deallocate(inst->me);
	      future_allocator.deallocate(inst->me);
	      pending_releases.push_back(PendingRelease(inst,
							true ,
							++cur_release_seqid));
	    }
	  } else {
	    if(inst->metadata.inst_offset != RegionInstanceImpl::INSTOFFSET_FAILED)
	      future_allocator.deallocate(inst->me, true );
	    pending_releases.push_back(PendingRelease(inst,
						      false ,
						      ++cur_release_seqid));
	  }
	}
      } while(0);
      if(triggered) {
	NodeID creator_node = ID(inst->me).instance_creator_node();
	if(creator_node == Network::my_node_id) {
	  inst->notify_deallocation();
	} else {
	  ActiveMessage<MemStorageReleaseResponse> amsg(creator_node);
	  amsg->inst = inst->me;
	  amsg.commit();
	}
      } else {
	inst->deferred_destroy.defer(inst, this, precondition);
      }
    }
void MemoryImpl :: release_instance_storage ( RegionInstanceImpl * inst , Event precondition ) { NodeID target = ID ( me ) . memory_owner_node ( ) ; if ( target != Network :: my_node_id ) { ActiveMessage < MemStorageReleaseRequest > amsg ( target ) ; amsg -> memory = me ; amsg -> inst = inst -> me ; amsg -> precondition = precondition ; amsg . commit ( ) ; return ; } bool poisoned = false ; bool triggered = precondition . has_triggered_faultaware ( poisoned ) ; if ( triggered && poisoned ) return ; do { AutoLock < > al ( allocator_mutex ) ; if ( inst -> metadata . inst_offset == RegionInstanceImpl :: INSTOFFSET_DELAYEDALLOC ) { assert ( ! triggered ) ; inst -> metadata . inst_offset = RegionInstanceImpl :: INSTOFFSET_DELAYEDDESTROY ; break ; } if ( pending_allocs . empty ( ) ) { if ( triggered ) { if ( inst -> metadata . inst_offset != RegionInstanceImpl :: INSTOFFSET_FAILED ) current_allocator . deallocate ( inst -> me ) ; } else { pending_releases . push_back ( PendingRelease ( inst , false , ++ cur_release_seqid ) ) ; } } else { if ( triggered ) { if ( inst -> metadata . inst_offset == RegionInstanceImpl :: INSTOFFSET_FAILED ) { } else { release_allocator . deallocate ( inst -> me ) ; future_allocator . deallocate ( inst -> me ) ; pending_releases . push_back ( PendingRelease ( inst , true , ++ cur_release_seqid ) ) ; } } else { if ( inst -> metadata . inst_offset != RegionInstanceImpl :: INSTOFFSET_FAILED ) future_allocator . deallocate ( inst -> me , true ) ; pending_releases . push_back ( PendingRelease ( inst , false , ++ cur_release_seqid ) ) ; } } } while ( 0 ) ; if ( triggered ) { NodeID creator_node = ID ( inst -> me ) . instance_creator_node ( ) ; if ( creator_node == Network :: my_node_id ) { inst -> notify_deallocation ( ) ; } else { ActiveMessage < MemStorageReleaseResponse > amsg ( creator_node ) ; amsg -> inst = inst -> me ; amsg . commit ( ) ; } } else { inst -> deferred_destroy . defer ( inst , this , precondition ) ; } }
release storage associated with an instance
release storage associated with an instance
// all allocation requests are handled by the memory's owning node for //  now - local caching might be possible though // a poisoned precondition silently cancels the deletion - up to //  requestor to realize this has occurred since the deletion does //  not have its own completion event // so we can 'break' out early below // special case: we can get a (deferred only!) destruction of an //  instance whose creation precondition hasn't even been satisfied - //  it won't be represented in the heap state, so we can't do a //  "future release of it" - wait until the creation precondition is //  satisfied // we can apply the destruction directly to current state // push the op, but we're not maintaining a future state yet /*!triggered*/ // even if this destruction is ready, we can't update current //  state because older pending ops exist // TODO: pushing past a single pending alloc should always be safe // (exception: a ready destruction of a failed allocation need not //  be deferred) // event is known to have triggered, so these must not fail /*triggered*/ // TODO: is it safe to test for failedness yet? /*missing ok*/ /*!triggered*/ // even if we don't apply the destruction to the heap state right away, //  we always ack a triggered destruction // issue notifications // local notification of result // remote notification // ask the instance to tell us when the precondition is satisified