Link to home
Start Free TrialLog in
Avatar of blitz051697
blitz051697

asked on

Way to get system resource percentages%

We are experiencing a problem on 98. We believe it is related to
resources.   What is the best way to check for available resources
on 95/98 and NT?  Is there an API call that will work under
both environments?
Avatar of Madshi
Madshi

What kind of resources do you mean? Do you mean the kernel/user/gdi resources? These kind of resources only exist under win9x. Is that what you need?

Regards, Madshi.
Of course these resources exist under winNT, too - but they are not restricted there...   :-)
For memory utilization call GlobalMemoryStatus.

Ciao, Mike
Avatar of blitz051697

ASKER

Yes. GDI, User.

I realize that NT doesn't have this restriction but I just want a single method that will work on both and not blow up under NT. I don't care if it returns 0 under NT.
I have an example of GlobalMemorystatus on my website:

http://www.drdelphi.com/delphi/right/tips/globalmem.htm

Good luck!!
That's fine but it does not appear to give me GDI and USER resources.
Here comes the answer. The code is a bit ugly, because the API is hidden in a 16 bit dll, so we need to use thunking...   :-(

interface

type TSysResources = (srSystem, srGdi, srUser);
function GetFreeSystemResources (res: TSysResources) : cardinal;
// returns the free system resources in %
// example:
// if GetFreeSystemResources(srSystem) < 80 then ...

implementation

function LoadLibrary16 (libraryName: PChar) : dword; stdcall;
         external kernel32 index 35;
function FreeLibrary16 (hInstance: dword) : integer; stdcall;
         external kernel32 index 36;
function GetProcAddress16 (hinstance: dword; procName: PChar) : pointer; stdcall;
         external kernel32 index 37;

// function GetFreeSystemResources(sysResource: word) : word; stdcall;
function _GetFreeSystemResources(SysResource: word) : word;
var thunkTrash : array [0..$20] of word;
    fp,qfp     : pointer;
    huser16    : cardinal;
begin
  result:=0;
  huser16:=LoadLibrary16('user.exe');
  if huser16<>0 then
    try
      thunkTrash[0]:=huser16;
      fp:=GetProcAddress16(huser16, 'GetFreeSystemResources');
      qfp:=GetProcAddress(GetModuleHandle(kernel32), 'QT_Thunk');
      if (fp<>nil) and (qfp<>nil) then
        asm
          push SysResource
          mov edx, fp
          call qfp
          mov result, ax
        end;
    finally FreeLibrary16(huser16) end;
end;

Regards, Madshi.

(BTW, it DOES return 0 under winNT..  :-)
It looks good but I can't get it to compile.  Am I missing something.  Can you send me a working example?  My email is Randy_michak@usiva.com
ASKER CERTIFIED SOLUTION
Avatar of jimburns
jimburns

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Well, I could only send you the same that I posted here. It compiles perfectly under D4 and D5 and should compile under D2 and D3, too.
Tell me what your compiler complains about...
Basically I copied the entire code section to a new pas file and it looks like the declaration of GetFreeSystemResources does not match the implementation.  There is a _GetFreeSystemResources method that I assume was a mistake so I removed the '-' and it kept giving me compile errors.
Oooooooooooooooooooooops... I'm sorry... It was my mistake. I've forgotten to copy this few lines:
Place them below that other code...

function GetFreeSystemResources(res: TSysResources) : cardinal;
begin
  result:=_GetFreeSystemResources(ord(res));
end;

Regards, Madshi.
Basically I copied the entire code section to a new pas file and it looks like the declaration of GetFreeSystemResources does not match the implementation.  There is a _GetFreeSystemResources method that I assume was a mistake so I removed the '-' and it kept giving me compile errors.
Yeah I figured something was missing so I went back and make a couple changes and got it working.  I just had never done any thunking before and wasn't sure if things were a certain way for a reason or not.  But it works.


Hey - blitz!!!!!

You accepted the WRONG answer!!!   :-((

Please write to customer service forum to change this...
I agree that you certainly may have accepted the wrong answer, but consider carefully.  I don't recommend the thunk to the 16 but dll.  GetFreeSystemResources is dead, MS recomends against it and using it in the future cannot be guaranteed.  Also, in the future what it returns can not even be guaranteed to be correct.  Look up GetDiskFreeSpace for a related discussion on how legacy calls can return incorrect either because variables to hold the information are too small (remember a 16 bit value holds 65535 max and while memory sizes are not quite up to the same large numbers as disk sizes, with virtual memory you will find memory sized returned in the Gigabytes), or because windows fiddles with the results before returning them to you.

As your original question states, you are experiencing a problem on Win98 and you believe resources are the issue.  What I submitted is all you need to take a look at the system memory resources, including memory load percentage and percentage of each type of memory.  The User/GDI issue came in later, and is really not necessary.

Your call.  Enjoy!

:)
That was 16-bit dll... ;)
No no, Jim, I'm sorry, but that's not right. Microsoft *tries* to tell everyone that the resource issue is dead in 32bit Windows. But that's not true!!!!! You can read that in each and every technical article that goes a bit deeper. The memory resources are not so important, since they are not really restricted. But the resources ARE still restricted. You don't believe that? Then go to "Control Panel"->"System"->Last Panel->system resources. Here you see exactly what blitz wanted to know. And thunking is the only way to get these kind of resource meter.
We've had several problems with these kind of resources with our programs in our firm, you can really believe me, it is NOT dead in win9x. It is dead in winNT, but not in win9x.
Try to run this one:

  for i1 := 0 to 100000 do
    OpenProcess(PROCESS_ALL_ACCESS, true, GetCurrerntProcessID);

Then you'll see that the resource issue is still there...   :-(

The only reason why Microsoft invented ImageLists is the GDI resource problem under win9x.
If your programs uses a lot of speedbuttons with bitmaps on it and you use a TBitmap for each bitmap (instead of a TImageList), then you'll bring win9x systems to its knees.
I concur with Madshi.  I don't know of another way to do this. All I know is that my app starts acting flakey on 98 and 95 when the resources get below 20%.  

Madshi, I realized that I excepted the wrong answer a little too late. I'll contact customer service.  If that doesn't work then I'll just enter a new question for you to then anser.

Thanks again, blitz
Customer service has been contacted.... Stay tuned.
Madshi... No offense, but it would help if you payed slightly more attention to what's you're reading.  

I NEVER said resources were not an issue in Win32 and I agree that despite MS's attempt to make us believe they are not, the reality is the opposite.

But, you shouldn't be thunking down to a 16-bit dll and using system level services developed almost a decade ago in today's environment.  My comment was regarding that choice.  I find it amazing that you would respond in a way that demonstrates you completely failed to comprehend my message.  You didn't just miss the bulls-eye, you missed the target my friend.  

Let's just make sure we're paying attention!
Jim, you said:

"The User/GDI issue came in later, and is really not necessary."

The long comment I've written was the answer to that sentence. The User/GDI issue *IS VERY VERY* necessary, because it is normally the only resource problem win32 programs do have. You sounded (at least in this sentence) like you would be ignoring the resource issue completely - sorry, if I misunderstood you!!

Well, I don't like thunking at all - but what other choice do we have when we NEED that info? Well, you say: "Don't do that!". But what should we do in your opinion? Ignoring the resources?   :-)   All the other APIs give us only infos that don't help us at all, because they don't tell us anything about the User/GDI/System resources.
Perhaps you're asking *why* do we need to get these infos via API? Here comes the answer:
Our customers complained because sometimes their systems froze. So we looked at these problems and found that a printer driver was responsible for consuming all the resources.
So our main program (it is something like a OS extension) now checks for the system resources regularly and gives out a warning box like this:
"The system resources are under 20%. You should now reboot your system...".
That helped us (and our customers) a lot - at least with finding the reason for the problems.
Hi,

I have been directed to this question because points werwe awarded to the wrong expert.

I have posted a question in this topic area for Madshi to claim his/her points.

IanB
Community Support @ Experts Exchange