- How does it expand:
Keep in mind anytime you ask something like that wrt the Linux kernel, the answer is never easy... so... here we go:
#define for_each_possible_cpu(cpu) for_each_cpu((cpu), cpu_possible_mask)
You can see that this macro is really just a for loop, called with an iterator as cpu
the for_each_cpu
is another macro which is the looping part defined as:
#define for_each_cpu(cpu, mask) \
for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask)
And the cpu_possible_mask is a pointer to a struct:
extern const struct cpumask *const cpu_possible_mask;
Which is seen here (consisting of another macro):
typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
That contains another macro (DECLARE_BITMAP
) and it has another #define
for NR_CPUS
, that is the number of CPUs in the system, it should be system dependent and set in the kconfig. The macro in there is really just an array and an accessor:
#define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]
So you can see that's the array and the accessor which of course consists of another #define
:
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
...which consists of two more #define
s:
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
#define BITS_PER_BYTE 8
Anyway... you can see that (A) this is a mess and (B) it ends up being a for
loop that increments number of CPUs but also issues a second iterative action via the comma operator. How exactly the second operator words itself out is system dependent. (what's the sizeof a long on your system? what's the number of cpus on your system?)
2.Why are two others #defines are called inside?
That's kind of answered by #1. Since it expands to a for
loop, you need that loop to do something.
3.Why is the per_cpu output equated to -1?
The per_cpu
macro is giving a pointer to the CPU frequency policy of each CPU in the system, that is being initialized to -1
. I'd have to do more research to be sure, but presumably they picked that because of the define:
#define CPUFREQ_ETERNAL (-1)
And the __init_rwsem
is an architecture defined way of initializing the read/write semaphore used for each CPU's policy.
I don't know if that explanation helped much, but at least maybe it helps point you in a better direction. Good luck exploring the kernel.