Bug 448769 - KCalc becomes unresponsive during computationally complex calculations
Summary: KCalc becomes unresponsive during computationally complex calculations
Status: CONFIRMED
Alias: None
Product: kcalc
Classification: Applications
Component: general (show other bugs)
Version: 21.12.1
Platform: Compiled Sources Linux
: NOR normal
Target Milestone: ---
Assignee: Gabriel Barrantes
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-01-19 13:04 UTC by Niklas Freund
Modified: 2024-06-22 02:02 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Niklas Freund 2022-01-19 13:04:58 UTC
SUMMARY
When entering a computationally complex calculation, like e.g. the factorial of 123456789, the entire application becomes unresponsive. The program would probably respond again once it's done calculating, though for absurdly complex calculations that might just take longer than the lifetime of the universe.


STEPS TO REPRODUCE
1. In science mode, enter a large number (123456789).
2. Press "x!" (factorial)

OBSERVED RESULT
KCalc becomes unresponsive

EXPECTED RESULT
KCalc indicates it's working (using a status message or a "Working..." animation), but the GUI stays responsive (can be resized, interacted with, ...). There should probably be a way to abort the calculation if it takes too long, e.g. through an additional button (or maybe just by pressing "AC").

SOFTWARE/OS VERSIONS
KDE Plasma Version: 5.23.4
KDE Frameworks Version: 5.89.0
Qt Version: 5.15.2

ADDITIONAL INFORMATION/SPECULATION
I suspect that the GUI is waiting on whatever math function it calls to return. To solve this issue, you'd probably have to have the math functions run in a seperate thread.
Comment 1 Niklas Freund 2022-01-19 16:07:16 UTC
To clarify, I may be exaggerating a bit on the runtime of that factorial there (it may not be the lifetime of the universe, though it definitely takes an hour), but the main point is that KCalc should have some way to abort a calculation if it takes too long (instead of having to kill KCalc).
Comment 2 Joe Cardenas 2022-01-19 23:10:03 UTC
Reproduced on 21.12.1 . I can also confirm that the UI regains responsiveness when the operation completes.
Comment 3 Evan Teran 2022-01-20 04:03:44 UTC
Right. So addressing this "right" is suprisingly complex. Basically the issue is that the code for doing arbitrary precision math has no "cancellation points". The conventional solution to this kind of thing is to do the work in a background thread, and have that thread periodically check "did the user cancel"... But the library we use (GMP) just does the work, start to finish. It doesn't ask the caller "should I continue?" at any point during a long calculation. 

Killing a thread mid-process is considered so dangerous, that many OSes don't even provide clean APIs to do it... 

The other solution, which GMP also doesn't offer, is to have the work done in small bits you can call repeatedly until complete, allowing the caller an oportunity to run the event loop themselves (and/or just stop calling the "do some work" function if the user wishes to cancel). One can imagine the math being done in a virtual machine of sorts where the caller can run as many or as few instructions towards solving the problem at a time as they please.

Either way, Neither of these are really easily options for us.

So what's the solution? Well, probably to literally have the work done in a seperate process which CAN be killed via a signal and communicate the results with a pipe. It will be complicated to do this nicely, but it's doable and would fully address this issue of long running calculations freezing the UI.
Comment 4 Gabriel Barrantes 2024-06-22 02:02:39 UTC
(In reply to Evan Teran from comment #3)
> The other solution, which GMP also doesn't offer, is to have the work done
> in small bits you can call repeatedly until complete, allowing the caller an
> oportunity to run the event loop themselves (and/or just stop calling the
> "do some work" function if the user wishes to cancel).

We could to this.