ActiveRelationshipTable ActiveRelationshipTable::createArtFromDptfBuffer(const DptfBuffer& buffer) { std::vector<std::shared_ptr<RelationshipTableEntryBase>> entries; UInt8* data = reinterpret_cast<UInt8*>(buffer.get()); struct EsifDataBinaryArtPackage* currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); if (buffer.size() == 0) { throw dptf_exception("There is no data to process."); } UIntN rows = countArtRows(buffer.size(), data); // Reset currentRow to point to the beginning of the data block data = reinterpret_cast<UInt8*>(buffer.get()); data += sizeof(esif_data_variant); // Ignore revision field currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); for (UIntN i = 0; i < rows; i++) { // Since the ART has 2 strings in it, the process for extracting them is: // 1. Extract the source at the beginning of the structure // 2. Since the actual string data is placed between the source and target, the pointer needs moved // 3. Move the pointer past the source string data and set current row // 4. Now the targetDevice field will actually point to the right spot // 5. Extract target device // 6. Move the pointer as before (past the targetDevice string data) and set current row // 7. Extract the remaining fields // 8. Point data and currentRow to the next row std::string source = TableStringParser::getDeviceString((currentRow->sourceDevice)); data += currentRow->sourceDevice.string.length; currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); std::string target = TableStringParser::getDeviceString((currentRow->targetDevice)); data += currentRow->targetDevice.string.length; currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); std::vector<UInt32> acEntries; acEntries.push_back(static_cast<UInt32>(currentRow->ac0MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac1MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac2MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac3MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac4MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac5MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac6MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac7MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac8MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac9MaxFanSpeed.integer.value)); auto newArtEntry = std::make_shared<ActiveRelationshipTableEntry>( BinaryParse::normalizeAcpiScope(source), BinaryParse::normalizeAcpiScope(target), static_cast<UInt32>(currentRow->weight.integer.value), acEntries); if (newArtEntry) { // Check for duplicate entries. Don't add entry if previous entry exists with same target/source pair Bool isDuplicateEntry = false; for (auto e = entries.begin(); e != entries.end(); e++) { auto artEntry = std::dynamic_pointer_cast<ActiveRelationshipTableEntry>(*e); if (artEntry && newArtEntry->isSameAs(*artEntry)) { isDuplicateEntry = true; break; } } if (isDuplicateEntry == false) { entries.push_back(newArtEntry); } } // Since we've already accounted for the strings, we now move the pointer by the size of the structure // to get to the next row. data += sizeof(struct EsifDataBinaryArtPackage); currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); } return ActiveRelationshipTable(entries); }
ThermalRelationshipTable ThermalRelationshipTable::createTrtFromDptfBuffer(const DptfBuffer& buffer) { std::vector<std::shared_ptr<RelationshipTableEntryBase>> entries; UInt8* data = reinterpret_cast<UInt8*>(buffer.get()); struct EsifDataBinaryTrtPackage* currentRow = reinterpret_cast<struct EsifDataBinaryTrtPackage*>(data); if (buffer.size() != 0) { UIntN rows = countTrtRows(buffer.size(), data); // Reset currentRow to point to the beginning of the data block data = reinterpret_cast<UInt8*>(buffer.get()); currentRow = reinterpret_cast<struct EsifDataBinaryTrtPackage*>(data); for (UIntN i = 0; i < rows; i++) { // Since the TRT has 2 strings in it, the process for extracting them is: // 1. Extract the source at the beginning of the structure // 2. Since the actual string data is placed between the source and target, the pointer needs moved // 3. Move the pointer past the source string data and set current row // 4. Now the targetDevice field will actually point to the right spot // 5. Extract target device // 6. Move the pointer as before (past the targetDevice string data) and set current row // 7. Extract the remaining fields // 8. Point data and currentRow to the next row std::string source( reinterpret_cast<const char*>(&(currentRow->sourceDevice)) + sizeof(union esif_data_variant), currentRow->sourceDevice.string.length); data += currentRow->sourceDevice.string.length; currentRow = reinterpret_cast<struct EsifDataBinaryTrtPackage*>(data); std::string target( reinterpret_cast<const char*>(&(currentRow->targetDevice)) + sizeof(union esif_data_variant), currentRow->targetDevice.string.length); data += currentRow->targetDevice.string.length; currentRow = reinterpret_cast<struct EsifDataBinaryTrtPackage*>(data); auto newTrtEntry = std::make_shared<ThermalRelationshipTableEntry>( BinaryParse::normalizeAcpiScope(source), BinaryParse::normalizeAcpiScope(target), static_cast<UInt32>(currentRow->thermalInfluence.integer.value), TimeSpan::createFromTenthSeconds(static_cast<UInt32>(currentRow->thermalSamplingPeriod.integer.value))); if (newTrtEntry) { // Check for duplicate entries. Don't add entry if previous entry exists with same target/source pair Bool isDuplicateEntry = false; for (auto e = entries.begin(); e != entries.end(); e++) { auto trtEntry = std::dynamic_pointer_cast<ThermalRelationshipTableEntry>(*e); if (trtEntry && newTrtEntry->isSameAs(*trtEntry)) { isDuplicateEntry = true; break; } } if (isDuplicateEntry == false) { entries.push_back(newTrtEntry); } } // Since we've already accounted for the strings, we now move the pointer by the size of the structure // to get to the next row. data += sizeof(struct EsifDataBinaryTrtPackage); currentRow = reinterpret_cast<struct EsifDataBinaryTrtPackage*>(data); } } return ThermalRelationshipTable(entries); }
Future<bool> CheckoutAction::hasConflict() { if (oldTree_) { auto treeInode = inode_.asTreePtrOrNull(); if (!treeInode) { // This was a directory, but has been replaced with a file on disk ctx_->addConflict(ConflictType::MODIFIED_MODIFIED, inode_.get()); return true; } // TODO: check for permissions changes // We don't check if this tree is unmodified from the old tree or not here. // We simply apply the checkout to the tree in this case, so that we report // conflicts for individual leaf inodes that were modified, and not for the // parent directories. return false; } else if (oldBlob_) { auto fileInode = inode_.asFilePtrOrNull(); if (!fileInode) { // This was a file, but has been replaced with a directory on disk ctx_->addConflict(ConflictType::MODIFIED_MODIFIED, inode_.get()); return true; } // Check that the file contents are the same as the old source control entry return fileInode->isSameAs(*oldBlob_, oldScmEntry_.value().getType()) .thenValue([this](bool isSame) { if (isSame) { // no conflict return false; } // The file contents or mode bits are different: // - If the file exists in the new tree but differs from what is // currently in the working copy, then this is a MODIFIED_MODIFIED // conflict. // - If the file does not exist in the new tree, then this is a // MODIFIED_REMOVED conflict. auto conflictType = newScmEntry_ ? ConflictType::MODIFIED_MODIFIED : ConflictType::MODIFIED_REMOVED; ctx_->addConflict(conflictType, inode_.get()); return true; }); } DCHECK(!oldScmEntry_) << "Both oldTree_ and oldBlob_ are nullptr, " "so this file should not have an oldScmEntry_."; DCHECK(newScmEntry_) << "If there is no oldScmEntry_, then there must be a " "newScmEntry_."; auto localIsFile = inode_.asFilePtrOrNull() != nullptr; if (localIsFile) { auto remoteIsFile = !newScmEntry_->isTree(); if (remoteIsFile) { // This entry is a file that did not exist in the old source control tree, // but it exists as a tracked file in the new tree. ctx_->addConflict(ConflictType::UNTRACKED_ADDED, inode_.get()); return true; } else { // This entry is a file that did not exist in the old source control tree, // but it exists as a tracked directory in the new tree. ctx_->addConflict(ConflictType::MODIFIED_MODIFIED, inode_.get()); return true; } } else { // This entry is a directory that did not exist in the old source control // tree. We must traverse the directory for UNTRACKED_ADDED and // MODIFIED_MODIFIED conflicts. Returning false signals that we must // recurse into this directory to continue to look for conflicts. return false; } }