// remove cycles
void cleanUpGroupingRec(UINT address, ParentRefMap& parentMap, ChildRefMap& childMap, MapAddressToAllocation& addressesToAllocations, AddressSet& visited)
{
   if (visited.find(address) != visited.end()) return;

   visited.insert(address);

   auto myUid = addressesToAllocations[address].uid;
   auto parents = parentMap[address]; // copy
   for (auto parent : parents)
   {
      auto parentUid = addressesToAllocations[parent].uid;
      
      bool eraseParent = 
         (parentUid > myUid) || 
         (address == parent); // remove self references
      
      if (eraseParent)
      {
         parentMap[address].erase(parent);
         childMap[parent].erase(address);
      }
      else
      {
         cleanUpGroupingRec(parent, parentMap, childMap, addressesToAllocations, visited);
      }
   }
}
void checkMemoryGrouping(const MemoryTracker::TrackedAllocation& ta, AddressSet& addresses, ParentRefMap& parentMap, ChildRefMap& childMap)
{
   //UINT * memory = (UINT*)address, *endMemory = (UINT*)(address+size);	//use memory hacks to see if there's pointers to the allocations in here

   UINT * buf = new UINT[ta.bytes];
   ZeroMemory(buf, ta.bytes);

   SIZE_T numberOfBytesRead = 0;

   if (ReadProcessMemory(global::hProcess, ta.mem, buf, ta.bytes, &numberOfBytesRead))
   {
      UINT * memory = buf;
      UINT * endMemory = buf + (ta.bytes / sizeof(UINT)); // min( (ta.bytes / sizeof(UINT)), (numberOfBytesRead / sizeof(UINT)) );
      for (; memory < endMemory; memory++)
      {
         auto it = addresses.find(*memory);
         if (it != addresses.end())
         {
            parentMap[*it].insert((UINT)ta.mem);
            childMap[(UINT)ta.mem].insert(*it);
         }
      }
   }

   delete[] buf;
}
AddressSet
AddressDb::list() const
{
    std::lock_guard<std::mutex> lock(mutex_);

    AddressSet out;
    for (const auto &i: addresses_)
        out.insert(i.first);

    return out;
}
void printSingleAggregateGrouping(std::ostream& out, int level, UINT address, TrackedCallstack::ptr callstackPtr, ReferenceCount& rc, MapAddressToAllocation& addressToAllocationMap, ChildRefMap& childMap, AddressSet visited, UINT sumResponsible)
{
   if (visited.find(address) != visited.end()) return;
   visited.insert(address);
   auto& alloc = addressToAllocationMap[address];
   auto p = callstackPtr;

   indent(out, level) << "Allocations " << dec << rc.totalSize << " total bytes for " << rc.instances << " instances; Responsible for " << sumResponsible << " nested bytes. Callstack:" << endl;
   for (auto s: p->callstackVerbose)
   {
      indent(out, level) << "|" << s << endl;
   }
   printAggregateGroupings(out, level + 1, childMap[address], addressToAllocationMap, childMap, visited);
}
UINT findResponsibleBytes(UINT address, MapAddressToAllocation& addressToAllocationMap, ChildRefMap& childMap, AddressSet& visitedInThisSearch)
{
   if (visitedInThisSearch.find(address) != visitedInThisSearch.end()) return 0;
   visitedInThisSearch.insert(address);
   UINT sum = 0;

   sum += addressToAllocationMap[address].bytes;

   for (UINT c: childMap[address])
   {
      sum += findResponsibleBytes(c, addressToAllocationMap, childMap, visitedInThisSearch);
   }
   return sum;
}
void MemoryTracker::ReportGroupLeaks(std::ostream& out, bool intensive, bool aggregate)
{
   AddressSet allAddresses;
   MapAddressToAllocation addressesToAllocations;
   for (auto& a: trackedAllocations)	//get all addresses
   {
      allAddresses.insert((UINT)a.mem);
      addressesToAllocations[(UINT)a.mem] = a;
   }

   //Find the groupings.
   ParentRefMap parentMap;
   ChildRefMap childMap;
   for (auto& a: trackedAllocations)
   {
      checkMemoryGrouping(a, allAddresses, parentMap, childMap);
   }

   //// clean up cycles
   //for (auto& a: trackedAllocations)
   //   cleanUpGroupingRec((UINT)a.mem, parentMap, childMap, addressesToAllocations, AddressSet());
   cleanUpAllGroupings(trackedAllocations, parentMap, childMap, addressesToAllocations);

   //find all the root addresses - recursive
   AddressSet rootAddresses;
   {
      AddressSet visited;
      for (auto& a: trackedAllocations)
      {
         walkUpGrouping((UINT)a.mem, parentMap, rootAddresses, visited);
      }
   }

   AddressSet visited;
   if (aggregate)
   {
      printAggregateGroupings(out, 0, rootAddresses, addressesToAllocations, childMap, visited);
   }
   else
   {
      for (UINT a: rootAddresses)
      {
         printGroupings(out, 0, a, addressesToAllocations, childMap, visited);
      }
   }
}
void printGroupings(std::ostream& out, int level, UINT address, MapAddressToAllocation& addressToAllocationMap, ChildRefMap& childMap, AddressSet& visited)
{
   if (visited.find(address) != visited.end()) return;
   visited.insert(address);
   auto& alloc = addressToAllocationMap[address];
   auto p = alloc.callStack;

   indent(out, level) << "Allocation at " << hex << address << " " << dec << alloc.bytes << " bytes; Callstack:" << endl;
   for (auto s: p->callstackVerbose)
   {
      indent(out, level) << s << endl;
   }

   for (auto a: childMap[address])
   {
      printGroupings(out, level + 1, a, addressToAllocationMap, childMap, visited);
   }
}
//recursive
void walkUpGrouping(UINT address, ParentRefMap& parentMap, AddressSet& outAddresses, AddressSet& visited)
{
   visited.insert(address);
   if (parentMap[address].size() == 0)	//base case
   {
      outAddresses.insert(address);
   }
   else
   {
      for (UINT a: parentMap[address])
      {
         if (visited.find(a) == visited.end())
         {
            walkUpGrouping(a, parentMap, outAddresses, visited);
         }
      }
   }
}
void SubnetTopology::getRemovedDevices(AddressSet& addressSet)
{
    markReachableNodes(MANAGER_ADDRESS, setNextSearchId());

    for (NodeMap::iterator itNode = nodes.begin(); itNode != nodes.end(); ++itNode) {
        if (itNode->second.getSearchId() != searchId) {
            addressSet.insert(itNode->first);
        }
    }
}
static ir::PTXU64 extent(const executive::ExecutableKernel& kernel) {
	typedef std::unordered_set<ir::PTXU64> AddressSet;
	report("Computing extent for kernel " << kernel.name);
	AddressSet encountered;
	AddressSet pointers;

	ir::PTXU64 extent = kernel.constMemorySize() + kernel.parameterMemorySize() 
		+ kernel.totalSharedMemorySize() + kernel.localMemorySize();
	
	executive::ExecutableKernel::TextureVector textures = kernel.textureReferences();
	
	for (executive::ExecutableKernel::TextureVector::iterator 
		texture = textures.begin(); texture != textures.end(); ++texture) {
		report(" Checking texture mapped address " << (*texture)->data);
		pointers.insert((ir::PTXU64)(*texture)->data);
	}
#if 0
	for (ir::Kernel::ParameterVector::const_iterator 
		parameter = kernel.parameters.begin();
		parameter != kernel.parameters.end(); ++parameter) {
		ir::PTXU64 address = 0;
		
		for (ir::Parameter::ValueVector::const_iterator 
			element = parameter->arrayValues.begin();
			element != parameter->arrayValues.end(); ++element) {
			switch (parameter->type) {
				case ir::PTXOperand::b8:
				case ir::PTXOperand::s8:
				case ir::PTXOperand::u8:
				{
					address <<= 8;
					address |= element->val_u8;
					break;
				}
				case ir::PTXOperand::b16:
				case ir::PTXOperand::s16:
				case ir::PTXOperand::u16:
				{
					address <<= 16;
					address |= element->val_u16;
					break;
				}
				case ir::PTXOperand::b32:
				case ir::PTXOperand::s32:
				case ir::PTXOperand::u32:
				{
					address <<= 32;
					address |= element->val_u32;
					break;
				}
				case ir::PTXOperand::b64:
				case ir::PTXOperand::s64:
				case ir::PTXOperand::u64:
				{
					address = element->val_u64;
					break;
				}
				default: break;
			}
			
			report(" Checking address " << (void*)address);
			pointers.insert(address);
		}
	}
#endif
	
	for(AddressSet::iterator pointer = pointers.begin(); 
		pointer != pointers.end(); ++pointer)
	{
		executive::Device::MemoryAllocation* 
			allocation = kernel.device->getMemoryAllocation((void*)*pointer);
		if(allocation != 0)
		{
			if(encountered.insert((ir::PTXU64)allocation->pointer()).second)
			{
				extent += allocation->size();
			}
		}
	}
	
	return extent;
	
}
Example #11
0
static Status
bridgeDoSweep(Wallet &wallet, PendingSweep &sweep,
              tABC_BitCoin_Event_Callback fAsyncCallback, void *pData)
{
    // Find utxos for this address:
    AddressSet addresses;
    addresses.insert(sweep.address);
    auto utxos = wallet.txCache.get_utxos(addresses);

    // Bail out if there are no funds to sweep:
    if (!utxos.size())
    {
        // Tell the GUI if there were funds in the past:
        if (wallet.txCache.has_history(sweep.address))
        {
            ABC_DebugLog("IncomingSweep callback: wallet %s, value: 0",
                         wallet.id().c_str());
            tABC_AsyncBitCoinInfo info;
            info.pData = pData;
            info.eventType = ABC_AsyncEventType_IncomingSweep;
            Status().toError(info.status, ABC_HERE());
            info.szWalletUUID = wallet.id().c_str();
            info.szTxID = nullptr;
            info.sweepSatoshi = 0;
            fAsyncCallback(&info);

            sweep.done = true;
        }
        return Status();
    }

    // Build a transaction:
    bc::transaction_type tx;
    tx.version = 1;
    tx.locktime = 0;

    // Set up the output:
    Address address;
    wallet.addresses.getNew(address);
    bc::transaction_output_type output;
    ABC_CHECK(outputScriptForAddress(output.script, address.address));
    tx.outputs.push_back(output);

    // Set up the inputs:
    uint64_t fee, funds;
    ABC_CHECK(inputsPickMaximum(fee, funds, tx, utxos));
    if (outputIsDust(funds))
        return ABC_ERROR(ABC_CC_InsufficientFunds, "Not enough funds");
    tx.outputs[0].value = funds;

    // Now sign that:
    KeyTable keys;
    keys[sweep.address] = sweep.key;
    ABC_CHECK(signTx(tx, wallet.txCache, keys));

    // Send:
    bc::data_chunk raw_tx(satoshi_raw_size(tx));
    bc::satoshi_save(tx, raw_tx.begin());
    ABC_CHECK(broadcastTx(wallet, raw_tx));

    // Calculate transaction information:
    const auto info = wallet.txCache.txInfo(tx, wallet.addresses.list());

    // Save the transaction metadata:
    Tx meta;
    meta.ntxid = info.ntxid;
    meta.txid = info.txid;
    meta.timeCreation = time(nullptr);
    meta.internal = true;
    meta.metadata.amountSatoshi = funds;
    meta.metadata.amountFeesAirbitzSatoshi = 0;
    ABC_CHECK(gContext->exchangeCache.satoshiToCurrency(
                  meta.metadata.amountCurrency, info.balance,
                  static_cast<Currency>(wallet.currency())));
    ABC_CHECK(wallet.txs.save(meta));

    // Update the transaction cache:
    if (wallet.txCache.insert(tx))
        watcherSave(wallet).log(); // Failure is not fatal
    wallet.balanceDirty();
    ABC_CHECK(wallet.addresses.markOutputs(info.ios));

    // Done:
    ABC_DebugLog("IncomingSweep callback: wallet %s, txid: %s, value: %d",
                 wallet.id().c_str(), info.txid.c_str(), output.value);
    tABC_AsyncBitCoinInfo async;
    async.pData = pData;
    async.eventType = ABC_AsyncEventType_IncomingSweep;
    Status().toError(async.status, ABC_HERE());
    async.szWalletUUID = wallet.id().c_str();
    async.szTxID = info.txid.c_str();
    async.sweepSatoshi = output.value;
    fAsyncCallback(&async);

    sweep.done = true;

    return Status();
}
bool SubnetTopology::releaseRemoved(EngineOperations& engineOperations, AddressSet& addressSet) {
    bool isGood = false;
    bool repeat = false;

    SubnetTdma& subnetTdma = NetworkEngine::instance().getSubnetTdma();
    SubnetServices& subnetServices = NetworkEngine::instance().getSubnetServices();
    DevicesTable& devicesTable = NetworkEngine::instance().getDevicesTable();

    markReachableNodes(MANAGER_ADDRESS, setNextSearchId());

    // steps through every node and see if the node has been touched (node.searchId has the value of
    // the current searchId)
    std::set<Uint16> affectedGraphs;
    for (NodeMap::iterator itNode = nodes.begin(); itNode != nodes.end(); ++itNode) {
        if (itNode->second.getSearchId() != searchId || itNode->second.getStatus() == Status::CANDIDATE_FOR_REMOVAL ) {
            LOG_INFO("Delete Node: " << ToStr(itNode->second.getNodeAddress()));

            affectedGraphs.insert( itNode->second.getOutboundGraphId() );
            affectedGraphs.insert( itNode->second.getInboundGraphId() );

            itNode->second.setStatus(Status::REMOVED);
            {
                Device& device = devicesTable.getDevice(itNode->first);
                if (device.capabilities.isGateway()) {
                    device.deviceRequested832 = true;
                } else {
                    device.deviceRequested832 = false;
                }

                // notify GW about the device has been removed (if the GW is not deleted also)
                if (devicesTable.existsDevice(GATEWAY_ADDRESS)) {
                    IEngineOperationPointer operation(new ChangeNotificationOperation((uint32_t) GATEWAY_ADDRESS,
                                device.address64, 769));
                    operation->setDependency(WaveDependency::TENTH);
                    engineOperations.addOperation(operation);
                }
            }

            subnetTdma.setRemovedStatus(itNode->first);
            subnetServices.setRemovedStatus(itNode->first);
            devicesTable.setRemoveStatus(itNode->first);

            EdgeList& edges = itNode->second.getOutBoundEdges();
            for (EdgeList::iterator itEdge = edges.begin(); itEdge != edges.end(); ++itEdge) {

                if (itEdge->getStatus() == Status::DELETED) {
                    continue;
                }

                GraphNeighborMap& neighbors = itEdge->getGraphs();
                for (GraphNeighborMap::iterator it = neighbors.begin(); it != neighbors.end(); ++it) {
                    if (it->second.status == Status::DELETED) {
                        continue;
                    }

                    if (!existsPath(it->first)) {
                        //TODO: ivp - !!! workaround
                        it->second.status = Status::DELETED;
                        LOG_ERROR("Deleted graph: " << ToStr(it->first) << " exists on node: " << itNode->second);
                    } else {
                        affectedGraphs.insert(it->first);
                        LOG_INFO("Affected graph(1): " << ToStr(it->first));
                    }
                }
            }

        } else {
            EdgeList& edges = itNode->second.getOutBoundEdges();
            for (EdgeList::iterator itEdge = edges.begin(); itEdge != edges.end();) {
                if (itEdge->getStatus() == Status::DELETED) {
                    ++itEdge;
                    continue;
                }

                //if peer node is not found mark the edge as deleted
                NodeMap::iterator it_peerNode = nodes.find(itEdge->getDestination());
                if (it_peerNode == nodes.end()) {
                    LOG_DEBUG("Mark deleted edge: its peer is down.");
                    itEdge->setStatus(Status::DELETED);
                    ++itEdge;
                    continue;
                }

                Node& peerNode = it_peerNode->second;

                //Node& peerNode = getNode(itEdge->getDestination());

                if (peerNode.getSearchId() != searchId) {
                    bool hasGraphNeighbors = false;

                    //generate delete GraphNeighbor operation
                    GraphNeighborMap& neighbors = itEdge->getGraphs();
                    for (GraphNeighborMap::iterator it = neighbors.begin(); it != neighbors.end(); ++it) {
                        if (it->second.status == Status::DELETED) {
                            continue;
                        }

                        if (!existsPath(it->first)) {
                            //TODO: ivp - !!! workaround
                            it->second.status = Status::DELETED;
                            LOG_ERROR("Deleted graph: " << ToStr(it->first) << " exists on node: " << itNode->second);
                        } else {
                            affectedGraphs.insert(it->first);
                            LOG_INFO("Affected graph(2 ): " << ToStr(it->first));
                        }

                        hasGraphNeighbors = true;

                        it->second.status = Status::DELETED;

                        if (it->first == OUTBOUND_GW_GRAPH_ID //
                                    && itEdge->getSource() == MANAGER_ADDRESS //
                                    && itEdge->getDestination() == GATEWAY_ADDRESS) {
                            continue;
                        }

                        IEngineOperationPointer operation(new NeighborGraphRemovedOperation(itEdge->getSource(),
                                    it->first, itEdge->getDestination()));

                        operation->setDependency(WaveDependency::NINETH);
                        engineOperations.addOperation(operation);
                    }

                    if (hasGraphNeighbors) {
                        LOG_DEBUG("releaseRemoved - set DELETED edge " << *itEdge);
                        itEdge->setStatus(Status::DELETED);

                        if ((itNode->second.getNodeType() == NodeType::NODE) && (itNode->second.getSecondaryClkSource()
                                    == peerNode.getNodeAddress())) {

                            itNode->second.resetSecondaryClkSource();
                            SetClockSourceOperation *op = new SetClockSourceOperation(itNode->second.getNodeAddress(),
                                        peerNode.getNodeAddress(), 0);
                            IEngineOperationPointer engineOp(op);
                            engineOp->setDependency(WaveDependency::SECOND);
                            engineOperations.addOperation(engineOp);
                        }

                        itEdge++;
                    } else {
                        LOG_DEBUG("releaseRemoved - delete edge" << *itEdge);

                        if ((itNode->second.getNodeType() == NodeType::NODE) && (itNode->second.getSecondaryClkSource()
                                    == peerNode.getNodeAddress())) {
                            itNode->second.resetSecondaryClkSource();
                            SetClockSourceOperation *op = new SetClockSourceOperation(itNode->second.getNodeAddress(),
                                        peerNode.getNodeAddress(), 0);
                            IEngineOperationPointer engineOp(op);
                            engineOp->setDependency(WaveDependency::SECOND);
                            engineOperations.addOperation(engineOp);
                        }

                        //edges.erase(itEdge++);
                        itNode->second.removeEdge(itEdge);
                    }
                } else {
                    ++itEdge;
                }
            }
        }
    }

    // checks the affected routing graphs
    //if the source or destination of the graph is deleted, check if the graph is used by other route,
    //delete or change the source/destination of the graph
    for (std::set<Uint16>::iterator it = affectedGraphs.begin(); it != affectedGraphs.end(); ++it) {
        Path& path = getPath(*it);
        if (path.getType() == RoutingTypes::SOURCE_ROUTING) {
            isGood = path.checkSourcePath();
        } else if (path.getType() == RoutingTypes::GRAPH_ROUTING || path.getType() == RoutingTypes::GRAPH_ROUTING_WITH_MIN_PATH_SELECTION) {
            isGood = path.checkGraphPath(engineOperations, setNextSearchId());
        }

        LOG_DEBUG("releaseRemoved - isGood=" << (int) isGood << " path: " << path);

        //TODO: temporary until a graph is used by multiple devices - in the case
        // that a graph is used by multiple routes, update the source/destination of the graph
        if (!isGood) {
            Address32 address = path.getSource();
            if (address == MANAGER_ADDRESS) {
                address = path.getDestination();
            }

            NodeMap::iterator nodeIt = nodes.find(address);

            if (nodeIt != nodes.end()) {
                if (nodeIt->second.getStatus() != Status::REMOVED) {
                    nodeIt->second.setStatus(Status::CANDIDATE_FOR_REMOVAL);
                    repeat = true;
                }
            }

            if (nodeIt == nodes.end() || nodeIt->second.getStatus() == Status::REMOVED) {
                LOG_DEBUG("releaseRemoved - delete path: " << path);

                PathMap::iterator itPath = paths.find(*it);
                if (itPath != paths.end()) {
                    //paths.erase(itPath);
                    deletePath(itPath);
                }
            }
        }
        else {
            graphsToRefresh.insert(std::pair<int, Uint16>(engineOperations.getOperationsSetIndex(), *it));
            PathMap::iterator itPath = paths.find(*it);
            if (itPath != paths.end()) {
                itPath->second.createTopologicalOrder();
            }
        }
    }

    for (PathMap::iterator it = paths.begin(); it != paths.end();) {
        if (it->second.getEvaluatePathPriority() != EvaluatePathPriority::InboundAttach
                    && it->second.getEvaluatePathPriority() != EvaluatePathPriority::OutboundAttach
                    && devicesTable.getDeviceStatus(it->second.getSource()) != DeviceStatus::DELETED
                    && devicesTable.getDeviceStatus(it->second.getDestination()) != DeviceStatus::DELETED
                    ) {
            ++it;
            continue;
        }

        Address32 address = it->second.getSource();

        if (address == MANAGER_ADDRESS || address == GATEWAY_ADDRESS) {
            address = it->second.getDestination();
        }

        NodeMap::iterator itNode = nodes.find(address);

        if (itNode == nodes.end() || itNode->second.getStatus() == Status::REMOVED) {
            //paths.erase(it++);
            deletePath(it);
        } else {
            ++it;
        }
    }

    for (NodeMap::iterator it = nodes.begin(); it != nodes.end();) {
        if (it->second.getStatus() == Status::REMOVED) {
            subnetServices.setRemovedStatus(it->first);
            subnetTdma.setRemovedStatus(it->first);
            devicesTable.setRemoveStatus(it->first);

            addressSet.insert(it->first);

            if ((it->second.getNodeType() == NodeType::NODE) //
                        && (it->second.hasNeighbor(it->second.getBackboneAddress())) //
                        && (devicesTable.existsDevice(it->second.getBackboneAddress()))) {
                SetClockSourceOperation *op = new SetClockSourceOperation(it->second.getBackboneAddress(), it->first,
                            0x2);
                IEngineOperationPointer engineOp(op);
                engineOp->setDependency(WaveDependency::FIFTH);
                engineOperations.addOperation(engineOp);
            }

            nodes.erase(it++);
        } else {
            ++it;
        }
    }
    if (repeat) {
        LOG_DEBUG("Repeat");
    }
    return repeat;
}