Disable CPU package idle states in Windows from C++ code - c++

I am successfully disabling CPU core C-states using this code (I’m working on Win10 and use Qt):
#include <QCoreApplication>
#include <QDebug>
#include "Windows.h"
extern "C" {
#include "powrprof.h"
}
#pragma comment(lib, "powrprof.lib")
int main()
{
const DWORD DISABLED = 1;
const DWORD ENABLED = 0;
GUID *scheme;
int error;
error = PowerGetActiveScheme(NULL, &scheme);
qDebug() << "PowerGetActiveScheme error code = " << error;
error = PowerWriteACValueIndex(NULL, scheme, &GUID_PROCESSOR_SETTINGS_SUBGROUP, &GUID_PROCESSOR_IDLE_DISABLE, DISABLED);
qDebug() << "PowerWriteACValueIndex error code = " << error;
error = PowerWriteDCValueIndex(NULL, scheme, &GUID_PROCESSOR_SETTINGS_SUBGROUP, &GUID_PROCESSOR_IDLE_DISABLE, DISABLED);
qDebug() << "PowerWriteDCValueIndex error code = " << error;
error = PowerSetActiveScheme(NULL, scheme);
qDebug() << "PowerSetActiveScheme error code = " << error;
return 0;
}
The reason behind this is that I am running an USB camera and figured out that I’m losing data packets when the processor enters idle modes. The code above works fine and overcomes this issue successfully. But it’s actually a bit too much (disabling all C states appears to be unnecessary). I made some tests with the vendor software of the camera and found out that during acquisition not the core C-states stop, but the package C-states (if it is of any interest, I posted the analysis of this problem in the answer here https://superuser.com/questions/1648849/monitor-used-usb-bandwidth-in-win10).
So my question is: Can I adapt the above code to only disable package idle states? In case that’s not possible, can I selectively disable core C-states?
Update:
Based on the suggestion of #1201ProgramAlarm I tried to use SetThreadPriority() as in the minimal example below:
#include <QDebug>
#include <windows.h>
#include <conio.h>
#include "processthreadsapi.h"
int main()
{
bool ok = false;
ok = SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
qDebug() << "SetPriorityClass ok = " << ok;
ok = SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
qDebug() << "SetThreadPriority ok = " << ok;
for (int i=1;i<100;i++) {
qDebug() << "Here I am in some dummy loop...";
if (_kbhit()) {
break;
}
Sleep(1000);
}
return 0;
}
Unfortunately, this doesn't help and when monitoring the cpu package idle states (using HWiNFO64) I see no effect (package goes still idle as before).

The system is shutting down the USB device to save power.
This link provides the solution USB system power issue.
Open the Device manager as administrator.
Find the camera.
On the "Power Management" tab, deselect "Allow the computer to turn off this device to save power".
This can be done programmatically if the device ID is known.

Related

Prevent GetAsyncKeyState() from getting blocked by Antivirus Software

I'm trying to create an afk money bot for a game.
I'm using GetAsyncKeyState() to start and stop the bot.
I've run the code a few times to try out a few things. Then I added a delay between calling the GetAsyncKeyState() function using the clock() function. When I tried to run the new code, I got an error stating that the .exe file was missing. I tried rebuiding or cleaning the project but it didn't work. Then I deleted the project, created a new one and copied the code back into the project. This did not work either, but I noticed a notification by my antivirus program: The .exe was detected as a fugrafa threat. I'm pretty confident that this was somehow caused by the GetAsyncKeyState() function since keyloggers can be recognized as a fugrafa threat.
There's gotta be a way to prevent this from happening, since I've seen GetAsyncKeyState() being used a lot.
Or do I really need to disable the antivirus in order to be able to use GetAsyncKeyState()?
Here's the Code:
#include <chrono>
#include <iostream>
#include <windows.h>
bool botActive = false;
void timeout(int);
int main()
{
bool F3_CurrentKeyState = GetAsyncKeyState(VK_F3);
bool F3_PreviousKeyState = F3_CurrentKeyState;
while (true)
{
//F3 Key Edge detection
F3_PreviousKeyState = F3_CurrentKeyState;
F3_CurrentKeyState = GetAsyncKeyState(VK_F3);
if (GetAsyncKeyState(VK_F3) && (F3_CurrentKeyState != F3_PreviousKeyState)) botActive = !botActive;
if (botActive)
{
std::cout << "Bot Active" << std::endl;
}
else
{
std::cout << "Bot Inactive" << std::endl;
}
timeout(100/*ms*/);
}
}
void timeout(int delay_ms)
{
clock_t toutStart = clock();
while (((float)clock() - toutStart) < delay_ms);
}

How to know if a device has been explicitly been disabled by user?

Using device manager a user can explicitly enable/disable a device, as can be seen in the following image.
For a given device I want to know if it's currently in a user disabled/enabled state.
I have tried the following approaches
CM_Get_DevNode_Status(&status, &problem, data.DevInst, 0); I was hoping that presence of DN_STARTED, or DN_DRIVER_LOADED would tell me that. But these can be zero even when a driver is being loaded/unloaded by the OS, when the device connects/disconnects. For example, a device which is enabled, and for which driver is loaded. DN_STARTED will be 1, but when we disconnect device it is set to zero before the device's entry is removed from device manager.
SetupDiGetDeviceRegistryProperty(..., SPDRP_INSTALL_STATE, ...) I though a state of CM_INSTALL_STATE_INSTALLED should mean that the device is enabled. But the function returns this state even for disabled devices.
Using WMI I was able to get the required information, but I used wmi in PowerShell. I do not want to use wmi, as it is quite difficult to implement in native c++. I used the following query.
Select Name, Availability, ConfigManagerErrorCode, ConfigManagerUserConfig from Win32_PnPEntity where Name = 'NVIDIA Quadro M1000M'
ConfigManagerErrorCode in above query, if set to 22, means that device has been disabled, 21 means that windows is removing the device
I am looking for a non wmi solution.
The information can be obtained from a device's problem code. There are two ways which I could find to get it.
Use SetupDiGetDeviceProperty() to query DEVPKEY_Device_ProblemCode.
Use CM_Get_DevNode_Status() the problem code will be present in the second argument after the call.
A problem code of 22 (CM_PROB_DISABLED) means that the device has been explicitly disabled by a user by either using device manager, or other such utility.
Sample code
#include "stdafx.h"
#include <Windows.h>
#include <SetupAPI.h>
#include <Cfgmgr32.h>
#include <devguid.h>
#include <initguid.h>
#include "devpkey.h"
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
HDEVINFO hDevInfo = ::SetupDiGetClassDevs(&GUID_DEVCLASS_DISPLAY, NULL, NULL, 0); //only getting for GPUs on the machine
if (INVALID_HANDLE_VALUE != hDevInfo)
{
SP_DEVINFO_DATA data;
data.cbSize = (DWORD)sizeof(data);
for (unsigned int nIndex = 0; ::SetupDiEnumDeviceInfo(hDevInfo, nIndex, &data); nIndex++)
{
ULONG status = 0, problem = 0;
CONFIGRET cr = ::CM_Get_DevNode_Status(&status, &problem, data.DevInst, 0); //after the call 'problem' variable will have the problem code
if (CR_SUCCESS == cr)
{
cout << " problem " << problem <<endl;
if(problem == CM_PROB_DISABLED)
{ /*Do Something*/ }
DEVPROPTYPE propertyType;
const DWORD propertyBufferSize = 100;
BYTE propertyBuffer[propertyBufferSize];
std::fill(begin(propertyBuffer), end(propertyBuffer), BYTE(0));
DWORD requiredSize = 0;
if (SetupDiGetDeviceProperty(hDevInfo, &data, &DEVPKEY_Device_ProblemCode, &propertyType, propertyBuffer, propertyBufferSize, &requiredSize, 0)) //after the call 'propertyBuffer' will have error codes
{
unsigned long deviceProblemCode = *((unsigned long*)propertyBuffer);
cout << " deviceProblemCode " << deviceProblemCode << endl;
if(problem == CM_PROB_DISABLED)
{ /*Do Something*/ }
}
}
}
}
return 0;
}
Sample Output
problem 0
deviceProblemCode 0
problem 22
deviceProblemCode 22
In the question it can be seen that Intel(R) HD Graphics 530 was enabled, and NVIDIA Quadro M1000M was disabled. Hence in the output we got a problem code of 0, and a problem code of 22 (CM_PROB_DISABLED).

I2C error when using the Windows Monitor Configuration Functions

I'm attempting to get/set the brightness level of the monitor through the Windows API. I've tried both the Low-Level Monitor Configuration Functions and the High-Level Monitor Configuration Functions, but they both seem to be breaking in the same place. In both cases I have no problem getting the HMONITOR handle and getting the physical monitor handle from the HMONITOR, but once I try to query the DDC/CI capabilities, I get an error saying "An error occurred while transmitting data to the device on the I2C bus."
The particular functions that cause this error are GetMonitorCapabilities for the high-level functions and GetCapabilitiesStringLength for the low-level functions. They both cause the same error.
This leads me to believe that maybe my monitor doesn't support DDC/CI, but I know my laptop's monitor brightness can be changed through the control panel, so it must be controlled through software somehow. Also I can successfully use the WMI classes in a PowerShell script to get/set the brightness as described on this page. Most things I've read suggest that most modern laptop screens do support DDC/CI.
Is there any way to find out what is causing this error or to get more information about it? I'm currently working in C++ in Visual Studio 2013 on Windows 7. I could probably use WMI in my C++ program if I can't get this current method working, but I thought I would ask here first.
Here's the code I currently have:
#include "stdafx.h"
#include <windows.h>
#include <highlevelmonitorconfigurationapi.h>
#include <lowlevelmonitorconfigurationapi.h>
#include <physicalmonitorenumerationapi.h>
#include <iostream>
#include <string>
int _tmain(int argc, _TCHAR* argv[])
{
DWORD minBrightness, curBrightness, maxBrightness;
HWND curWin = GetConsoleWindow();
if (curWin == NULL) {
std::cout << "Problem getting a handle to the window." << std::endl;
return 1;
}
// Call MonitorFromWindow to get the HMONITOR handle
HMONITOR curMon = MonitorFromWindow(curWin, MONITOR_DEFAULTTONULL);
if (curMon == NULL) {
std::cout << "Problem getting the display monitor" << std::endl;
return 1;
}
// Call GetNumberOfPhysicalMonitorsFromHMONITOR to get the needed array size
DWORD monitorCount;
if (!GetNumberOfPhysicalMonitorsFromHMONITOR(curMon, &monitorCount)) {
std::cout << "Problem getting the number of physical monitors" << std::endl;
return 1;
}
// Call GetPhysicalMonitorsFromHMONITOR to get a handle to the physical monitor
LPPHYSICAL_MONITOR physicalMonitors = (LPPHYSICAL_MONITOR)malloc(monitorCount*sizeof(PHYSICAL_MONITOR));
if (physicalMonitors == NULL) {
std::cout << "Unable to malloc the physical monitor array." << std::endl;
return 1;
}
if (!GetPhysicalMonitorsFromHMONITOR(curMon, monitorCount, physicalMonitors)) {
std::cout << "Problem getting the physical monitors." << std::endl;
return 1;
}
std::cout << "Num Monitors: " << monitorCount << std::endl; // This prints '1' as expected.
wprintf(L"%s\n", physicalMonitors[0].szPhysicalMonitorDescription); // This prints "Generic PnP Monitor" as expected
// Call GetMonitorCapabilities to find out which functions it supports
DWORD monCaps;
DWORD monColorTemps;
// The following function call fails with the error "An error occurred while transmitting data to the device on the I2C bus."
if (!GetMonitorCapabilities(physicalMonitors[0].hPhysicalMonitor, &monCaps, &monColorTemps)) {
std::cout << "Problem getting the monitor's capabilities." << std::endl;
DWORD errNum = GetLastError();
DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
LPVOID buffer;
FormatMessage(flags, NULL, errNum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&buffer, 0, NULL);
wprintf(L"%s\n", buffer);
return 1;
}
// Same error when I use GetCapabilitiesStringLength(...) here.
// More code that is currently never reached...
return 0;
}
Edit: Also I should note that physicalMonitors[0].hPhysicalMonitor is 0, even though the monitor count and text description are valid and the GetPhysicalMonitorsFromHMONITOR function returns successfully. Any thoughts on why this might be?
This is a "wonky hardware" problem, the I2C bus it talks about is the logical interconnect between the video adapter and the display monitor. Primarily useful for plug & play. Underlying error code is 0xC01E0582, STATUS_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA. It is generated by a the DxgkDdiI2CTransmitDataToDisplay() helper function in the video miniport driver. It is the vendor's video driver job to configure it, providing the functions that tickle the bus and to implement the IOCTL underlying GetMonitorCapabilities().
Clearly you are device driver land here, there isn't anything you can do about this failure in your C++ program. You can randomly spin the wheel of fortune by looking for a driver update from the video adapter manufacturer. But non-zero odds that the monitor is at fault here. Try another one first.
I know its bad time to reply but i thought you should know.
The problem you are facing is because of the DDC/CI disabled on your monitor so you should go to the monitor settings and check if DDC/CI is disabled and if it is, then you have to enable it and run your code again. It would work. If you were not able to find DDC/CI option ( some of the monitor have a separate button for enabling/disabling the DDC/CI like the Benq's T71W monitor has a separate down arrow button to enable/disable DDC/CI ) then you should refer to your monitor's manual or contact the manufacturer.
Hope that helps. and sorry for late reply.
Best of luck. :)
As I read the original question, the poster wanted to control a laptop display using DDC/CI. Laptop displays do not support DDC/CI. They provide a stripped down I2C bus sufficient to read the EDID at slave address x50, but that's it.

Qt Creator crashes when using multiple threads

I'm writing a Qt (5.3) program which has a joystick test UI in it, but I need a separate thread for an infinite while loop looking for joystick axis/button value changes through SDL. That part of the code is working fine as I can have the thread qDebug() messages and it seems to work. But from the main window, when I try to open the test joystick UI, the program crashes. I've had the test joystick UI running separation WITHOUT the JoystickThread thread and it seems to open up fine.
The error messages are inconsistent though - some times, I just get
The program has unexpectedly finished.
/home/narendran/QtWorkspace/build-LinkControl-Desktop-Debug/LinkControl crashed
This has shown up once:
QXcbWindow: Unhandled client message: "_GTK_LOAD_ICONTHEMES"
And a few other times:
[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
star: ../../src/xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
I found that this was common if XInitThreads(); is not run in the main function, but even with it on there, it crashes with the same error(s).
main.cpp
#include <qsplashscreen.h>
#include "linkcontrol.h"
#include "configure.h"
#include <unistd.h>
#include <QApplication>
#include <QPixmap>
#include <QStyle>
#include <QDesktopWidget>
#include "linkports.h"
#include "joystickthread.h"
#include <X11/Xlib.h>
int main(int argc, char *argv[])
{
XInitThreads();
QApplication a(argc, argv);
QPixmap pix(":splash.png");
QSplashScreen splash(pix);
splash.show();
a.processEvents();
JoystickThread jsThread;
jsThread.start();
LinkControl linkcontrol;
usleep(1000000);
splash.finish(&linkcontrol);
usleep(100000);
linkcontrol.show();
linkcontrol.setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter,linkcontrol.size(),a.desktop()->availableGeometry()));
return a.exec();
}
The actual thread is in joystickthread.cpp
#include "joystickthread.h"
#include "global.h"
#include "unistd.h"
/* JoystickThread::JoystickThread(int _interval)
{
this->interval_us = _interval;
} */
void JoystickThread::run()
{
while(1)
{
if(joystick->connected)
{
joystick->updateJSData();
// Check for changed values
for(int i=0; i<joystick->axis.count(); i++)
{
if(joystick->axis.value(i) != joystick->axis_last[i])
{
joystick->axisUpdateEmit(i);
// qDebug() << "AXIS: " << i << "\tVALUE: " << joystick->axis.value(i);
}
joystick->axis_last[i] = joystick->axis.value(i);
}
for(int i=0; i<joystick->button.count(); i++)
{
if(joystick->button.value(i) != joystick->button_last[i])
{
joystick->btnUpdateEmit(i);
// qDebug() << "BUTTON: " << i << "\tVALUE: " << joystick->button.value(i);
}
joystick->button_last[i] = joystick->button.value(i);
}
}
usleep(2500);
}
}
The function that causes the program to crash is in linkcontrol.cpp
void LinkControl::on_actionJoystick_Test_triggered()
{
qDebug() << "STARTING CHECK";
if(!js_test->initialized) {
qDebug() << "NOT INIT";
js_test = new TestJoystick();
js_test->initialized = true;
qDebug() << "FININSH INIT";
}
if(joystick->connected) {
qDebug() << "SHOWING UI";
js_test->show();
} else {
QMessageBox::critical(this, tr("No Joystick Connected!"), tr("Please connect a joystick first..."));
}
}
Where js_test is declared as a TestJoystick object in the linkcontrol.h file
public:
explicit LinkControl(QWidget *parent = 0);
QSlider *portSliders[16];
QLineEdit *setVals[16];
SerialTerminal *ser_term;
TestJoystick *js_test;
~LinkControl();
Thank you very much! Please let me know if you need anymore information.
QThreads are a little tricky to get used to initially, and have their share of gotchas.
You should construct and connect appropriate items at the top of your run function.
If you do it other places, you need to make sure that you don't use Qt::AutoConnection, but instead use Qt:QueuedConnection.
http://qt-project.org/doc/qt-5/qt.html#ConnectionType-enum
Certain elements are only accessible from the "GUI" thread or the main thread of the program. This is the thread that has QApplication::exec(); ran on. It has an event loop that propagates messages around.
Look at the Application output for runtime errors that Qt will tell you about.
When crossing thread boundaries, be sure to use signals and slots.
And if you are accessing a member of your thread class from outside that thread, be sure to use thread synchronization, practices, such as prefacing all access to these members with QMutexLocker locker(m_mutex);.
http://qt-project.org/doc/qt-5/threads.html
And as implied by the title "GUI thread", it is the only thread that is allowed to do certain things such as drawing QPixmaps and accessing certain parts of QWidgets.
Hope that helps.

modbus communication decrease wait time to timeout

I'm writing a C++ app that will need to connect to various PLCs over modbus, the IPs of these PLCs is given by user input. Currently when the user puts in an IP that cannot be connected to, my program hangs for around 2 minutes in an attempt to connect and having my app hang for 2 minutes is not an option.
An example program illustrates the issue and my attempted fixes:
#include <modbus/modbus.h>
#include <string>
#include <errno.h>
#include <iostream>
#define PRINT_TIMEVAL(timeval) std::cout << "timeval sec: " << timeval.tv_sec << " usec: " << timeval.tv_usec << std::endl;
int main()
{
std::string ip = "192.168.2.5";
int port = 502;
int slaveNum = 1;
int address = 1;
int nb = 1;
struct timeval currentTimeout;
struct timeval responseTimeout;
responseTimeout.tv_sec = 1;
responseTimeout.tv_usec = 0;
struct timeval byteTimeout;
byteTimeout.tv_sec = 1;
byteTimeout.tv_usec = 0;
modbus_t *mb = modbus_new_tcp(ip.c_str(), port);
modbus_set_debug(mb, true);
modbus_set_error_recovery(mb, MODBUS_ERROR_RECOVERY_NONE);
modbus_flush(mb);
modbus_set_slave(mb, slaveNum);
modbus_get_response_timeout(mb, &currentTimeout);
PRINT_TIMEVAL(currentTimeout);
modbus_set_response_timeout(mb, &responseTimeout);
modbus_get_response_timeout(mb, &currentTimeout);
PRINT_TIMEVAL(currentTimeout);
modbus_get_byte_timeout(mb, &currentTimeout);
PRINT_TIMEVAL(currentTimeout);
modbus_set_byte_timeout(mb, &byteTimeout);
modbus_get_byte_timeout(mb, &currentTimeout);
PRINT_TIMEVAL(currentTimeout);
std::cout << "About to connect to " << ip << std::endl;
int errno;
if((errno = modbus_connect(mb)))
{
std::cout << "Error when connecting: " << modbus_strerror(errno) << std::endl;
}
std::cout << "Done connecting to " << ip << std::endl;
modbus_close(mb);
modbus_free(mb);
return 0;
}
As you can see I've tried setting both the response and byte timeout variables to 1 second (I've also tried 500 and 5000 microseconds). When I read the timeout values they have been set properly so I'm assuming that they don't have anything to do with the initial connection attempt. I've also tried explicitly setting the error recovery mode to none in case it was trying to reconnect on its own.
I would like something that will either stop modbus_connect after x amount of time or another command that will allow me to check to see if the IP is valid before attempting to connect through modbus, this would also need to timeout after a short amount of time.
I'm using libmodbus version 3.0.1-2
The issue was with my version of libmodbus (3.0.1), which is the current release version. In that version they were using the linux connect command but they weren't passing a NONBLOCKING flag, thus connect would become blocked for 2m7s. We resolved this issue by upgrading to libmodbus v3.1.1 which is marked as unstable but is not under active development (they're developing on v3.1.2). Unfortunately that version of libmodbus does not work for windows.
Use threads to listen for each device and push those messages into a queue that can be processed without holding up the other threads.