On Thu, Nov 7, 2013 at 11:04 AM, sdptroy3@gmail.com <sdptroy3@gmail.com> wrote:
While going through kernel source , I came across this ALIGN macro
#define ALIGN(x, a) __ALIGN_KERNEL((x), (a))
and
#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1)
#define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask))
What does this macro do? I have read this article http://stackoverflow.com/questions/13122846/align-macro-kernel but it was not of much help.
Try the above calculation for a small number, and align it to a 4 byte boundary. That'll clear things up as to how this macro is working. So for example, lets align '6' to a '4' byte boundary. This should result in 8. ALIGN(6, 4) = __ALIGN_KERNEL((6), (4)) __ALIGN_KERNEL(6, 4) = __ALIGN_KERNEL_MASK(6, (typeof(6)) (4) - 1) typeof(6) is 'int' & 4 - 1 = 3. __ALIGN_KERNEL_MASK(6, (int) 3) = (((6) + (3)) & ~(3)) Assuming only 4 bits for simplicity): 6 + 3 = 9 = 1001 ~3 = 1100 __ALIGN_KERNEL_MASK(6, (int) 3) = (((6) + (3)) & ~(3)) = 1001 & 1100 = 1000 = 8 Since alignment is a power of 2, subtracting 1 from it sets all bits after the (original) MSB to 1 (eg: 4 = 100 & 3 = 011). Adding this 'mask' (3) ensures that the resulting number is at least larger than the next multiple of 'a' that is greater than x (so in our case 9 > 8, and 8 is a multiple of 4 which is > 6 (x)). Now bitwise AND-ing with the 1s compliment of mask ensures that all bits, except the MSB, will be set to 0, thus resulting in a number aligned at a multiple of 'a'. In our case, the MSB was set when we did the addition. Hope this makes it a little clear. -mandeep
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies