// current_thread_info()->preempt_count bit划分 // /* // * - bits 0-7 are the preemption count (max preemption depth: 256) // * - bits 8-15 are the softirq count (max # of softirqs: 256) // * // * The hardirq count can be overridden per architecture, the default is: // * // * - bits 16-27 are the hardirq count (max # of hardirqs: 4096) // * - ( bit 28 is the PREEMPT_ACTIVE flag. ) // * // * PREEMPT_MASK: 0x000000ff // * SOFTIRQ_MASK: 0x0000ff00 // * HARDIRQ_MASK: 0x0fff0000 // */ // #define PREEMPT_BITS 8 // #define SOFTIRQ_BITS 8 // // #ifndef HARDIRQ_BITS // #define HARDIRQ_BITS 12 // #endif // #define PREEMPT_SHIFT 0 // #define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) //8 // #define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) //16 // #define __IRQ_MASK(x) ((1UL << (x))-1) // #define PREEMPT_MASK (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT) //0x000000ff // #define HARDIRQ_MASK (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT) //0x0000ff00 // #define SOFTIRQ_MASK (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) //0x0fff0000 // // #define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT) //1<<0 // #define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT) //1<<8 // #define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) //1<<16 // #define preempt_count() (current_thread_info()->preempt_count) // #define hardirq_count() (preempt_count() & HARDIRQ_MASK) // #define softirq_count() (preempt_count() & SOFTIRQ_MASK) // #define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK)) // #define in_irq() (hardirq_count()) // #define in_softirq() (softirq_count()) // #define in_interrupt() (irq_count()) // #define add_preempt_count(val) do { preempt_count() += (val); } while (0) // #define sub_preempt_count(val) do { preempt_count() -= (val); } while (0) // 中断进入 // 调用路径:do_IRQ->irq_enter // 函数主要任务: // 1.递增hardirq嵌套计数 1.1 void irq_enter(void) { do { //递增hardirq计数 add_preempt_count(HARDIRQ_OFFSET); } while (0); } // 中断退出 // 调用路径:do_IRQ->irq_exit // 函数主要任务: // 1.递减hardirq计数 // 2.如果此中断为嵌套路径上最后一个(#(hardirq+softirq)=0),并且此刻有软中断待处理 // 2.1 执行软中断处理函数 // 3.递减抢占计数 // 注: // 通过sub_preempt_count(IRQ_EXIT_OFFSET)、preempt_enable_no_resched()的配合,实现 // 检查是否有待处理软中断,以及执行 1.2 void irq_exit(void) { // 中断退出路径上对内核抢占的考虑 // 当支持内核抢占时,CONFIG_PREEMPT=1,此时IRQ_EXIT_OFFSET=(1<<16-1) // preempt_count -= IRQ_EXIT_OFFSET => preempt_count -= (1<<16) + 1 // 等价于: // 1.递减hardirq计数 // 2.preempt+1,禁止内核抢占 sub_preempt_count(IRQ_EXIT_OFFSET); //#(softirq+hardirq)=0,有待处理的软中断 if (!in_interrupt() && local_softirq_pending()) { //执行软中断处理函数 invoke_softirq(); } //preempt-1,开启内核抢占 preempt_enable_no_resched(); } 1.3 #ifdef CONFIG_PREEMPT # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1) #else # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET #endif #define preempt_enable_no_resched() \ do { \ barrier(); \ sub_preempt_count(1); \ } while (0)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架