青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

天下

記錄修行的印記

Linux內核的同步機制(1)自旋鎖(spinlock)

Linux內核的同步機制(1)、自旋鎖(spinlock)

  自旋鎖與互斥鎖有點類似,只是自旋鎖不會引起調用者睡眠,如果自旋鎖已經被別的執行單元保持,調用者就一直循環在那里看是否該自旋鎖的保持者已經釋放了鎖,"自旋"一詞就是因此而得名。

  由于自旋鎖使用者一般保持鎖時間非常短,因此選擇自旋而不是睡眠是非常必要的,自旋鎖的效率遠高于互斥鎖。

  信號量和讀寫信號量適合于保持時間較長的情況,它們會導致調用者睡眠,因此只能在進程上下文使用(_trylock的變種能夠在中斷上下文使用),而自旋鎖適合于保持時間非常短的情況,它可以在任何上下文使用。

  如果被保護的共享資源只在進程上下文訪問,使用信號量保護該共享資源非常合適,如果對共巷資源的訪問時間非常短,自旋鎖也可以。但是如果被保護的共享資源需要在中斷上下文訪問(包括底半部即中斷處理句柄和頂半部即軟中斷),就必須使用自旋鎖。

  自旋鎖保持期間是搶占失效的,而信號量和讀寫信號量保持期間是可以被搶占的。自旋鎖只有在內核可搶占或SMP的情況下才真正需要,在單CPU且不可搶占的內核下,自旋鎖的所有操作都是空操作。

  跟互斥鎖一樣,一個執行單元要想訪問被自旋鎖保護的共享資源,必須先得到鎖,在訪問完共享資源后,必須釋放鎖。如果在獲取自旋鎖時,沒有任何執行單元保持該鎖,那么將立即得到鎖;如果在獲取自旋鎖時鎖已經有保持者,那么獲取鎖操作將自旋在那里,直到該自旋鎖的保持者釋放了鎖。

  無論是互斥鎖,還是自旋鎖,在任何時刻,最多只能有一個保持者,也就說,在任何時刻最多只能有一個執行單元獲得鎖。

自旋鎖的API有:

spin_lock_init(x)
該宏用于初始化自旋鎖x。自旋鎖在真正使用前必須先初始化。該宏用于動態初始化。
    
DEFINE_SPINLOCK(x)
該宏聲明一個自旋鎖x并初始化它。該宏在2.6.11中第一次被定義,在先前的內核中并沒有該宏。
    
SPIN_LOCK_UNLOCKED
該宏用于靜態初始化一個自旋鎖。

DEFINE_SPINLOCK(x)等同于spinlock_t x = SPIN_LOCK_UNLOCKED
    
spin_is_locked(x)
該宏用于判斷自旋鎖x是否已經被某執行單元保持(即被鎖),如果是,返回真,否則返回假。
    
spin_unlock_wait(x)
該宏用于等待自旋鎖x變得沒有被任何執行單元保持,如果沒有任何執行單元保持該自旋鎖,該宏立即返回,否則將循環在那里,直到該自旋鎖被保持者釋放。
    
spin_trylock(lock)
該宏盡力獲得自旋鎖lock,如果能立即獲得鎖,它獲得鎖并返回真,否則不能立即獲得鎖,立即返回假。它不會自旋等待lock被釋放。
    
spin_lock(lock)
該宏用于獲得自旋鎖lock,如果能夠立即獲得鎖,它就馬上返回,否則,它將自旋在那里,直到該自旋鎖的保持者釋放,這時,它獲得鎖并返回。總之,只有它獲得鎖才返回。
    
spin_lock_irqsave(lock, flags)
該宏獲得自旋鎖的同時把標志寄存器的值保存到變量flags中并失效本地中斷。
    
spin_lock_irq(lock)
該宏類似于spin_lock_irqsave,只是該宏不保存標志寄存器的值。
    
spin_lock_bh(lock)
該宏在得到自旋鎖的同時失效本地軟中斷。
    
spin_unlock(lock)
該宏釋放自旋鎖lock,它與spin_trylock或spin_lock配對使用。如果spin_trylock返回假,表明沒有獲得自旋鎖,因此不必使用spin_unlock釋放。
    
spin_unlock_irqrestore(lock, flags)
該宏釋放自旋鎖lock的同時,也恢復標志寄存器的值為變量flags保存的值。它與spin_lock_irqsave配對使用。
    
spin_unlock_irq(lock)
該宏釋放自旋鎖lock的同時,也使能本地中斷。它與spin_lock_irq配對應用。
    
spin_unlock_bh(lock)
該宏釋放自旋鎖lock的同時,也使能本地的軟中斷。它與spin_lock_bh配對使用。
    
spin_trylock_irqsave(lock, flags)
該宏如果獲得自旋鎖lock,它也將保存標志寄存器的值到變量flags中,并且失效本地中斷,如果沒有獲得鎖,它什么也不做。
  因此如果能夠立即獲得鎖,它等同于spin_lock_irqsave,如果不能獲得鎖,它等同于spin_trylock。如果該宏獲得自旋鎖lock,那需要使用spin_unlock_irqrestore來釋放。

spin_trylock_irq(lock)
該宏類似于spin_trylock_irqsave,只是該宏不保存標志寄存器。如果該宏獲得自旋鎖lock,需要使用spin_unlock_irq來釋放。
    
spin_trylock_bh(lock)
該宏如果獲得了自旋鎖,它也將失效本地軟中斷。如果得不到鎖,它什么也不做。因此,如果得到了鎖,它等同于spin_lock_bh,如果得不到鎖,它等同于spin_trylock。如果該宏得到了自旋鎖,需要使用spin_unlock_bh來釋放。

spin_can_lock(lock)
該宏用于判斷自旋鎖lock是否能夠被鎖,它實際是spin_is_locked取反。如果lock沒有被鎖,它返回真,否則,返回假。該宏在2.6.11中第一次被定義,在先前的內核中并沒有該宏。 

  獲得自旋鎖和釋放自旋鎖有好幾個版本,因此讓讀者知道在什么樣的情況下使用什么版本的獲得和釋放鎖的宏是非常必要的。 

  如果被保護的共享資源只在進程上下文訪問和軟中斷上下文訪問,那么當在進程上下文訪問共享資源時,可能被軟中斷打斷,從而可能進入軟中斷上下文來對被保護的共享資源訪問,因此對于這種情況,對共享資源的訪問必須使用spin_lock_bh和spin_unlock_bh來保護。 

  當然使用spin_lock_irq和spin_unlock_irq以及spin_lock_irqsave和spin_unlock_irqrestore也可以,它們失效了本地硬中斷,失效硬中斷隱式地也失效了軟中斷。但是使用spin_lock_bh和spin_unlock_bh是最恰當的,它比其他兩個快。 

  如果被保護的共享資源只在進程上下文和tasklet或timer上下文訪問,那么應該使用與上面情況相同的獲得和釋放鎖的宏,因為tasklet和timer是用軟中斷實現的。 

  如果被保護的共享資源只在一個tasklet或timer上下文訪問,那么不需要任何自旋鎖保護,因為同一個tasklet或timer只能在一個CPU上運行,即使是在SMP環境下也是如此。實際上tasklet在調用tasklet_schedule標記其需要被調度時已經把該tasklet綁定到當前CPU,因此同一個tasklet決不可能同時在其他CPU上運行。 

  timer也是在其被使用add_timer添加到timer隊列中時已經被幫定到當前CPU,所以同一個timer絕不可能運行在其他CPU上。當然同一個tasklet有兩個實例同時運行在同一個CPU就更不可能了。 

  如果被保護的共享資源只在兩個或多個tasklet或timer上下文訪問,那么對共享資源的訪問僅需要用spin_lock和spin_unlock來保護,不必使用_bh版本,因為當tasklet或timer運行時,不可能有其他tasklet或timer在當前CPU上運行。 

  如果被保護的共享資源只在一個軟中斷(tasklet和timer除外)上下文訪問,那么這個共享資源需要用spin_lock和spin_unlock來保護,因為同樣的軟中斷可以同時在不同的CPU上運行。 

  如果被保護的共享資源在兩個或多個軟中斷上下文訪問,那么這個共享資源當然更需要用spin_lock和spin_unlock來保護,不同的軟中斷能夠同時在不同的CPU上運行。 

  如果被保護的共享資源在軟中斷(包括tasklet和timer)或進程上下文和硬中斷上下文訪問,那么在軟中斷或進程上下文訪問期間,可能被硬中斷打斷,從而進入硬中斷上下文對共享資源進行訪問,因此,在進程或軟中斷上下文需要使用spin_lock_irq和spin_unlock_irq來保護對共享資源的訪問。 

  而在中斷處理句柄中使用什么版本,需依情況而定,如果只有一個中斷處理句柄訪問該共享資源,那么在中斷處理句柄中僅需要spin_lock和spin_unlock來保護對共享資源的訪問就可以了。 

  因為在執行中斷處理句柄期間,不可能被同一CPU上的軟中斷或進程打斷。但是如果有不同的中斷處理句柄訪問該共享資源,那么需要在中斷處理句柄中使用spin_lock_irq和spin_unlock_irq來保護對共享資源的訪問。 

  在使用spin_lock_irq和spin_unlock_irq的情況下,完全可以用spin_lock_irqsave和spin_unlock_irqrestore取代,那具體應該使用哪一個也需要依情況而定,如果可以確信在對共享資源訪問前中斷是使能的,那么使用spin_lock_irq更好一些。 

  因為它比spin_lock_irqsave要快一些,但是如果你不能確定是否中斷使能,那么使用spin_lock_irqsave和spin_unlock_irqrestore更好,因為它將恢復訪問共享資源前的中斷標志而不是直接使能中斷。 

  當然,有些情況下需要在訪問共享資源時必須中斷失效,而訪問完后必須中斷使能,這樣的情形使用spin_lock_irq和spin_unlock_irq最好。 

  需要特別提醒讀者,spin_lock用于阻止在不同CPU上的執行單元對共享資源的同時訪問以及不同進程上下文互相搶占導致的對共享資源的非同步訪問,而中斷失效和軟中斷失效卻是為了阻止在同一CPU上軟中斷或中斷對共享資源的非同步訪問。    
  

#include <linux/spinlock.h>

頭文件:
#include<linux/spinlock_types.h>

#ifndef __LINUX_SPINLOCK_TYPES_H
#define __LINUX_SPINLOCK_TYPES_H

/*
 * include/linux/spinlock_types.h - generic spinlock type definitions
 *                                  and initializers
 *
 * portions Copyright 2005, Red Hat, Inc., Ingo Molnar
 * Released under the General Public License (GPL).
 
*/

//對稱多處理器
#if defined(CONFIG_SMP)
    #include <asm/spinlock_types.h>
#else
    #include <linux/spinlock_types_up.h>
#endif

#include <linux/lockdep.h>

typedef struct {
    raw_spinlock_t raw_lock;
#ifdef CONFIG_GENERIC_LOCKBREAK
    unsigned int break_lock;
#endif
} spinlock_t;

#define SPINLOCK_MAGIC        0xdead4ead

typedef struct {
    raw_rwlock_t raw_lock;
#ifdef CONFIG_GENERIC_LOCKBREAK
    unsigned int break_lock;
#endif
} rwlock_t;

#define RWLOCK_MAGIC        0xdeaf1eed

#define SPINLOCK_OWNER_INIT    ((void *)-1L)

# define __SPIN_LOCK_UNLOCKED(lockname) \
    (spinlock_t)    {    .raw_lock = __RAW_SPIN_LOCK_UNLOCKED,    \
                SPIN_DEP_MAP_INIT(lockname) }
#define __RW_LOCK_UNLOCKED(lockname) \
    (rwlock_t)    {    .raw_lock = __RAW_RW_LOCK_UNLOCKED,    \
                RW_DEP_MAP_INIT(lockname) }

/*
 * SPIN_LOCK_UNLOCKED and RW_LOCK_UNLOCKED defeat lockdep state tracking and
 * are hence deprecated.
 * Please use DEFINE_SPINLOCK()/DEFINE_RWLOCK() or
 * __SPIN_LOCK_UNLOCKED()/__RW_LOCK_UNLOCKED() as appropriate.
 
*/
#define SPIN_LOCK_UNLOCKED    __SPIN_LOCK_UNLOCKED(old_style_spin_init)
#define RW_LOCK_UNLOCKED    __RW_LOCK_UNLOCKED(old_style_rw_init)

#define DEFINE_SPINLOCK(x)    spinlock_t x = __SPIN_LOCK_UNLOCKED(x)
#define DEFINE_RWLOCK(x)    rwlock_t x = __RW_LOCK_UNLOCKED(x)

#endif /* __LINUX_SPINLOCK_TYPES_H */
  

posted on 2013-04-12 18:21 天下 閱讀(1894) 評論(0)  編輯 收藏 引用 所屬分類: kernel & Driver

<2015年10月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

導航

統計

常用鏈接

留言簿(4)

隨筆分類(378)

隨筆檔案(329)

鏈接

最新隨筆

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久久精品动漫| 久久久久国产精品午夜一区| 老司机久久99久久精品播放免费 | 国产精品午夜视频| 欧美一级欧美一级在线播放| 亚洲免费视频在线观看| 国产一区二区精品在线观看| 久久综合久久久| 欧美日韩在线影院| 久久久久久成人| 国产精品观看| 欧美黄色大片网站| 国产亚洲一区在线播放| 亚洲国产毛片完整版| 欧美成人综合网站| 欧美午夜精品理论片a级按摩| 欧美在线视频网站| 欧美精品久久久久久久| 久久久水蜜桃av免费网站| 欧美黄免费看| 亚洲精品欧美日韩专区| 99在线精品观看| 久久久久免费| 日韩一区二区电影网| 欧美一区二区三区在线免费观看| 校园春色综合网| 欧美日韩国产免费观看| 久久乐国产精品| 国产日韩欧美一区| 亚洲深夜av| 午夜视频在线观看一区| 欧美日韩亚洲综合| 日韩视频免费观看高清在线视频| 亚洲精品1234| 欧美激情精品久久久久久黑人 | 亚洲免费福利视频| 国产丝袜一区二区| 久久亚洲不卡| 欧美激情aⅴ一区二区三区| 国产午夜亚洲精品不卡| 欧美综合国产| 欧美国产亚洲视频| 亚洲主播在线观看| 国产视频亚洲| 欧美黑人在线观看| 亚洲午夜久久久久久久久电影院| 欧美中文在线观看国产| 精品动漫3d一区二区三区免费| 欧美91大片| 午夜日韩电影| 国产欧美在线| 欧美久久久久免费| 久久香蕉国产线看观看网| 巨胸喷奶水www久久久免费动漫| 亚洲成人自拍视频| 欧美视频手机在线| 欧美成人影音| 麻豆av福利av久久av| 亚洲欧美日韩视频二区| 最新成人av网站| 久久人体大胆视频| 性久久久久久久久久久久| 亚洲美女性视频| 黄色综合网站| 亚洲黄色天堂| 亚洲黄色在线观看| 亚洲精品视频在线播放| 亚洲国产成人高清精品| 激情欧美日韩| 亚洲国产精品久久精品怡红院| 狠狠色2019综合网| 影音先锋亚洲电影| 伊人狠狠色j香婷婷综合| 国内偷自视频区视频综合| 国产欧美日韩视频一区二区| 国产精品一区二区三区成人| 国产日韩亚洲欧美综合| 国内精品久久久久久久果冻传媒| 激情偷拍久久| 一区二区三区欧美在线| 欧美在线高清| 亚洲大胆av| 亚洲欧美在线另类| 欧美va天堂va视频va在线| 欧美日韩亚洲天堂| 国产亚洲一二三区| 一区二区激情| 欧美一区二区三区视频在线| 久久精品国产亚洲5555| 欧美国产第二页| 亚洲欧美日韩另类| 欧美激情一区在线| 在线亚洲精品福利网址导航| 性伦欧美刺激片在线观看| 久久久噜噜噜久久| 国产日韩一区二区三区在线播放| 在线日韩成人| 麻豆九一精品爱看视频在线观看免费| 亚洲高清不卡在线| 久久这里有精品视频| 久久激情视频| 免费亚洲视频| 亚洲第一色中文字幕| 久久精品国产视频| 亚洲欧美另类久久久精品2019| 国产精品劲爆视频| 亚洲欧美三级在线| 亚洲一区二区三区乱码aⅴ蜜桃女| 欧美日韩在线影院| 亚洲天堂免费观看| 午夜在线成人av| 精品成人一区| 亚洲欧洲日韩综合二区| 国产精品成人在线观看| 亚洲一区精品在线| 欧美一区二区三区免费观看| 国语自产精品视频在线看抢先版结局| 久久久精品动漫| 欧美国产日韩一区二区在线观看 | 欧美大片免费观看在线观看网站推荐 | 亚洲在线1234| 日韩视频一区二区三区| 母乳一区在线观看| 亚洲第一福利视频| 免费在线国产精品| 一二三区精品| 欧美福利在线| 亚洲福利视频三区| 老司机免费视频一区二区| 蜜桃久久av| 亚洲视频一区| 午夜日韩电影| 亚洲欧美激情视频| 一本色道久久综合亚洲精品高清 | 麻豆精品在线观看| 午夜精品婷婷| 欧美精品久久99久久在免费线| 亚洲一区国产视频| 欧美激情视频一区二区三区在线播放| 亚洲午夜女主播在线直播| 久久久国产亚洲精品| 亚洲综合不卡| 欧美日韩国产黄| 免费在线国产精品| 亚洲久久一区| 欧美连裤袜在线视频| 免费欧美在线| 黄色精品在线看| 久久精品国产欧美激情| 久久久蜜桃一区二区人| 伊人久久久大香线蕉综合直播| 99在线精品视频| 亚洲一区二区三区在线| 国产精品日韩久久久久| 亚洲欧美在线x视频| 久久精品国产69国产精品亚洲| 国产精品久久久久久久久久妞妞 | 亚洲国产毛片完整版| 最近中文字幕日韩精品 | 欧美激情性爽国产精品17p| 99精品99| 国产欧美日韩亚州综合| 久久激情久久| 一区二区三区免费网站| 亚洲欧美综合另类中字| 国内精品一区二区三区| 免费欧美高清视频| 亚洲性夜色噜噜噜7777| 欧美激情精品久久久久久大尺度| 亚洲网在线观看| 国产亚洲精品久久久久婷婷瑜伽 | 欧美在线视频免费播放| 亚洲精品久久久久久久久久久久久 | 久久精品亚洲国产奇米99| 99国产精品| 在线视频国内自拍亚洲视频| 欧美精品亚洲| 欧美精品成人在线| 免费视频一区| 亚洲午夜一二三区视频| 免播放器亚洲| 欧美成人精品1314www| 久久成人综合视频| 欧美一区二粉嫩精品国产一线天| 亚洲精品永久免费| 在线观看欧美成人| 亚洲高清在线观看| 亚洲国产成人av在线| 一区二区在线观看视频在线观看 | 91久久一区二区| 中日韩男男gay无套| 亚洲午夜在线视频| 亚洲色图综合久久| 一区二区欧美激情| 亚洲午夜在线视频| 久久xxxx精品视频| 久久亚洲欧洲| 亚洲精品护士| 欧美制服第一页| 欧美日韩精品高清|