本文主要是介绍MLX5_SET_TO_ONES宏解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
看代码时,遇到一个非常复杂的宏MLX5_SET_TO_ONES,这个宏的主要作用是对特定的数据结构置位,宏的上下文如下:
#define __mlx5_nullp(typ) ((struct mlx5_ifc_##typ##_bits *)0)
#define __mlx5_bit_off(typ, fld) (offsetof(struct mlx5_ifc_##typ##_bits, fld))
// 获取fld在typ中的字(32位)偏移量,
#define __mlx5_dw_off(typ, fld) (__mlx5_bit_off(typ, fld) / 32)
#define __mlx5_bit_sz(typ, fld) sizeof(__mlx5_nullp(typ)->fld)
#define __mlx5_mask(typ, fld) ((u32)((1ull << __mlx5_bit_sz(typ, fld)) - 1))
#define __mlx5_mask16(typ, fld) ((u16)((1ull << __mlx5_bit_sz(typ, fld)) - 1))
// 获取fld在一个字内的偏移量
#define __mlx5_dw_bit_off(typ, fld) (32 - __mlx5_bit_sz(typ, fld) - (__mlx5_bit_off(typ, fld) & 0x1f))
#define __mlx5_dw_mask(typ, fld) (__mlx5_mask(typ, fld) << __mlx5_dw_bit_off(typ, fld))
#define __mlx5_16_bit_off(typ, fld) (16 - __mlx5_bit_sz(typ, fld) - (__mlx5_bit_off(typ, fld) & 0xf))
#define __mlx5_16_mask(typ, fld) (__mlx5_mask16(typ, fld) << __mlx5_16_bit_off(typ, fld))#define __mlx5_st_sz_bits(typ) sizeof(struct mlx5_ifc_##typ##_bits)#define __mlx5_16_off(typ, fld) (__mlx5_bit_off(typ, fld) / 16)/* 置位 */
#define MLX5_SET_TO_ONES(typ, p, fld) do { \BUILD_BUG_ON(__mlx5_st_sz_bits(typ) % 32); \*((__be32 *)(p) + __mlx5_dw_off(typ, fld)) = \cpu_to_be32((be32_to_cpu(*((__be32 *)(p) + __mlx5_dw_off(typ, fld))) & \(~__mlx5_dw_mask(typ, fld))) | ((__mlx5_mask(typ, fld)) \<< __mlx5_dw_bit_off(typ, fld))); \
} while (0)
来一步一步看一下
- 获取目标位置
- 这个宏首先会将指针 p 转换为指向 32 位大端整数 (__be32) 的指针:(__be32 *)§ ,这是因为要以32位为单位,内部设置偏移量进行置位,
- 其次获取fld在typ中的字偏移量(32位):__mlx5_dw_off(typ, fld)
- 获取p指针字偏移处的值:*((__be32 *)§ + __mlx5_dw_off(typ, fld))
- 读取当前值并转换为主机字节序: be32_to_cpu(*((__be32 *)§ + __mlx5_dw_off(typ, fld)))
- 读取目标字处的值。
- be32_to_cpu 将读取到的大端格式值转换为主机字节序。
- 清除目标位:
- __mlx5_dw_mask(typ, fld) 生成目标字段的掩码。
- ~__mlx5_dw_mask(typ, fld) 取反掩码,用于清除目标位。
- & (~__mlx5_dw_mask(typ, fld)) 使用按位与操作,将目标字段位清零。
- 生成新值并转换为大端字节序:((__mlx5_mask(typ, fld)) << __mlx5_dw_bit_off(typ, fld))
- __mlx5_mask(typ, fld) 生成目标字段的位掩码。
- << __mlx5_dw_bit_off(typ, fld) 将掩码左移至目标位偏移量位置。
- | ((__mlx5_mask(typ, fld)) << __mlx5_dw_bit_off(typ, fld)) 将目标位设置为 1。
- cpu_to_be32 将结果转换回大端格式。
- 写回结果:*((__be32 *)§ + __mlx5_dw_off(typ, fld)) = cpu_to_be32(…)
- 将处理后的结果写回 p 指针对应双字偏移量处。
这篇关于MLX5_SET_TO_ONES宏解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!