The problem is that you need to constantly check for work. That is expensive on tight loops. Yes, I checked on every loop iteration unless I knew a small, but constant, amount of work had to be done.
That's the thing: if you have a tight loop, do you know how long it's going to take to run through everything? In addition, when a SIGINT comes, can you be sure that your state is correct?
Here's a test: download my utility and run these commands:
$ git checkout 2.7.0
$ ./configure.sh -gO3
$ make
$ echo "2^2^32" | bin/bc
Then send a SIGINT after a random amount of time.I did that twice, and both times, I triggered asserts. Some state was wrong.
This was after I had carefully gone through the entire codebase to check signals everywhere.
Now do this:
$ git checkout 6.7.0
$ ./configure.sh -gO3 -Sbc.sigint.reset
$ make
$ echo "2^2^32" | bin/bc
And send a SIGINT after a random amount of time.bc exits because its stdin is a pipe, but nothing goes wrong. If you do it like this:
$ bin/bc
>>> 2^2^32
^C
interrupt (type "quit" to exit)
0: (main)
ready for more input
>>>
And you can merrily continue.Semaphores and mutexes have the same problem: I would need to keep checking them.
I understand why you think the way you do; I did too. But the real world is more complicated.