gabr42/OmniThreadLibrary

PostMessage related Quota error during peak machine latencies

Opened this issue · 0 comments

  • Windows 10.0.19044
  • Delphi 10.4 Version 27.0.40680.4203
  • OmniThreadLibrary-3.07.8
  • quad Ryzen 5 1500x with 32GB ram
  • Numerical application that often uses +32GB memory
  • using Parallel.ForEach<Integer>( ... ).NumTasks( System.CPUCount ).Execute( ...) api.
  • problem also occurs on a 32 core 128GB ryzen machine

I've noticed that once I get above 50% physical memory and hard faults begin to happen, ERROR_NOT_ENOUGH_QUOTA is thrown inside

procedure TOmniContainerWindowsMessageObserverImpl.PostWithRetry(msg: UINT;
wParam: WPARAM; lParam: LPARAM);
const
CInitialSleep = 1 {ms};
CSecondSleep = 5 {ms};
CMaxTries = 1000;
var
lasterr: cardinal;
retry : integer;
wait : integer;
begin
retry := 0;
wait := CInitialSleep;
while not PostMessage(cwmoHandle, msg, wParam, lParam) do begin
Inc(retry);
lasterr := GetLastError;
if (lasterr = ERROR_NOT_ENOUGH_QUOTA) and (retry < CMaxTries) then begin
Sleep(wait);
wait := CSecondSleep;
end
else
RaiseLastOSError(lasterr);
end;
end; { TOmniContainerWindowsMessageObserverImpl.PostWithRetry }

My working theory is that for the system to resolve the hard faults and allow the process message queues to drain the messaging process needs more sleep time, ie CSecondSleep needs to be longer (at least as long as a timeslice?) or CMaxTries needs to be bigger (which would just result in more busy waiting).

I've been able to address the issue for the moment by making CSecondSleep = 500. A better hack might be some form of Nagleing or a HardFault notification.

Possibly related: #63