Solid

winprocessor.cpp
1/*
2 SPDX-FileCopyrightText: 2013 Patrick von Reth <vonreth@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5*/
6
7#include "winprocessor.h"
8
9#include <solid/devices/backends/shared/cpufeatures.h>
10
11#include <QSettings>
12
13using namespace Solid::Backends::Win;
14
15typedef BOOL(WINAPI *GLPI_fn)(SYSTEM_LOGICAL_PROCESSOR_INFORMATION *Buffer, DWORD *ReturnLength);
16GLPI_fn pGetLogicalProcessorInformation = (GLPI_fn)GetProcAddress(LoadLibraryA("kernel32.dll"), "GetLogicalProcessorInformation");
17
18WinProcessor::WinProcessor(WinDevice *device)
19 : WinInterface(device)
20{
21 m_number = m_device->udi().mid(m_device->udi().length() - 1).toInt();
22}
23
24WinProcessor::~WinProcessor()
25{
26}
27
28int WinProcessor::number() const
29{
30 return m_number;
31}
32
33int WinProcessor::maxSpeed() const
34{
35 return updateCache()[m_number].speed;
36}
37
38bool WinProcessor::canChangeFrequency() const
39{
40 // TODO:implement
41 return false;
42}
43
44Solid::Processor::InstructionSets WinProcessor::instructionSets() const
45{
46 static Solid::Processor::InstructionSets set = Solid::Backends::Shared::cpuFeatures();
47 return set;
48}
49
50QSet<QString> WinProcessor::getUdis()
51{
52 static QSet<QString> out;
53 if (out.isEmpty()) {
54 const QMap<int, ProcessorInfo> map = updateCache();
55 for (const ProcessorInfo &info : map) {
56 out << QString("/org/kde/solid/win/cpu/device#%1,cpu#%2").arg(info.id).arg(info.lgicalId);
57 }
58 }
59 return out;
60}
61
62DWORD WinProcessor::countSetBits(ULONG_PTR bitMask)
63{
64 DWORD LSHIFT = sizeof(ULONG_PTR) * 8 - 1;
65 DWORD bitSetCount = 0;
66 ULONG_PTR bitTest = (ULONG_PTR)1 << LSHIFT;
67 DWORD i;
68
69 for (i = 0; i <= LSHIFT; ++i) {
70 bitSetCount += ((bitMask & bitTest) ? 1 : 0);
71 bitTest /= 2;
72 }
73
74 return bitSetCount;
75}
76
77const QMap<int, WinProcessor::ProcessorInfo> &WinProcessor::updateCache()
78{
80
81 if (p.isEmpty()) {
82 DWORD size = 0;
83 pGetLogicalProcessorInformation(NULL, &size);
84 char *buff = new char[size];
85 SYSTEM_LOGICAL_PROCESSOR_INFORMATION *info = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION *)buff;
86 pGetLogicalProcessorInformation(info, &size);
87 size /= sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
88
89 uint processorCoreCount = 0;
90 uint logicalProcessorCount = 0;
91
92 for (uint i = 0; i < size; ++i) {
93 if (info[i].Relationship == RelationProcessorCore) {
94 // A hyperthreaded core supplies more than one logical processor.
95 uint old = logicalProcessorCount;
96 logicalProcessorCount += countSetBits(info[i].ProcessorMask);
97 for (; old < logicalProcessorCount; ++old) {
98 QSettings settings(QLatin1String("HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\") + QString::number(old),
100 ProcessorInfo proc;
101 proc.id = processorCoreCount;
102 proc.lgicalId = old;
103 proc.speed = settings.value("~MHz").toInt();
104 proc.vendor = settings.value("VendorIdentifier").toString().trimmed();
105 proc.name = settings.value("ProcessorNameString").toString().trimmed();
106 proc.produuct = settings.value("Identifier").toString().trimmed();
107
108 p[old] = proc;
109 }
110 processorCoreCount++;
111 }
112 }
113 delete[] buff;
114 }
115 return p;
116}
117
118#include "moc_winprocessor.cpp"
bool isEmpty() const const
bool isEmpty() const const
QString arg(Args &&... args) const const
QString number(double n, char format, int precision)
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:17:12 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.