tags:

views:

3685

answers:

6

Hello, is it possible, in C++, to get the current RAM and CPU usage? Is there a platform-indepentent function call?

Thank you.

+5  A: 

No, there isn't, not in the standard.

If you truly need this information, you will have to write platform-specific #ifdefs or link against a library that provides it.

HUAGHAGUAH
+12  A: 

Sadly these things rely heavily on the underlying OS, so there are no platform-independent calls. (Maybe there are some wrapper frameworks, but I don't know of any.)

On Linux you could have a look at the getrusage() function call, on Windows you can use GetProcessMemoryInfo() for RAM Usage. Have also a look at the other functions in the Process Status API of Windows.

Kosi2801
Why is this sad? The sheer variety of CPU/RAM/NUMA/(insert one or more acronyms here) makes a platform independent reporting mechanism somewhat limited.
MSN
+2  A: 

There is not a platform independent function for this that I know of. IF you plan to target multiple versions of Windows be aware that the implementation differs across some versions. I hit this problem when testing an app under NT 3.51 for instance... (archaic, I know).

Here is some code I used for the memory side of things. This doesn't work across platforms other than windows, and will just return 0 when compiled without the WIN32 define:

EDIT: I forgot to mention, this code divides and rounds down to the nearest MB, hence the >> 20 all over the place.

// get memory info...
int getTotalRAM()
{
    int ret = 0;
#ifdef WIN32
    DWORD v = GetVersion();
    DWORD major =  (DWORD)(LOBYTE(LOWORD(v)));
    DWORD minor =  (DWORD)(HIBYTE(LOWORD(v)));
    DWORD build;
    if (v < 0x80000000) build = (DWORD)(HIWORD(v));
    else build = 0;

    // because compiler static links the function...
    BOOL (__stdcall*GMSEx)(LPMEMORYSTATUSEX) = 0;

    HINSTANCE hIL = LoadLibrary(L"kernel32.dll");
    GMSEx = (BOOL(__stdcall*)(LPMEMORYSTATUSEX))GetProcAddress(hIL, "GlobalMemoryStatusEx");

    if(GMSEx)
    {
     MEMORYSTATUSEX m;
     m.dwLength = sizeof(m);
     if(GMSEx(&m))
     {
      ret = (int)(m.ullTotalPhys>>20);
     }
    }
    else
    {
     MEMORYSTATUS m;
     m.dwLength = sizeof(m);
     GlobalMemoryStatus(&m);
     ret = (int)(m.dwTotalPhys>>20);
    }
#endif
    return ret;
}

int getAvailRAM()
{
    int ret = 0;
#ifdef WIN32
    DWORD v = GetVersion();
    DWORD major =  (DWORD)(LOBYTE(LOWORD(v)));
    DWORD minor =  (DWORD)(HIBYTE(LOWORD(v)));
    DWORD build;
    if (v < 0x80000000) build = (DWORD)(HIWORD(v));
    else build = 0;

    // because compiler static links the function...
    BOOL (__stdcall*GMSEx)(LPMEMORYSTATUSEX) = 0;

    HINSTANCE hIL = LoadLibrary(L"kernel32.dll");
    GMSEx = (BOOL(__stdcall*)(LPMEMORYSTATUSEX))GetProcAddress(hIL, "GlobalMemoryStatusEx");

    if(GMSEx)
    {
     MEMORYSTATUSEX m;
     m.dwLength = sizeof(m);
     if(GMSEx(&m))
     {
      ret = (int)(m.ullAvailPhys>>20);
     }
    }
    else
    {
     MEMORYSTATUS m;
     m.dwLength = sizeof(m);
     GlobalMemoryStatus(&m);
     ret = (int)(m.dwAvailPhys>>20);
    }
#endif
    return ret;
}

int getTotalMemory()
{
    int ret = 0;
#ifdef WIN32
    DWORD v = GetVersion();
    DWORD major =  (DWORD)(LOBYTE(LOWORD(v)));
    DWORD minor =  (DWORD)(HIBYTE(LOWORD(v)));
    DWORD build;
    if (v < 0x80000000) build = (DWORD)(HIWORD(v));
    else build = 0;

    // because compiler static links the function...
    BOOL (__stdcall*GMSEx)(LPMEMORYSTATUSEX) = 0;

    HINSTANCE hIL = LoadLibrary(L"kernel32.dll");
    GMSEx = (BOOL(__stdcall*)(LPMEMORYSTATUSEX))GetProcAddress(hIL, "GlobalMemoryStatusEx");

    if(GMSEx)
    {
     MEMORYSTATUSEX m;
     m.dwLength = sizeof(m);
     if(GMSEx(&m))
     {
      ret = (int)(m.ullTotalPhys>>20) + (int)(m.ullTotalVirtual>>20);
     }
    }
    else
    {
     MEMORYSTATUS m;
     m.dwLength = sizeof(m);
     GlobalMemoryStatus(&m);
     ret = (int)(m.dwTotalPhys>>20) + (int)(m.dwTotalVirtual>>20);
    }
#endif
    return ret;
}

int getAvailMemory()
{
    int ret = 0;
#ifdef WIN32
    DWORD v = GetVersion();
    DWORD major =  (DWORD)(LOBYTE(LOWORD(v)));
    DWORD minor =  (DWORD)(HIBYTE(LOWORD(v)));
    DWORD build;
    if (v < 0x80000000) build = (DWORD)(HIWORD(v));
    else build = 0;

    // because compiler static links the function...
    BOOL (__stdcall*GMSEx)(LPMEMORYSTATUSEX) = 0;

    HINSTANCE hIL = LoadLibrary(L"kernel32.dll");
    GMSEx = (BOOL(__stdcall*)(LPMEMORYSTATUSEX))GetProcAddress(hIL, "GlobalMemoryStatusEx");

    if(GMSEx)
    {
     MEMORYSTATUSEX m;
     m.dwLength = sizeof(m);
     if(GMSEx(&m))
     {
      ret = (int)(m.ullAvailPhys>>20) + (int)(m.ullAvailVirtual>>20);
     }
    }
    else
    {
     MEMORYSTATUS m;
     m.dwLength = sizeof(m);
     GlobalMemoryStatus(&m);
     ret = (int)(m.dwAvailPhys>>20) + (int)(m.dwAvailVirtual>>20);
    }
#endif
    return ret;
}
jheriko
A: 

Not directly.

But you can use a library that abstracts the OS (such as ACE).
Though this might by a bit heavy if you just want CPU and Memory.

Martin York
A: 

There is no platform independent way to do this. Although for windows, you can get the CPU usage and performance metrics by using PDH.dll(Performance Data Helper) and its related APIs in your code.

Here's more on how to use it.

Samrat Patil
A: 

There is an open source library that gives these (and more system info stuff) across many platforms: SIGAR API

I've used it in fairly large projects and it works fine (except for certain corner cases on OS X etc.)

ididak