With some parallels to previous responses, I'll describe more detailedly. Two main contexts shall be distinguished: 1) a code with supervisor rights directly on the running hardware (this includes OS) and 2) an application code.
For the second case - an application code - an application shall do a system call usually named "exit" which notifies supervisor (kernel) that the application is finished. Details of this call vary; e.g. MS-DOS AH=4Ch/int21h as described by rcgldr is such "exit"; in modern Linux it's exit_group
syscall; and so on. When seeing only main() you might miss the fact that main() is called by a system-specific application wrapper, which do this exit() call. If application doesn't exit explicitly, it will execute until a fatal error occured. Getting this exit() request, supervisor destructs the process and switches to another one.
For the supervisor itself, if it stops execution, this is very platform specific. For x86, initially the main method for shutdown without poweroff was a cycle around HLT
instruction (because the latter can spontaneously continue on interrupts). The same HLT was used until approx. Pentium4 and Athlon to stop processor until an interrupt when there is no work; since these processors, additional measures became needed to stop chipset-level activity, so the stopping method became more complex. Modern x86 platforms describe how to make temporary system stop according to description on ACPI internal language, which includes multiple system port programming. Similar instructions for stopping until external event coming are present for all real architectures. There can be multiple levels of stopping; e.g. some embedded ones have "minor stop" which only slows processor down and "major stop" which stops processor fully but then needs tens of microseconds for clock PLL settling out. Anyway, after such stop, supervisor tries to continue normal work, until reboot/poweroff/etc. is being reached.
Multi-processor (multi-core) configurations have their own specifics so initially only one core at one processor is started. Then, inter-processor interrupts (IPIs) or analogs are used to start or stop another cores and processors. Stopping OS work usually includes stopping of all processors and cores except a final one.
hsc
– ta.speot.is