void MainWindow::generateRouteReport() { int totalCost = 0; QString route; // Check a route actually exists if (m_route.isEmpty() || !m_routeStart || !m_routeEnd) { postErrorMessage("Route has not been built."); return; } // Seed the route with the start node route = m_routeStart->text(); // Iterate over the route list updating the variables above QListIterator<EdgeItem*> i(m_route); while (i.hasNext()) { EdgeItem* edge = i.next(); // Add the target to the route route += edge->endNode()->text(); // Update the cost totalCost += edge->weight(); } // Print the result postInfoMessage(QString("Total route cost: %1").arg(totalCost)); postInfoMessage(QString("Route taken: %1").arg(route)); }
UInt32 LpmConfigurationReaderV0::readCpuPercentageActiveLogicalProcessors() { string key = "CpuPercentageActiveLogicalProcessors"; UInt32 cpuPercentageActiveLogicalProcessors; try { cpuPercentageActiveLogicalProcessors = getPolicyServices().platformConfigurationData->readConfigurationUInt32( root() + keyPath() + key); } catch(dptf_exception& e) { string msg = e.what(); postInfoMessage(PolicyMessage(FLF, "No CpuPercentageActiveLogicalProcessors - defaulting to 1%. msg - " + msg, Constants::Invalid)); // Default to 1% (translates to 1 core). cpuPercentageActiveLogicalProcessors = 1; } if (cpuPercentageActiveLogicalProcessors < 1) { cpuPercentageActiveLogicalProcessors = 1; } else if (cpuPercentageActiveLogicalProcessors > 100) { cpuPercentageActiveLogicalProcessors = 100; } return cpuPercentageActiveLogicalProcessors; }
CoreControlOffliningMode::Type LpmConfigurationReaderV0::readCpuOffliningMode() { string key = "CpuOffLiningMode"; CoreControlOffliningMode::Type cpuOffliningMode; try { UIntN valueInt = getPolicyServices().platformConfigurationData->readConfigurationUInt32( root() + keyPath() + key); if (valueInt > CoreControlOffliningMode::Core) { postErrorMessage(PolicyMessage(FLF, "Invalid CoreControlOffliningMode returned (" + to_string(valueInt) + ")" + " - defaulting to core", Constants::Invalid)); cpuOffliningMode = CoreControlOffliningMode::Core; } else { cpuOffliningMode = (CoreControlOffliningMode::Type)valueInt; } } catch(dptf_exception& e) { string msg = e.what(); postInfoMessage(PolicyMessage(FLF, "No CoreControlOffliningMode returned - defaulting to core. msg - " + msg, Constants::Invalid)); cpuOffliningMode = CoreControlOffliningMode::Core; } return cpuOffliningMode; }
Bool LpmConfigurationReaderV0::readCpuUseTStateThrottling() { string key = "CpuUseTStateThrottling"; Bool cpuUseTStateThrottling; try { UIntN valueInt = getPolicyServices().platformConfigurationData->readConfigurationUInt32( root() + keyPath() + key); if (valueInt) { cpuUseTStateThrottling = true; } else { cpuUseTStateThrottling = false; } } catch(dptf_exception& e) { string msg = e.what(); postInfoMessage(PolicyMessage(FLF, "No CpuUseTStateThrottling - defaulting to false. msg - " + msg, Constants::Invalid)); cpuUseTStateThrottling = false; } if ((cpuUseTStateThrottling != true) && (cpuUseTStateThrottling != false)) { cpuUseTStateThrottling = false; } return cpuUseTStateThrottling; }
// Network specification stuff void MainWindow::parseAndRouteNetwork(const QString& description) { // Attempt to build the graph int buildResult = buildNetwork(description); if (buildResult < 0) { // Error occurred; just clear everything and abort clearNetwork(); return; } // Load complete, lay it out if ((buildResult & WarningAbort) == 0) { postInfoMessage("Laying out graph..."); applySpringLayout(); postSuccessMessage("Graph loaded successfully!"); // Enable the UI m_controlsDock->enableClearNetwork(true); m_controlsDock->enableGraphLayoutOptions(true); // Extract the start and end points if (buildResult == Success) { postInfoMessage("Beginning routing step..."); routeNetwork(); // Enable the graph display controls and the report generator m_controlsDock->enableGraphDisplayOptions(true); m_controlsDock->enableGenerateReport(true); } else { // Make sure the route does not exist m_routeStart = m_routeEnd = nullptr; m_route.clear(); // Disable the UI stuff that depends on the route being generated m_controlsDock->enableGraphDisplayOptions(false); m_controlsDock->enableGenerateReport(false); // Inform the user postErrorMessage("Routing skipped step due to warnings."); } } }
// MainWindow implementation MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , m_highlightPath(true) { // Set up the general UI stuff m_ui.setupUi(this); // Create the graph explorer m_graphScene = new QGraphicsScene(this); m_graphScene->setItemIndexMethod(QGraphicsScene::NoIndex); m_graphView = new QGraphicsView; m_graphView->setScene(m_graphScene); m_graphView->setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing); m_graphView->setCacheMode(QGraphicsView::CacheNone); m_graphView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); m_graphView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse); m_graphView->setResizeAnchor(QGraphicsView::AnchorViewCenter); m_graphView->ensureVisible(-150.0f, -150.0f, 300.0f, 300.0f); // Set as central widget setCentralWidget(m_graphView); // Create the transcript QDockWidget* transcriptDock = new QDockWidget( QLatin1String("Transcript"), this); m_transcript = new QTextEdit(transcriptDock); m_transcript->setFont(QFont("Meslo LG S DZ", 8)); transcriptDock->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetVerticalTitleBar); transcriptDock->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea); transcriptDock->setWidget(m_transcript); addDockWidget(Qt::BottomDockWidgetArea, transcriptDock); // Create the control button panel m_controlsDock = new ControlsDockWidget(this); m_controlsDock->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable); m_controlsDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); addDockWidget(Qt::RightDockWidgetArea, m_controlsDock); // Initialisation finished postInfoMessage("Ready; paste network description into the text edit."); }
vector<LpmSet> LpmConfigurationReaderV1::readLpmSets(void) { vector<LpmSet> lpmSets; vector<LpmEntry> lpmEntries; // // Since this configuration does not have the numLpmEntries we loop through // till we fail to read. We handle it in the catch block. // UIntN lpmSetIndex; try { for (lpmSetIndex = LpmEntriesIndexLimit::MinLpmSetIndex; ; lpmSetIndex++) { setLpmSetsKeyPath(lpmSetIndex); lpmEntries = readLpmEntries(); if (lpmEntries.empty()) { // No more LPM entries to process. throw dptf_exception("No more LPM entries"); } lpmSets.push_back(LpmSet(lpmSetIndex, lpmEntries)); if (lpmSetIndex >= LpmEntriesIndexLimit::MaxLpmSetIndex) { throw dptf_exception("Number of LPM sets exceeded max value"); } } } catch (dptf_exception& e) { string msg = e.what(); postInfoMessage(PolicyMessage(FLF, "Error msg (" + msg + "). Last lpmSetIndex = " + to_string(lpmSetIndex), Constants::Invalid)); return lpmSets; } // Will come here only if there are no entries/lpmsets. return lpmSets; }
vector<LpmEntry> LpmConfigurationReaderV1::readLpmEntries(void) { vector<LpmEntry> lpmEntries; string target; DomainType::Type domainType; ControlKnobType::Type controlKnob; UInt32 controlValue; UIntN lpmEntryIndex; string inputKeyPath = keyPath(); try { for (lpmEntryIndex = 0; ; lpmEntryIndex++) { setLpmEntryKeyPath(inputKeyPath, lpmEntryIndex); target = readTargetDeviceAcpiScope(); domainType = readDomainType(); controlKnob = readControlKnob(); controlValue = readControlValue(); lpmEntries.push_back(LpmEntry(target, domainType, controlKnob, controlValue)); if (lpmEntryIndex >= LpmEntriesIndexLimit::MaxLpmEntryIndex) { throw dptf_exception("LPM entries exceeded max value"); } } } catch (dptf_exception& e) { string msg = e.what(); postInfoMessage(PolicyMessage(FLF, "Error msg (" + msg + "). Last lpmEntryIndex = " + to_string(lpmEntryIndex), Constants::Invalid)); return lpmEntries; } return (lpmEntries); }
vector<AppSpecificEntry> LpmConfigurationReaderV1::readAppSpecificEntries(void) { vector<AppSpecificEntry> appSpecificEntries; // // Since this configuration does not have the numAppSpecificEntries we loop through // till we fail to read. We handle it in the catch block. // UIntN appIndex; try { for (appIndex = 0; ; appIndex++) { vector<string> appNames = readAppNames(appIndex); string key = "LPMSet"; UIntN lpmSetIndex = getPolicyServices().platformConfigurationData->readConfigurationUInt32( root() + keyPath() + key); appSpecificEntries.push_back(AppSpecificEntry(appNames, lpmSetIndex)); if (appIndex >= LpmEntriesIndexLimit::MaxAppEntryIndex) { throw dptf_exception("App Entries exceeded max value"); } } } catch (dptf_exception& e) { string msg = e.what(); postInfoMessage(PolicyMessage(FLF, "Error msg (" + msg + "). Last appIndex = " + to_string(appIndex), Constants::Invalid)); return appSpecificEntries; } return appSpecificEntries; }
vector<string> LpmConfigurationReaderV0::readAppNames(UInt32 entryIndex) { string key = "AppName"; vector<string> appNames; string indexAsString = getIndexAsString(entryIndex); setKeyPath("AppSpecificMode" + indexAsString + "/"); try { // TODO: Error check for appname? string appName = getPolicyServices().platformConfigurationData->readConfigurationString( root() + keyPath() + key); appNames.push_back(appName); } catch (dptf_exception& e) { string msg = e.what(); postInfoMessage(PolicyMessage(FLF, "Error msg (" + msg + "). Error in reading AppName", Constants::Invalid)); } return appNames; }
UInt32 LpmConfigurationReaderV0::readCpuTargetFrequency() { string key = "CpuTargetFrequency"; UInt32 cpuTargetFrequency; try { cpuTargetFrequency = getPolicyServices().platformConfigurationData->readConfigurationUInt32( root() + keyPath() + key); } catch(dptf_exception& e) { string msg = e.what(); postInfoMessage(PolicyMessage(FLF, "No CpuTargetFrequency - defaulting to 800Mhz. msg - " + msg, Constants::Invalid)); // if not found, we default to 800 mhz (MFM or LFM) cpuTargetFrequency = 800; } return cpuTargetFrequency; }
vector<AppSpecificEntry> LpmConfigurationReaderV0::readAppSpecificEntries(void) { m_lpmSets.clear(); vector<AppSpecificEntry> appSpecificEntries; UIntN entryIndex = 0; try { string key = "NumAppSpecificEntries"; UIntN numEntries = getPolicyServices().platformConfigurationData->readConfigurationUInt32( root() + key); if (numEntries == 0) { throw dptf_exception("No app specific entries for v0"); } for (entryIndex = 0; entryIndex < numEntries; entryIndex++) { vector<string> appNames = readAppNames(entryIndex); vector<LpmEntry> lpmEntries = readLpmEntries(); appSpecificEntries.push_back(AppSpecificEntry(appNames, entryIndex)); m_lpmSets.push_back(LpmSet(entryIndex, lpmEntries)); } } catch (dptf_exception& e) { string msg = e.what(); postInfoMessage(PolicyMessage(FLF, "Error msg (" + msg + "). Last entryIndex = " + to_string(entryIndex), Constants::Invalid)); } return appSpecificEntries; }
void MainWindow::routeNetwork() { // Storage class for the metadata required by Dijkstra struct MetaData { int distance; EdgeItem* edge; NodeItem* previous; NodeItem* owner; MetaData() : distance(INT_MAX) , edge(nullptr) , previous(nullptr) , owner(nullptr) { } MetaData(NodeItem* owner_) : distance(INT_MAX) , edge(nullptr) , previous(nullptr) , owner(owner_) { } }; QMap<NodeItem*, MetaData> metadata; QList<NodeItem*> nodes; NodeItem* current; // Initialise data-structres postInfoMessage("Preparing to route..."); { QMapIterator<QString, NodeItem*> i(m_graphNodes); while (i.hasNext()) { auto item = i.next(); // Initialise the metadata MetaData md(item.value()); if (item.value() == m_routeStart) { // Need minimal distance for the start node md.distance = 0; } metadata[i.value()] = md; // Initialise the node list nodes.append(i.value()); } } // Dijkstra's algorithm: calculate all the distances while (!nodes.isEmpty()) { // Find node with smallest distance { int d = INT_MAX; auto elem = nodes.end(); for (auto it = nodes.begin(); it != nodes.end(); ++it) { int thisDistance = metadata[*it].distance; if (thisDistance < d) { d = thisDistance; elem = it; } } current = *elem; // If we hit the target, we can stop if (current == m_routeEnd) { postInfoMessage("Search complete; reached target node!"); break; } else { // Emshrinken the list nodes.erase(elem); } } postInfoMessage(QString("Considering node %1...") .arg(current->text())); // Visit the neighbours QListIterator<EdgeItem*> i(current->edges()); while (i.hasNext()) { EdgeItem* edge = i.next(); NodeItem* neighbour = edge->endNode(); int dist = metadata[current].distance + edge->weight(); if (dist < metadata[neighbour].distance) { metadata[neighbour].distance = dist; metadata[neighbour].edge = edge; metadata[neighbour].previous = current; } } } // Walk backwards from the target to the source, building the path postInfoMessage("Back-tracking to construct route..."); for (current = m_routeEnd; current; current = metadata[current].previous) { EdgeItem* edge = metadata[current].edge; if (edge) { m_route.prepend(edge); } } // All done! postSuccessMessage("Routing complete!"); // Update the display setHighlightStartNode(m_controlsDock->highlightStartNode()); setHighlightEndNode(m_controlsDock->highlightEndNode()); setHighlightPath(m_controlsDock->highlightPath()); }
int MainWindow::buildNetwork(const QString& description) { int result = Success; // Split into lines QStringList lines = description.split(QRegExp("[\\n|\\r]"), QString::SkipEmptyParts); if (lines.isEmpty()) { postErrorMessage("Problem specification is empty after whitespace " "removed!"); return ErrorEmpty; } // Validate the length of the specification int nodeCount = lines[0].toInt(); postInfoMessage(QString("Expecting %1x%1 adjacency matrix...") .arg(nodeCount)); if (lines.length() != (nodeCount + 2)) { postErrorMessage(QString("Expecting %1 lines in specification; read %2") .arg(nodeCount + 2) .arg(lines.length())); return ErrorSpecTooSmall; } // Clear the existing graph and scene if (boost::num_vertices(m_graph) != 0) { postWarningMessage("Existing network already loaded; must be cleared " "in order to continue."); int response = QMessageBox::question(this, "NetRoute", "There is " "already a graph in the explorer; the current data will have to " "be discared. Continue?"); if (response == QMessageBox::No) { postErrorMessage("Aborted by user."); return WarningAbort; } postInfoMessage("Discarding network."); clearNetwork(); } // Create the nodes postInfoMessage("Creating nodes..."); for (int i = 0; i < nodeCount; ++i) { QString name = QString("%1").arg(QChar('A' + i)); NodeItem* node = new NodeItem; node->setText(name); m_graphNodes[name] = node; boost::add_vertex(NodeProperties(node), m_graph); m_graphScene->addItem(node); } // Create the edges postInfoMessage("Creating edges from adjacency matrix..."); for (int i = 0; i < nodeCount; ++i) { QString line = lines[i + 1].trimmed(); QStringList weights = line.split(',', QString::SkipEmptyParts); // Sanity check if (weights.length() != nodeCount) { postErrorMessage( QString("Matrix row %1 has %2 columns; expecting %3.") .arg(i) .arg(weights.length()) .arg(nodeCount)); return ErrorRowTooShort; } // Actually create the edges postInfoMessage(QString("Creating edges for node %1") .arg(QChar('A' + i))); DigraphVertex vStart = boost::vertex(i, m_graph); for (int j = 0; j < nodeCount; ++j) { bool ok; int weight = weights[j].trimmed().toInt(&ok); if (ok && weight >= 0) { DigraphVertex vEnd = boost::vertex(j, m_graph); // Create the new edge item EdgeItem* edge = new EdgeItem; edge->setStartNode(m_graph[vStart].item); edge->setEndNode(m_graph[vEnd].item); edge->setWeight(weight); m_graphScene->addItem(edge); // Add it to the graph boost::add_edge(vStart, vEnd, EdgeProperties(edge), m_graph); } else if (!ok) { postWarningMessage(QString("Weight (%1,%2) is malformed: %3.") .arg(i) .arg(j) .arg(weights[j])); result |= WarningBadCell; } } } // Parse the final line of the description: the start/end nodes QStringList nodes = lines[lines.length() - 1].split(QRegExp("\\s+"), QString::SkipEmptyParts); if (nodes.length() != 2) { postWarningMessage("Start and end nodes line is malformed; " "routing will not take place."); result |= WarningBadStartEnd; } else { QString startNodeName = nodes[0]; QString endNodeName = nodes[1]; m_routeStart = m_graphNodes[startNodeName]; m_routeEnd = m_graphNodes[endNodeName]; if (!m_routeStart) { postWarningMessage(QString("Failed to find start node '%1'; " "routing will not take place.") .arg(startNodeName)); result |= WarningNoStartNode; } if (!m_routeEnd) { postWarningMessage(QString("Failed to find end node '%1'; " "routing will not take place.") .arg(endNodeName)); result |= WarningNoEndNode; } } // Graph was built successfully, even if some parsing errors arose. return result; }