How to retrieve total system CPU usage from Windows in C++? - c++

I need to retrieve total CPU usage on the fly for a feedback system to change the behavior based on whether CPU is getting throttled or not. For this, I looked into NtQuerySystemInformation sys call which provides system information at any given time but it seems like this function has been deprecated in the latest versions of Windows since MSDN page says
[NtQuerySystemInformation may be altered or unavailable in future
versions of Windows. Applications should use the alternate functions
listed in this topic.]
Reference: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724509(v=vs.85).aspx
Does anyone know what OS versions this call is supported on? Win 7/8/8.1/10? Is there any other way to directly retrieve total CPU usage?

Officaially, there are two functions are in the MSDN.
GetSystemTimes(): It looks more easier but posted a long time ago.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724400(v=vs.85).aspx
GetSystemInfo() : I've got the sample code from https://code.msdn.microsoft.com/windowsdesktop/Use-PerformanceCounter-to-272d57a1
DWORD GetProcessorCount()
{
SYSTEM_INFO sysinfo;
DWORD dwNumberOfProcessors;
GetSystemInfo(&sysinfo);
dwNumberOfProcessors = sysinfo.dwNumberOfProcessors;
return dwNumberOfProcessors;
}
vector<PCTSTR> GetValidCounterNames()
{
vector<PCTSTR> validCounterNames;
DWORD dwNumberOfProcessors = GetProcessorCount();
DWORD index;
vector<PCTSTR> vszProcessNames;
TCHAR * szCounterName;
validCounterNames.push_back(TEXT("\\Processor(_Total)\\% Processor Time"));
validCounterNames.push_back(TEXT("\\Processor(_Total)\\% Idle Time"));
// skip some codes
return validCounterNames;
}
Good Luck !
In my opinion, Windows command "tasklist /v " will show the CPU TIME and MEMORY from the OS and you can call the command through 'system' or other functions.
PS. I still think looking at the OS side is the best way for monitoring CPU usage. (If I use the function, it will also do the same thing inside.)

Related

Accessing Max Input Delay with C++ on Windows

I am having trouble obtaining certain data from Windows Performance Counters with C++. I will preface my question by stating that I am new to both C++ and to developing for Windows, but I have spent some time on this issue already so I feel familiar with the concepts I am discussing here.
Question:
How do I use Windows PDH (Performance Data Helper) C++ to obtain Max Input Delay--either per session or per process? Are there certain Performance Counters that are not available outside of perfmon?
Progress so far:
I have used this example to log some Performance Counters successfully, but the ones I want produce the error code 0xC0000BB8: "The specified object is not found on the system." This confuses me because I can access the objects--"User Input Delay per Process" or "User Input Delay per Session"--fine through perfmon. I even went as far as enabling the counter in the registry as outlined in the article I linked in my question, despite being on a build of Windows 10 that should have it enabled by default. I had to make a small change to get the code to compile, but I have changed only the definition of COUNTER_PATH during my testing because, again, the code works as advertised except when it comes to the counter I want to access. Specifically:
Does not compile:
CONST PWSTR COUNTER_PATH = L"\\Processor(0)\\% Processor Time";
Does compile and log:
CONST wchar_t *COUNTER_PATH = L"\\Processor(0)\\% Processor Timee";
OR
CONST PWSTR COUNTER_PATH = const_cast<PWSTR>(TEXT( "\\Processor(0)\\% Processor Time" ));
Compiles, but throws error code 0xC0000BB8 at runtime (This is the Counter I want to access):
CONST PWSTR COUNTER_PATH = const_cast<PWSTR>(TEXT( "\\User Input Delay per Session(1)\\Max Input Delay" ));
The hardcoded session ID of 1 in the string was for troubleshooting purposes, but wildcard (*) and 0 were also used with the same result. The counter path matches that shown in perfmon.
Essentially, all Performance Counters that I have attempted to access with this code--about 5 completely different ones--have successfully logged the data being requested, but the one I want to access continues to be evasive.
I asked this same question on Microsoft Q&A and received the answer:
The Performance Counters in question require administrator privileges to access. All I had to do was run this program in administrator command prompt, and that solved my issue.

Can a process be limited on how much physical memory it uses?

I'm working on an application, which has the tendency to use excessive amounts of memory, so I'd like to reduce this.
I know this is possible for a Java program, by adding a Maximum heap size parameter during startup of the Java program (e.g. java.exe ... -Xmx4g), but here I'm dealing with an executable on a Windows-10 system, so this is not applicable.
The title of this post refers to this URL, which mentions a way to do this, but which also states:
Maximum Working Set. Indicates the maximum amount of working set assigned to the process. However, this number is ignored by Windows unless a hard limit has been configured for the process by a resource management application.
Meanwhile I can confirm that the following lines of code indeed don't have any impact on the memory usage of my program:
HANDLE h_jobObject = CreateJobObject(NULL, L"Jobobject");
if (!AssignProcessToJobObject(h_jobObject, OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId())))
{
throw "COULD NOT ASSIGN SELF TO JOB OBJECT!:";
}
JOBOBJECT_EXTENDED_LIMIT_INFORMATION tagJobBase = { 0 };
tagJobBase.BasicLimitInformation.MaximumWorkingSetSize = 1; // far too small, just to see what happens
BOOL bSuc = SetInformationJobObject(h_jobObject, JobObjectExtendedLimitInformation, (LPVOID)&tagJobBase, sizeof(tagJobBase));
=> bSuc is true, or is there anything else I should expect?
In top of this, the mentioned tools (resource managed applications, like Hyper-V) seem not to work on my Windows-10 system.
Next to this, there seems to be another post about this subject "Is there any way to force the WorkingSet of a process to be 1GB in C++?", but here the results seem to be negative too.
For a good understanding: I'm working in C++, so the solution, proposed in this URL are not applicable.
So now I'm stuck with the simple question: is there a way, implementable in C++, to limit the memory usage of the current process, running on Windows-10?
Does anybody have an idea?
Thanks in advance

Retrieve RAM info on a Mac?

I need to retrieve the total amount of RAM present in a system and the total RAM currently being used, so I can calculate a percentage. This is similar to: Retrieve system information on MacOS X?
However, in that question the best answer suggests how to get RAM by reading from:
/usr/bin/vm_stat
Due to the nature of my program, I found out that I am not cannot read from that file - I require a method that will provide me RAM info without simply opening a file and reading from it. I am looking for something to do with function calls. Something like this preferably : getTotalRam() and getRamInUse().
I obviously do not expect it to be that simple but I was looking for a solution other than reading from a file.
I am running Mac OS X Snow Leopard, but would preferably get a solution that would work across all current Mac OS X Platforms (i.e. Lion).
Solutions can be in C++, C or Obj-C, however C++ would the best possible solution in my case so if possible please try to provide it in C++.
Getting the machine's physical memory is simple with sysctl:
int mib [] = { CTL_HW, HW_MEMSIZE };
int64_t value = 0;
size_t length = sizeof(value);
if(-1 == sysctl(mib, 2, &value, &length, NULL, 0))
// An error occurred
// Physical memory is now in value
VM stats are only slightly trickier:
mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
vm_statistics_data_t vmstat;
if(KERN_SUCCESS != host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat, &count))
// An error occurred
You can then use the data in vmstat to get the information you'd like:
double total = vmstat.wire_count + vmstat.active_count + vmstat.inactive_count + vmstat.free_count;
double wired = vmstat.wire_count / total;
double active = vmstat.active_count / total;
double inactive = vmstat.inactive_count / total;
double free = vmstat.free_count / total;
There is also a 64-bit version of the interface.
You're not supposed to read from /usr/bin/vm_stat, rather you're supposed to run it; it is a program. Look at the first four lines of output
Pages free: 1880145.
Pages active: 49962.
Pages inactive: 43609.
Pages wired down: 123353.
Add the numbers in the right column and multiple by the system page size (as returned by getpagesize()) and you get the total amount of physical memory in the system in bytes.
vm_stat isn't setuid on Mac OS, so I assume there is a non-privileged API somewhere to access this information and that vm_stat is using it. But I don't know what that interface is.
You can figure out the answer to this question by looking at the source of the top command. You can download the source from http://opensource.apple.com/. The 10.7.2 source is available as an archive here or in browsable form here. I recommend downloading the archive and opening top.xcodeproj so you can use Xcode to find definitions (command-clicking in Xcode is very useful).
The top command displays physical memory (RAM) numbers after the label "PhysMem". Searching the project for that string, we find it in the function update_physmem in globalstats.c. It computes the used and free memory numbers from the vm_stat member of struct libtop_tsamp_t.
You can command-click on "vm_stat" to find its declaration as a membor of libtop_tsamp_t in libtop.h. It is declared as type vm_statistics_data_t. Command-clicking that jumps to its definition in /usr/include/mach/vm_statistics.h.
Searching the project for "vm_stat", we find that it is filled in by function libtop_tsamp_update_vm_stats in libtop.c:
mach_msg_type_number_t count = sizeof(tsamp->vm_stat) / sizeof(natural_t);
kr = host_statistics(libtop_port, HOST_VM_INFO, (host_info_t)&tsamp->vm_stat, &count);
if (kr != KERN_SUCCESS) {
return kr;
}
You will need to figure out how libtop_port is set if you want to call host_statistics. I'm sure you can figure that out for yourself.
It's been 4 years but I just wanted to add some extra info on calculating total RAM.
To get the total RAM, we should also consider Pages occupied by compressor and Pages speculative in addition to Kyle Jones answer.
You can check out this post for where the problem occurs.

C stat() and daylight savings

I'm having serious trouble with the function stat(). I have an application compiled under cygwin ond Windows 7 and the same app compiled with MSVC++ on Windows 7. The app contains the following code:
struct stat stb;
memset( &stb, 0, sizeof( stb ) );
stat( szPath, &stb );
cout << hex << uppercase << setw(8) << stb.st_mtime << endl;
szPath is a path to a file. The file does not get modified in any way by the app. The problem is, that i get different results for some files. For example:
cygwin version: 40216D72
MSVC++ version: 40217B82
The difference is always E10 = 3600 = 1 hour
By using google, i found this, which seems to be exactly the same issue i'm seeing. Is there a portable way how to fix this? I cannot use any WinAPI calls. The most simple and reliable solution is what i'm looking for, but if it needs to be complicated, so be it. Reliability and portability (win + linux) is the most important thing here.
To obtain both reliability and portability here (or in most situations of this sort where two platforms do different things with what should be the "same" code), you will probably need to use some form of target-dependent code, like:
#ifdef _MSC_VER
// do MSVC++-specific code
#else
// do Linux/Cygwin/generic code
#endif
You then ought to be able to use WinAPI calls in the _MSC_VER section, because that will only be compiled when you're using MSVC++
Apparently per http://support.microsoft.com/kb/190315 this is actually a FEATURE although it really seems like a bug to me. They say you can work around it by clearing "Automatically adjust clock for daylight saving changes" in the Date/Time Properties dialog box for the system clock.
If you have the date of the file, you can use the relative state of dst to determine if you need to make a one-hour adjustment yourself in MSVC only, but that's hacky as well.
Not sure about the functions you are using but I do know that Windows and Linux use the system clock differently. Windows stores local time (including DST) on the system clock. Linux (at least traditionally) stores GMT (or UTC to be precise) on the system clock. I don't if this applies to cygwin.
If a linux system shares hardware with windows it needs to be configured to use the system clock like windows or get messed-up every time windows adjusts DST.

How to Find CPU Utilization of a Single Thread within a Process

I am looking a Tool on How to Find CPU Utilization of a Single Thread within a Process in VC++.
It would be great full if any one could provide me a tool.
Also it could be better if you guys provide how to do programmatically.
Thank you in Advance.
Perhaps using GetThreadTimes would help ?
To elaborate if the thread belongs to another executable, that would be something (not tested) in the lines of:
// Returns true if thread times could be queried and its results are usable,
// false otherwise. Error handling is minimal, considering throwing detailed
// exceptions instead of returning a simple boolean.
bool get_remote_thread_times(DWORD thread_id, FILETIME & kernel_time, FILETIME & user_time)
{
FILETIME creation_time = { 0 };
FILETIME exit_time = { 0 };
HANDLE thread_handle = OpenThread(THREAD_QUERY_INFORMATION, FALSE, thread_id);
if (thread_handle == INVALID_HANDLE) return false;
bool success = GetThreadTimes(thread_handle, &creation_time, &exit_time, &kernel_time, &user_time) != 0;
CloseHandle(thread_handle);
return success;
}
try using process explorer.. (tool).. pretty useful..
http://download.cnet.com/Process-Explorer/3000-2094_4-10223605.html
I'm sure you're asking about Windows here, but for completeness sake, I'll describe one way this can be done on Unix systems.
The /proc file system contains information about all of the running processes on your machine. In this directory you'll find sub directory's for every process on the system (named by pid), inside each of these directory's is a file called stat. Look at 'man proc' and search for the "stat" entry. This file contains a bunch of information, but a couple of the fields can be used to determine how much user and kernel mode time this process has consumed.
With this knowledge in hand, look for a sub directory of a process called "task"... In here you'll find all the child processes spawned by the outer process.. and if you cd into those, you'll find that each has a stat file.