My app consumes a CPU while doing nothing. What's it doing?

My app seems to be consuming 100% or so of a CPU while running in a VM under Linux Mint Cinnamon (I also have a report of it doing this on real hardware). Running under macOS or Win7/10 this does not happen. One can see the consumption using top in a Terminal window. This happens even when the app is supposedly idle with just the Main Thread, and one other thread that is suspended. There will be a couple of timers running one of which fires once a minute, the other once an hour.

If I run it under debug and, in the IDE, pause the app, then CPU usage drops off to zero until I resume it. Every time I pause it, the IDE says the Main Thread is in the Event Loop, and the other thread is on its suspend, waiting for work.

The IDE does not exhibit this behaviour.

How can I find out more about what is happening?

The Event Loop is always running. If you have an access to a Macintosh, fire the “Activity Monitor” (in Application --> Utilities) and be sure the Processor tab is set to ON.

You will see the processor running per application. Stunning :frowning:

Check your application for any overlapping controls or a canvas that is redrawing itself in its paint event. I’ve seen this when GTK tries to refresh the overlapping controls.

Ah. I’m using the modGTK3 package to make the controls draw better. Can I test this by commenting out the modGTK3 inirialisation?

You’re using GTK regardless of whether you use modGTK3 or not.

However, since you’re using modGTK3, removing the init call will stop the control resizing that may be causing overlapping that you’re not expecting.

Roger that Houston. I’ll check into it in a while after cutting the lawn.

Well, commenting out the modGTK3 initialisation made no difference. Guess I’ll have to go through all the paint events.

I went through all 33 paint/celltextpaint/cellbackgroundpaint event handlers and added a system.debuglog message to each, at the beginning. None of them fired more than expected. I was hoping to see a pair of them alternating producing non-stop pairs of messages but it didn’t happen.

Anything else I can try?

You could try profiling the project. The profiler results will gove you an indicator of where things are getting overly friendly with your CPU.

Have you tried tracing the OS calls (strand / ptrace)?

A few years back we noticed our Linux console apps were using a lot of CPU time when idling. We discovered that the Xojo framework was performing lots of micro sleeps (calls to pthread) when we executed a sleep command in our code.

I think the bug was fixed in a later version of Xojo but I wouldn’t be surprised if there are other similar bugs lurking in the framework.

Profiling: this appears to have a problem in that if you abort the app from within the IDE you get no profile information for that run. As I’m also having an issue with the app quitting under Linux, this seemed it might be a difficulty, however profiling alters the timings enough that the app quits OK. The profile data appears to show that all the time is spent in my websocket server, but adding some system.DebugLog() shows that this is not the case. This server has the usual work queue, and suspends itself until resumed and then executes items on its work queue, suspends again.

Perhaps thread.suspend() under Linux is just a CPU loop, but that seems unlikely.

strace: this gives the following:

[quote]select(30, [29], [], [29], {tv_sec=0, tv_usec=0}) = 0 (Timeout)
ioctl(29, FIONREAD, [0]) = 0
select(12, [11], [], [11], {tv_sec=0, tv_usec=0}) = 0 (Timeout)
ioctl(11, FIONREAD, [0]) = 0
recvmsg(3, {msg_namelen=0}, 0) = -1 EAGAIN (Resource temporarily unavailable)

with these five lines appearing as blocks ad infinitum.

Try running perf / perf top as that might indicate if those calls are responsible for the high cpu usage.

If they are then you might have to re-implement your functionality without using Suspend.

A quick search on Feedback shows a case from 2014 where Suspend causes high CPU usage on macOS. I wouldn’t be surprised if it is the same issue.

I guess that Xojo for desktop does a lot of pooling for I/O and event processing while “idle”.

[quote=445718:@Tim Streater]Profiling: this appears to have a problem in that if you abort the app from within the IDE you get no profile information for that run.
You do need to quit cleanly as an abort makes it so the profiler also aborts and so you get no results

[quote=445719:@Kevin Gale]A quick search on Feedback shows a case from 2014 where Suspend causes high CPU usage on macOS. I wouldn’t be surprised if it is the same issue.

I tried the example project from this feedback under macOS and while the thread is suspended, it uses no CPU time. Just tried it under Linux (which I’m running in a VM under VirtualBox) and it uses 100% CPU while the suspend is in operation.

But more bizarrely, I commented out the suspend() and uncommented the sleep(100). No difference!

Yeah, once I thought about it I realised that the profile data will be stored in memory until the profiler quits.

My next port of call.

Why are you using suspend (granted, that is a bug since the purpose of suspend is to not use ANY CPU cycles)? Are you using it to allow for UI responsiveness? Would a thread.Sleep(5) get the job done for you instead?

The thread implements a websocket server for an HTMLViewer to communicate with the rest of the app. It avoids having to use the StatusChanged and TitleChanged events which either no longer work on some platforms or are limited in how much data they can pass.

If the server has no work items then it has nothing to do, so thread.suspend() seemed the obvious choice. I suppose thread.sleep(1000, true) would also work with a low overhead, but on Linux that seems also to consume CPU. I shall play with that a bit more, and if a minimal example still consumes cycles then I can submit it as a bug.

You know Zoom got in trouble just recently for this exact same thing?