They are compiler hints for GCC. They're used in conditionals to tell the compiler if a branch is likely to be taken or not. It can help the compiler laying down the code in such a way that's optimal for the most frequent outcome.
They are used like this:
if (likely(some_condition)) {
// the compiler will try and make the code layout optimal for the case
// where some_condition is true, i.e. where this block is run
most_likely_action();
} else {
// this block is less frequently used
corner_case();
}
It should be used with great care (i.e. based on actual branch profiling results). A wrong hint can degrade performance (obviously).
Some examples of how the code can be optimized are easily found by searching for GCC __builtin_expect
. This blog post gcc optimisation: __builtin_expect for example details a disassembly with it.
The kind of optimizations that can be done is very processor-specific. The general idea is that often, processors will run code faster if it does not branch/jump all over the place. The more linear it is, and the more predictable the branches are, the faster it will run. (This is especially true for processors with deep pipelines for example.)
So the compiler will emit the code such that the most likely branch will not involve a jump if that's what the target CPU prefers, for instance.
Though it was down voted ... possibly because someone thought it was not answering the question ... I think @Rony's answer is a good start at explaining what the boot
flag is about. (I was actually planning to begin my answer with an example similar to the one he provided.)
I was all set to ramble off an answer about how the boot
flag is, at this point in time, an often ignored (as @Rony's example shows) historical remnant from a period when hard drives were smaller and bootloaders were much less sophisticated.
But then I discovered this had already been said in this answer to this question: What is the "Bootable flag" option when installing a distro?
What's more there was also a link to a short article about the Boot flag which says
- "Its primary function is to indicate to a MS-DOS/MS Windows-type boot loader which partition to boot. In some cases it is used by Windows XP/2000 to assign the active partition the letter "C:"."
Well, this is embarrassing ...
When I claimed that the boot
flag was a "historical remnant" I was assuming this was the case because clearly GRUB had no need to use it. Surely Microsoft would also have "moved on".
The well known quote usually attributed to Oscar Wilde turned out to be too true in this instance.
It appears that the MBR and PBR (Partition Boot Record) loaders used by the Windows operating systems DO expect the boot
flag to be set correctly.
To test this I cleared the boot flag from all the partitions of a Windows 8 VM. (See below. If you're curious, here's a link to the pastebin of the complete BootInfo Script result)
Drive: sda
Disk /dev/sda: 26.8 GB, 26843545600 bytes
255 heads, 63 sectors/track, 3263 cylinders, total 52428800 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
Partition Boot Start Sector End Sector # of Sectors Id System
/dev/sda1 2,048 718,847 716,800 7 NTFS / exFAT / HPFS
/dev/sda2 718,848 52,426,751 51,707,904 7 NTFS / exFAT / HPFS
When I cleared the flag from both partitions, I got the error message FATAL: INT18: BOOT FAILURE
when I attempted to boot. (I am not sure if that is from the Windows MBR bootloader or the VM's equivalent of a BIOS.)
Just to see what would happen, I also set the boot
flag on the "wrong" partition, /dev/sda2
instead of /dev/sda1
. Doing that resulted in the window shown in the image below.
<sigh/>
This experience makes me wonder if Microsoft is still using the same MBR boot sector loader which they used for MS-DOS and Windows 3.0/3.1?
Best Answer
On a preemptive kernel, a process running in kernel mode can be replaced by another process while in the middle of a kernel function.
This only applies to processes running in kernel mode, a CPU executing processes in user mode is considered "idle". If a user mode process wants to request a service from the kernel, he has to issue an exception which the kernel can handle.
As an example:
Process
A
executes an exception handler, ProcessB
gets awaken by an IRQ request, the kernel replaces processA
withB
(a forced process switch). ProcessA
is left unfinished. The scheduler decides afterwards if processA
gets CPU time or not.On a nonpreemptive kernel, process
A
would just have used all the processor time until he is finished or voluntarily decides to allow other processes to interrupt him (a planned process switch).Today's Linux based operating systems generally do not include a fully preemptive kernel, there are still critical functions which have to run without interruption. So I think you could call this a "selective preemptive kernel".
Apart from that, there are approaches to make the Linux kernel (nearly) fully preemptive.