進程上下文和中斷上下文

文章目錄

  • 進程的preempt_count變量
    • thread_info
    • preempt_count
  • hardirq相關
  • softirq相關
  • 上下文

原文鏈接: https://zhuanlan.zhihu.com/p/88883239

進程的preempt_count變量

thread_info

在內核中,上下文的設置和判斷接口可以參考 include/linux/preempt.h 文件,整個機制的實現都依賴于一個變量:preempt_count,這個變量被定義在進程struct task_struct的 thread_info域中 ,也就是線程描述符中,線程描述符被放在內核棧的底部,在內核中可以通過 current_thread_info() 接口來獲取進程的 thread_info:

static inline struct thread_info *current_thread_info(void)
{return (struct thread_info *)(current_stack_pointer & ~(THREAD_SIZE - 1));
}register unsigned long current_stack_pointer asm ("sp");

其中 THREAD_SIZE 通常的大小為 4K 或者 8K,取出當前內核棧的 sp 指針,通過簡單地屏蔽掉 sp 的低 13 位,就可以獲取到 thread_info 的基地址。

在 arm 中,preempt_count 是 per task 的變量,而在 x86 中,preempt_count 是 percpu 類型的變量。

preempt_count

請添加圖片描述
作為控制上下文的變量, preempt_count 是 int 型,一共 32 位。通過設置該變量不同的位來設置內核中的上下文標志,包括硬中斷上下文、軟中斷上下文、進程上下文等,通過判斷該變量的值就可以判斷當前程序所屬的上下文狀態。

整個 preempt_count 被分為幾個部分:

  • bit 0-7:用于記錄關閉調度的次數。中斷上下文中,調度是關閉的,不會發生進程的切換,可以使用preempt_disable()來顯示地關閉調度,關閉次數由第0到7個bits組成的preemption count(注意不是preempt count)來記錄。每使用一次preempt_disable(),preemption count的值就會加1,使用preempt_enable()則會讓preemption count的值減1。
  • bit 8-15:描述軟中斷的標志位,如果softirq count的值為正數,說明現在正處于softirq上下文中,因為軟中斷在單個CPU上是不會嵌套執行的,所以只需要用第8位就可以用來判斷當前是否處于軟中斷的上下文中,其他的9-15位用于記錄關閉軟中斷的次數
  • bit 16-19:描述硬中斷嵌套次數,在老版本的linux 上支持中斷的嵌套,但是自從 2.6 版本之后內核就不再支持中斷嵌套,所以其實只用到了一位,如果這部分為正數表示在硬件中斷上下文,為 0 則表示不在。
  • bit20 :用于指示 NMI 中斷,只有兩個狀態:發生并處理 NMI 中斷置 1,退出中斷清除。
  • 其它 bit :沒有使用到,保留

hardirq相關

preempt_count中的第16到19個bit表示hardirq count,它記錄了進入hardirq/top half的嵌套次數,在這篇文章介紹的do_IRQ()中,irq_enter()用于標記hardirq的進入,此時hardirq count的值會加1。irq_exit()用于標記hardirq的退出,hardirq count的值會相應的減1。如果hardirq count的值為正數,說明現在正處于hardirq上下文中,代碼中可借助in_irq()宏實現快速判斷。注意這里的命名是"in_irq"而不是"in_hardirq"。

#define hardirq_count()	 (preempt_count() & HARDIRQ_MASK)
#define in_irq()  (hardirq_count())

hardirq count占據4個bits,理論上可以表示16層嵌套,但現在Linux系統并不支持hardirq的嵌套執行,所以實際使用的只有1個bit。

softirq相關

preempt_count中的第8到15個bit表示softirq count,它記錄了進入softirq的嵌套次數,如果softirq count的值為正數,說明現在正處于softirq上下文中。由于softirq在單個CPU上是不會嵌套執行的,因此和hardirq count一樣,實際只需要一個bit(bit 8)就可以了。但這里多出的7個bits并不是因為歷史原因多出來的,而是另有他用。

這個"他用"就是表示在進程上下文中,為了防止進程被softirq所搶占,關閉/禁止softirq的次數,比如每使用一次local_bh_disable(),softirq count高7個bits(bit 9到bit 15)的值就會加1,使用local_bh_enable()則會讓softirq count高7個bits的的值減1。

代碼中可借助in_softirq()宏快速判斷當前是否在softirq上下文:

#define softirq_count()  (preempt_count() & SOFTIRQ_MASK)
#define in_softirq()	 (softirq_count())

上下文

不管是hardirq上下文還是softirq上下文,都屬于我們俗稱的中斷上下文(interrupt context)。
請添加圖片描述
為此,有一個名為in_interrupt()的宏專門用來判斷當前是否在中斷上下文中。

#define irq_count()	 (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK | NMI_MASK))			 
#define in_interrupt()  (irq_count())

與中斷上下文相對應的就是俗稱的進程上下文(process context)

#define in_task()  (!(preempt_count() & (HARDIRQ_MASK | SOFTIRQ_OFFSET | NMI_MASK)))			   

需要注意的是,并不是只有進程才會處在process context,內核線程依然可以運行在process context。
在中斷上下文中,調度是關閉的,不會發生進程的切換,這屬于一種隱式的禁止調度,而在代碼中,也可以使用preempt_disable()來顯示地關閉調度,關閉次數由第0到7個bits組成的preemption count(注意不是preempt count)來記錄。每使用一次preempt_disable(),preemption count的值就會加1,使用preempt_enable()則會讓preemption count的值減1。preemption count占8個bits,因此一共可以表示最多256層調度關閉的嵌套。

處于中斷上下文,或者顯示地禁止了調度,preempt_count()的值都不為0,都不允許睡眠/調度的發生,這兩種場景被統稱為atomic上下文,可由in_atomic()宏給出判斷。

#define in_atomic()	(preempt_count() != 0)

中斷上下文、進程上下文和atomic上下文的關系大概可以表示成這樣:
請添加圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/379514.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/379514.shtml
英文地址,請注明出處:http://en.pswp.cn/news/379514.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

標題:湊算式

標題:湊算式 這個算式中AI代表19的數字,不同的字母代表不同的數字。 比如: 68/3952/714 就是一種解法, 53/1972/486 是另一種解法。 這個算式一共有多少種解法? 注意:你提交應該是個整數,不要…

匯編中imul_JavaScript中帶有示例的Math.imul()方法

匯編中imulJavaScript | Math.imul()方法 (JavaScript | Math.imul() Method) Math.imul() is a function in math library of JavaScript that is used to the 32-bit multiplication of the two values passed to it. It uses C-like semantics to find the multiplication. …

AFTER觸發器與INSTEAD OF觸發器的區別

INSTEAD OF 觸發器用來代替通常的觸發動作,即當對表進行INSERT、UPDATE 或 DELETE 操作時,系統不是直接對表執行這些操作,而是把操作內容交給觸發器,讓觸發器檢查所進行的操作是否正確。如正確才進行相應的操作。因此,…

Linux內存地址管理

文章目錄系統內存布局內核地址的低端和高端內存概念低端內存高端內存地址轉換和MMULinux中的四級分頁模型虛擬地址字段頁表處理將虛擬地址轉換物理地址Linux系統中的每個內存地址都是虛擬的,它們不直接指向任何物理內存地址。每當訪問內存位置時,可以執行…

錄制caf 轉 mp3

編譯需要使用的 lame庫http://www.cocoachina.com/bbs/read.php?tid108237參考的文章http://blog.csdn.net/ysy441088327/article/details/7392842說起來,我一直在找一個音頻轉換成mp3的方法。一年前,我成功編譯出了一個lame for armv7的庫。苦于不會使…

杭電2012-素數判定(C)

Problem Description 對于表達式n^2n41&#xff0c;當n在&#xff08;x,y&#xff09;范圍內取整數值時&#xff08;包括x,y&#xff09;(-39<x<y<50)&#xff0c;判定該表達式的值是否都為素數。 Input 輸入數據有多組&#xff0c;每組占一行&#xff0c;由兩個整數…

math.ceil帶小數點_JavaScript中帶有示例的Math.ceil()方法

math.ceil帶小數點JavaScript | Math.ceil()方法 (JavaScript | Math.ceil() Method) Math.ceil() is a function in math library of JavaScript that is used to round up the number passed to the function. The method will return the nearest integer value indeed is g…

開發記要 詭異的變量

告別繁體文盲,從寫blog開始 Variable命名很重要,有多重要,看看.net和java的加密就知道, 都是把variable改到一塌糊塗,你想看看都沒門. 但是這幾天看遺留系統的代碼,真是大開眼界。 我一直以為別人寫a,b,c,d這些單字節variable已經很過分。直到我看到以下這幾個&#xff0…

排序算法---快速排序、堆排序、冒泡排序

排序算法1 快速排序代碼實現stdlib庫快排2 堆排序堆排序的基本思想如何構造一個大頂堆排序3 冒泡排序1 快速排序 文章原地址&#xff1a;https://blog.csdn.net/morewindows/article/details/6684558 快速排序的平均時間復雜度是0(NlogN)&#xff0c;它采用了一種分治的策略&a…

CSS Hack 匯總快查

*:lang(zh) select {font:12px !important;} /*FF的專用*/ select:empty {font:12px !important;} /*safari可見*/ 這里select是選擇符&#xff0c;根據情況更換。第二句是MAC上safari瀏覽器獨有的。 僅IE7識別 *html {…} 當面臨需要只針對IE7做樣式的時候就可以采用這個HACK…

杭電2013-蟠桃記(C++)

Problem Description 喜歡西游記的同學肯定都知道悟空偷吃蟠桃的故事&#xff0c;你們一定都覺得這猴子太鬧騰了&#xff0c;其實你們是有所不知&#xff1a;悟空是在研究一個數學問題&#xff01; 什么問題&#xff1f;他研究的問題是蟠桃一共有多少個&#xff01; 不過&#…

c#中重載單目運算符-_C#程序重載二進制運算符(-,*,/)

c#中重載單目運算符-Here, we will design overloaded methods for binary operators: minus, multiply and divide. In the below program, we will create a Calculator class with data member val. 在這里&#xff0c;我們將為二進制運算符設計重載方法&#xff1a;減&…

項目總結:華南師范大學校園開發教育android客戶端總結

忽略之前小打小鬧&#xff0c;這個項目算是我的第一個項目--SCNU的網絡公選課的android版本的客戶端。項目是從5月中旬開始的&#xff0c;中間經歷了幾個星期的復習考試時間&#xff0c;到現在可以說是完工了吧&#xff08;或許還有寫細節要修改&#xff09;。這個項目帶給我蠻…

火鳥字幕合并器

火鳥字幕合并器-區塊獨立勾選-保存。漢王 PDF OCR轉載于:https://www.cnblogs.com/hnytwn/archive/2009/10/31/1593395.html

Linux系統編程---守護進程

1 守護進程的概述 Daemon&#xff08;守護進程&#xff09;是運行在后臺的一種特殊進程。它獨立于控制終端并且周期性地執行某種任務或等待處理某些發生的事件。它不需要用戶輸入就能運行而且提供某種服務&#xff0c;不是對整個系統就是對某個用戶程序提供服務。Linux系統的大…

c ++明明的隨機數_從列表C ++程序中隨機建議電影

c 明明的隨機數Problem statement: 問題陳述&#xff1a; Write an application code that will suggest movies from a list randomly and there wont be any repeat while suggesting the movies. That means the same movie wont be suggested twice though it will be don…

郵箱服務器

一&#xff0e;郵箱服務器的基本概念 郵件的客戶端&#xff1a;可以只安裝在電腦上&#xff08;C/S&#xff09;的也可以是網頁形式&#xff08;B/S&#xff09;的 郵件服務器&#xff1a;起到郵件的接受與推送的作用 郵件發送的協議&#xff1a; 協議&#xff1a;就是數據傳輸…

C#提高保存jpg圖像的質量

在程序中直接生成的jpg圖像&#xff0c;漢字有毛邊&#xff0c;經過一番搜索&#xff0c;在msdn上發現了下面控制jpg質量系數的文章&#xff0c;修改后試了一下&#xff0c;效果確實比前面強多了。原理我也不大懂&#xff0c;把代碼貼出來&#xff0c;與大家共享。 聯合圖…

延遲和定時器管理

文章目錄1 內核中時間概念2 標準定時器jiffies和HZ定時器API標準定時器案例3 高精度定時器(HRT)高精度定時器案例4 內核中延遲和睡眠原子上下文非原子上下文1 內核中時間概念 時間概念對計算機來說有些模糊&#xff0c;事實上內核必須在硬件的幫助下才能計算和管理時間。硬件為…

Web開發工具(插件)收集

1.IE Developer Toolbar 瀏覽和修改&#xff0c;選定Web頁上的特定元素&#xff0c;查看HTML對象的類名、ID&#xff0c;以及類似鏈接路徑、tab順序、快捷鍵等。 2.HttpWatch Professional 一款強大的網頁數據分析工具,可以查看當前網頁的http數據 FireFox插件 FireFox下插件實…