Recent

Author Topic: unblocked Sleep() for all Platforms  (Read 3767 times)

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2007
  • Fifty shades of code.
    • Delphi & FreePascal
unblocked Sleep() for all Platforms
« on: August 27, 2022, 03:56:24 pm »
In Windows i do use this ->

Code: Pascal  [Select][+][-]
  1. procedure Sleep(const AMilliSeconds: DWORD);
  2. var
  3.   Ret: DWORD;
  4.   WaitTime: Int64;
  5.   Timer: THandle;
  6. begin
  7.   Timer := CreateWaitableTimer(nil, TRUE, nil);
  8.   WaitTime := Round((AMilliSeconds / 1000) * -10000000);
  9.   SetWaitableTimer(Timer, WaitTime, 0, nil, nil, FALSE);
  10.   repeat
  11.     Ret := MsgWaitForMultipleObjects(1, Timer, FALSE, INFINITE, QS_ALLINPUT);
  12.     if (Ret <> (WAIT_OBJECT_0+1)) then
  13.       Break;
  14.     Application.ProcessMessages;
  15.   until False;
  16.   if (Ret <> WAIT_OBJECT_0) then
  17.     CancelWaitableTimer(Timer);
  18.   CloseHandle(Timer);
  19. end;
  20.  
to temporarily suspend the workflow without that my application freeze or i do waste CPU.

Since i do use pure Windows Api calls to achieve that, how can i do the same for other OS's?


(I am sorry if i did posted in wrong sub-forum, please move this topic wherever it should be)

Maybe FPC/Lazarus has already something similar included?
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Red_prig

  • Full Member
  • ***
  • Posts: 143

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2007
  • Fifty shades of code.
    • Delphi & FreePascal
Re: unblocked Sleep() for all Platforms
« Reply #2 on: August 27, 2022, 04:16:03 pm »
https://www.freepascal.org/docs-html/rtl/sysutils/sleep.html

That is blocking. I do need unblocked version. (Application shall not freeze)
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Red_prig

  • Full Member
  • ***
  • Posts: 143
Re: unblocked Sleep() for all Platforms
« Reply #3 on: August 27, 2022, 04:17:39 pm »
There are definitely none

Red_prig

  • Full Member
  • ***
  • Posts: 143
Re: unblocked Sleep() for all Platforms
« Reply #4 on: August 27, 2022, 04:19:16 pm »
In principle you can use https://wiki.lazarus.freepascal.org/TTimer maybe this will work for you

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2007
  • Fifty shades of code.
    • Delphi & FreePascal
Re: unblocked Sleep() for all Platforms
« Reply #5 on: August 27, 2022, 04:27:44 pm »
In principle you can use https://wiki.lazarus.freepascal.org/TTimer maybe this will work for you
I do know about TTimer but that will not stop my workflow.

just exemplary...
Code: Pascal  [Select][+][-]
  1.   DoJob(); // start a method
  2.   Sleep(5000); // wait 5 seconds on this line of code without that app will be frozen
  3.   DoAnotherJob(); // start another method
  4.  
I hope that was more clear.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: unblocked Sleep() for all Platforms
« Reply #6 on: August 27, 2022, 04:28:33 pm »
That is blocking. I do need unblocked version. (Application shall not freeze)

Put the background computation in a separate thread.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Red_prig

  • Full Member
  • ***
  • Posts: 143
Re: unblocked Sleep() for all Platforms
« Reply #7 on: August 27, 2022, 04:34:50 pm »
Code: Pascal  [Select][+][-]
  1. DoJob(); // start a method
  2.  
  3. Timer1:=TTimer.Create;
  4. Timer1.Interval := 5000;
  5. Timer1.Enabled := True;
  6. Timer1.OnTimer := OnTimerCb;
  7. Exit;
  8.  
  9. //.........
  10.  
  11. procedure TForm1.OnTimerCb(Sender: TObject);
  12. begin
  13.  Timer1.Enabled := False;
  14.  DoAnotherJob(); // start another method
  15. end;
  16.  
  17.  

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2007
  • Fifty shades of code.
    • Delphi & FreePascal
Re: unblocked Sleep() for all Platforms
« Reply #8 on: August 27, 2022, 04:40:16 pm »
Ok, i still was not precise enough.

I do have a lot of sources/projects where i call my variant of Sleep() like the RTL is doing just without blocking.
I can not outsource following code into tthreads or create ttimers all over.

So what i actual mean is, i am a lazy guy that just likes to exchange my version with a CrossCompile version :)
I am really not looking for work-arounds.

Thank you for reading and your patience with me!
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Josh

  • Hero Member
  • *****
  • Posts: 1271
Re: unblocked Sleep() for all Platforms
« Reply #9 on: August 27, 2022, 05:15:20 pm »
not sure how cross platform, or how low cpu would be, not that accurate.

Code: Pascal  [Select][+][-]
  1. procedure WaitForInterval(msecs:Longint);
  2. var
  3.   currenttime,targettime,timetodelay:cardinal;
  4.   sleep_delay:integer=40; //delay before application.ProcessMessages called
  5. begin
  6.   currenttime:=DateTimeToTimeStamp(now).Time;
  7.   timetodelay:=currenttime;
  8.   targettime:=currenttime+msecs;
  9.   while currenttime<targettime do
  10.   begin
  11.     currenttime:=DateTimeToTimeStamp(now).Time;
  12.     if currenttime-timetodelay>Sleep_delay then
  13.     begin
  14.       application.ProcessMessages;  // keep alive
  15.       timetodelay:=currenttime;
  16.     end
  17.     else sleep(sleep_delay div 2); // go to sleep for 1/2 of sleep delay
  18.   end;
  19. end;    
« Last Edit: August 27, 2022, 05:21:19 pm by Josh »
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

rvk

  • Hero Member
  • *****
  • Posts: 6111
Re: unblocked Sleep() for all Platforms
« Reply #10 on: August 27, 2022, 05:45:20 pm »
Maybe just simply this...

Code: Pascal  [Select][+][-]
  1. procedure Delay(ms: DWORD);
  2. var
  3.   I: UInt64;
  4. begin
  5.   I := myGetTick64 + ms;
  6.   while I > myGetTick64 do
  7.   begin
  8.     Application.ProcessMessages;
  9.     Sleep(1);
  10.   end;
  11. end;
You can adjust the Sleep(1) to Sleep(10) if you want to.

Josh

  • Hero Member
  • *****
  • Posts: 1271
Re: unblocked Sleep() for all Platforms
« Reply #11 on: August 27, 2022, 06:18:04 pm »
Hi RVK,

do you mean GetTickCount64, or your own custom version  myGetTick64 ...

GetTickCount64 Windows >=Vista, i remember at one time in *nix the counter did not increase when in suspended, this may not be true now though, not on a machine with fpc/laz on it at the moment to test.
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

rvk

  • Hero Member
  • *****
  • Posts: 6111
Re: unblocked Sleep() for all Platforms
« Reply #12 on: August 27, 2022, 06:53:47 pm »
do you mean GetTickCount64, or your own custom version  myGetTick64 ...
GetTickCount64 Windows >=Vista, i remember at one time in *nix the counter did not increase when in suspended, this may not be true now though, not on a machine with fpc/laz on it at the moment to test.
Sorry, yes I mean GetTickCount64.
I have my own custom version of myGetTick64 because I still had Windows XP machines at my customers (although I think they are all replaced now).

Code: Pascal  [Select][+][-]
  1. procedure Delay(ms: DWORD);
  2. var
  3.   I: UInt64;
  4. begin
  5.   I := GetTickCount64 + ms;
  6.   while I > GetTickCount64 do
  7.   begin
  8.     Application.ProcessMessages;
  9.     Sleep(1);
  10.   end;
  11. end;

GetTickCount64 should always increase because it's based on the uptime of the machine and it's retrieved every time.
But even if GetTickCount64 doesn't increase during standby/machine suspension it wouldn't be a problem usually because with a Delay(5000) it really wouldn't matter much.

But don't do Delay(24 * 60 * 60 * 1000) for a sleep of 1 day because then, yes, it might not be that accurate.
In that case a different kind of alarm is better.
But my guess is that KodeZwerg is just asking for a Delay of a few seconds while it doesn't lock the OS and your own program.

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2007
  • Fifty shades of code.
    • Delphi & FreePascal
Re: unblocked Sleep() for all Platforms
« Reply #13 on: August 28, 2022, 12:31:30 pm »
https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-gettickcount64
This belongs to windows and for windows my code works perfect already but thanks! (since i did not wanted to use RTL blocking Sleep() at all)

I try to play with Josh's code a little, thank you all for answers!!!
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

rvk

  • Hero Member
  • *****
  • Posts: 6111
Re: unblocked Sleep() for all Platforms
« Reply #14 on: August 28, 2022, 12:51:36 pm »
https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-gettickcount64
This belongs to windows and for windows my code works perfect already but thanks! (since i did not wanted to use RTL blocking Sleep() at all)

I try to play with Josh's code a little, thank you all for answers!!!
The code from Josh also uses sleep.
And without sleep you'll put the cpu at a high percentage.

Btw GetTickCount64 is a Windows function but is recreated in FPC to be cross platform.
Or are you having problems with GetTickCount64 on another platform?

You can try clock_gettime or something else but in that case it isn't really cross platform and you're doing the same thing GetTickCount is doing under the hood.
« Last Edit: August 28, 2022, 12:53:38 pm by rvk »

 

TinyPortal © 2005-2018