Date: Fri, 8 May 2020 21:02:59 -0400
Currently in the C++ language, it is undefined behaviour to have an
infinite loop without observable side effects. While this is nice on paper,
it has a few issues. Any time you need to loop forever, you basically need
to insert a (potentially costly) side effect. This applies any time you
need are, say, running a game on a old console, and just need to spin while
waiting for interrupts to do stuff (same with an os kernel). This results
in requiring assembly to so this, or maybe insert an instruction to wait
for an interrupt in a loop (both llvm and gcc allow the volatile specifier
in an assembly declaration, which is treated as observable, so x86_64 code
could use hlt (in CPL=0), 65816 could WAI). This, however, seems to violate
one of C++'s core principles, that there is no lower level language.
A further case would be an init process on linux, which cannot terminate
(doing so results in a kernel panic), nor can just call hlt in a loop, as
that's one way to get a #GP which probably translates to SIGILL. Once an
init process is done setting up, it could want to just spin forever, and do
so using as little system resources as possible. The logical idea would be
just for(;;) std::this_thread::yield();, but that would be UB as yield() is
not observable (correct me if I'm wrong).
Having the ability to spin forever, without wasting time actually doing
stuff, seems like a reasonable thing to have in low-level code, so its very
curious (and in many cases, annoying) that you cannot actually do this in
real code that might have to.
infinite loop without observable side effects. While this is nice on paper,
it has a few issues. Any time you need to loop forever, you basically need
to insert a (potentially costly) side effect. This applies any time you
need are, say, running a game on a old console, and just need to spin while
waiting for interrupts to do stuff (same with an os kernel). This results
in requiring assembly to so this, or maybe insert an instruction to wait
for an interrupt in a loop (both llvm and gcc allow the volatile specifier
in an assembly declaration, which is treated as observable, so x86_64 code
could use hlt (in CPL=0), 65816 could WAI). This, however, seems to violate
one of C++'s core principles, that there is no lower level language.
A further case would be an init process on linux, which cannot terminate
(doing so results in a kernel panic), nor can just call hlt in a loop, as
that's one way to get a #GP which probably translates to SIGILL. Once an
init process is done setting up, it could want to just spin forever, and do
so using as little system resources as possible. The logical idea would be
just for(;;) std::this_thread::yield();, but that would be UB as yield() is
not observable (correct me if I'm wrong).
Having the ability to spin forever, without wasting time actually doing
stuff, seems like a reasonable thing to have in low-level code, so its very
curious (and in many cases, annoying) that you cannot actually do this in
real code that might have to.
Received on 2020-05-08 20:06:11