I am unable to understand what this macro does. These are defined in linux-kernel
but my doubt is independent of that. I am unable to understand what does (((x)+(mask))&~(mask))
line does.
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
Any help appreciated.
Say you have a number: 0x1006
For some reasons you want to align it to a 4
bytes boundary.
With a 4-byte boundary, you know aligned values are 0x1000
, 0x1004
, 0x1008
, etc.
You then also know the aligned value of 0x1006
is 0x1008
.
How would you get 0x1008
? The alignment mask for alignment value 4
is (4 - 1) = 0x03
Now 0x1006 + 0x03 = 0x1009
and 0x1009 & ~0x03 = 0x1008
This operation is the __ALIGN_MASK
macro.
If you want to pass the value 4
(the alignment) instead of directly 0x03
(the alignment mask), you have the ALIGN
macro
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
the alignment, a
, is cast to x
's type, and then one is subtracted. The alignment should be a power of 2, so that results in a number of the bit-pattern 00..011..11
of x
's type, the mask (k
1s if a = 2^k
).
Then
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
adds the value of the mask to x
, so that (x)+ (mask)
is at least as large as the smallest multiple of the alignment that is not smaller than x
and smaller than the next larger multiple. Then the bitwise and with the complement of the mask reduces that number to that multiple of the alignment.
For masks of the form 2^k - 1
, the computation
(x + mask) & ~mask
is the same as
(x + 2^k - 1) - ((x + 2^k - 1) % (2^k))
or
((x + 2^k - 1)/(2^k)) * (2^k)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With