linux内核中的位运算

在linux内核中有很多位运算函数,如:set_bit,clear_bit,clear_bit,test_and_set_bit等等。

1. set_bit

 

  1. <span style="font-size: 16px;">static __always_inline void  
  2. set_bit(unsigned int nr, volatile unsigned long *addr)  
  3. </span>  
static __always_inline void
set_bit(unsigned int nr, volatile unsigned long *addr)

 

       在起始地址为addr的位图中设置第nr位;是原子操作。

2. __set_bit

 

  1. <span style="font-size: 16px;">static __always_inline void  
  2. set_bit(unsigned int nr, volatile unsigned long *addr)  
  3. </span>  
static __always_inline void
set_bit(unsigned int nr, volatile unsigned long *addr)

 

       在起始地址为addr的位图中设置第nr位;非原子操作。

3. clear_bit

 

  1. <span style="font-size: 16px;">static __always_inline void  
  2. clear_bit(int nr, volatile unsigned long *addr)  
  3. </span>  
static __always_inline void
clear_bit(int nr, volatile unsigned long *addr)

 

       清除起始地址为addr的位图中的第nr位,改操作是原子操作但不具有加锁功能,若要用于加锁目的,应当调用smp_mb__before_clear_bit 或smp_mb__after_clear_bit函数,以确保任何改变在其他的处理器上是可见的。

4. change_bit

 

       static inline void change_bit(int nr, volatile unsigned long *addr)  

static inline void change_bit(int nr, volatile unsigned long *addr)

 

       在起始地址为addr的位图中改变第nr位;

5. test_and_set_bit

 

      static inline int test_and_set_bit(int nr, volatile unsigned long *addr)  

  

static inline int test_and_set_bit(int nr, volatile unsigned long *addr)

 

       在起始地址为addr的位图中设置第nr位;并返回原来的值,原子操作。

6. test_and_clear_bit

 

           static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)  

static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)

 

       在起始地址为addr的位图中清除第nr位;并返回原来的值,原子操作。

7. test_and_change_bit

 

          static inline int test_and_change_bit(int nr, volatile unsigned long *addr)  

static inline int test_and_change_bit(int nr, volatile unsigned long *addr)

 

       在起始地址为addr的位图中更改第nr位;并返回原来的值,原子操作。

8. test_bit

 

            define test_bit(nr, addr)           \  

  1.     (__builtin_constant_p((nr))     \  
  2.      ? constant_test_bit((nr), (addr))  \  
  3.      : variable_test_bit((nr), (addr)))  
#define test_bit(nr, addr)			\
	(__builtin_constant_p((nr))		\
	 ? constant_test_bit((nr), (addr))	\
	 : variable_test_bit((nr), (addr)))

 

       根据nr是否为编译时常数来调用不同的函数,

       若编译时为常数,则调用constant_test_bit

 

        static __always_inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr)    
static __always_inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr)

 

       若编译时为非常数,则调用variable_test_bit

          static inline int variable_test_bit(int nr, volatile const unsigned long *addr)

static inline int variable_test_bit(int nr, volatile const unsigned long *addr)

 

9. find_first_zero_bit

 

  1. <pre class="cpp" name="code"><span style="font-size: 16px;">int find_first_zero_bit (void * addr, unsigned size) </span></pre>  
  2. <pre></pre>  
  3. <p><span style="font-family: Microsoft YaHei;"><span style="font-size: 16px;"><span style="font-family: Microsoft YaHei;">       </span>addr为内存区的起始地址,size为要查找的最大长度,返回第一个位为0的位号</span></span></p>  
  4. <p><span style="font-family: Microsoft YaHei;"><span style="font-size: 16px;"><strong>10. find_next_zero_bit</strong> <span style="font-family: Microsoft YaHei;"></span></span></span></p>  
  5. <span style="font-family: Microsoft YaHei;"></span><pre class="cpp" name="code"><span style="font-size: 16px;">int find_next_zero_bit (void * addr, int size, int offset) </span></pre>  
  6. <p><span style="font-size: 16px;"><span style="font-family: Microsoft YaHei;">       </span>addr为内存区的起始地址,size为要查找的最大长度,offset开始搜索的起始位号。</span></p>  
  7. <p><span style="font-family: Microsoft YaHei;"><span style="font-size: 16px;"><strong>11. ffz <br>  
  8. </strong><span style="font-family: Microsoft YaHei;">        </span>ffz (x):在字x中搜索第一个0。</span></span></p>  
  9. <p><span style="font-family: Microsoft YaHei;"><span style="font-size: 16px;"><strong>12. ffs <br>  
  10. </strong><span style="font-family: Microsoft YaHei;">        </span>ffs (x):<span style="font-family: Microsoft YaHei;"> </span>在字x中搜索第一个已设置的位。</span></span></p>  
  11. <p><span style="font-family: Microsoft YaHei;"><span style="font-size: 16px;"><strong>13. hweight32</strong> <br>  
  12. <span style="font-family: Microsoft YaHei;">        </span>返回一个N位字的加权平衡值  <br>  
  13. <strong>14. hweight32 ( x)</strong><br>  
  14. <span style="font-family: Microsoft YaHei;">        </span>x为要加权的字 ,一个数的加权平衡是这个数所有位的总和。</span></span></p>  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux3.6.2内核配置详细介绍。学习内核编译和理解内核编译的绝佳资料 ( ) No Forced Preemption (Server) 适合服务器环境的禁止内核抢占这是传统的LINUX抢先式模型,针对于高吞吐量设计。它同样在很多时候 会提供很好的响应,但是也可能会有较长的延迟。如果你是建立服务器或者用于科学运算,选这项,或者 你想要最大化内核的原始运算能力,而不理会调度上的延迟。 (X) Voluntary Kernel Preemption (Desktop) 适 合普通桌面环境的自愿内核抢占这个选项通过向内核添加更多的“清晰抢先点”来减少内核延迟。这些新 的抢先点以降低吞吐量的代价,来降低内核的最大延迟,提 供更快的应用程序响应。这通过允许低优先级 的进程自动抢先来响应事件,即使进程在内核进行系统调用。这使得应用程序运行得更“流畅”,即使系统 已经是高 负荷运转。如果你是为桌面系统编译内核,选这项。 ( ) Preemptible Kernel (Low-Latency Desktop) 适 合运行实时程序的主动内核抢占这个选项通过使所有内核代码(非致命部分)编译为“可抢先”来降低内 核延迟。这通过允许低优先级进程进行强制抢先来响应事 件,即使这些进程正在进行系统调用或者未达到 正常的“抢先点”。这使得应用程序运行得更加“流畅”即使系统已 经是高负荷运转。代价是吞吐量降低,内核 运行开销增大。选这项如果你是为桌面或者嵌入式系统编译内核,需要非常低的延迟。如果你要最快的响 应,选第三项。 我认为万物是平衡的,低延迟意味着系统运行不稳定,因为过多来响应用户的要求,所以 我选第二个。
Linux内核,每个进程都有自己的内核堆栈,用于保存当前进程的执行状态、寄存器、局部变量等信息。当内核执行系统调用、断处理、异常处理等操作时,会使用内核堆栈来保存相关信息。 以下是Linux内核堆栈解析方法: 1. 确定内核堆栈地址:在Linux内核堆栈通常位于进程控制块(PCB)内核栈指针(kernel stack pointer)所指向的地址。可以通过查看进程的PCB结构体的kernel_stack成员来获取内核堆栈地址。 2. 获取堆栈帧指针:堆栈帧指针(frame pointer)是指向当前堆栈帧底部的指针,用于确定当前堆栈帧的大小和位置。可以通过读取当前CPU寄存器ebp(x86架构)或者r29(ARM架构)的值来获取堆栈帧指针。 3. 解析堆栈帧:在堆栈帧,局部变量、函数参数、返回值等信息都保存在栈。可以通过指针运算和类型转换等方法来访问这些信息。需要注意的是,由于内核堆栈是内核态的栈,因此在解析过程需要特别小心,防止出现悬垂指针、越界访问等问题。 4. 调试工具:除了手动解析堆栈外,还可以使用调试工具来辅助解析。例如,可以使用gdb调试器的bt命令来打印当前进程的堆栈回溯信息,或者使用系统调用ptrace来跟踪进程的堆栈信息。 总之,在Linux内核解析堆栈需要一定的经验和技能,需要特别小心,以避免出现问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值