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

天下

記錄修行的印記

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

<2012年8月>
2930311234
567891011
12131415161718
19202122232425
2627282930311
2345678

導航

統計

常用鏈接

留言簿(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>
            一区二区久久久久久| 久久久久久自在自线| 国产精品社区| 翔田千里一区二区| 久久另类ts人妖一区二区| 伊人久久亚洲热| 欧美黄色成人网| 欧美大片在线观看一区| 亚洲国产精品va在线看黑人| 欧美日韩dvd在线观看| 亚洲中字在线| 欧美高清视频在线播放| 亚洲视频在线视频| 国一区二区在线观看| 欧美乱在线观看| 午夜精品视频一区| 亚洲精品韩国| 美女黄毛**国产精品啪啪| 狠狠色噜噜狠狠狠狠色吗综合| 欧美国产大片| 性欧美1819性猛交| 欧美成人a∨高清免费观看| 亚洲一区久久久| 影视先锋久久| 国产日韩欧美电影在线观看| 欧美久久影院| 久久综合色一综合色88| 一本色道久久综合亚洲精品按摩 | 在线观看成人小视频| 亚洲一区二区三区四区五区午夜 | 亚洲免费av观看| 欧美高清视频在线| 久久久99国产精品免费| 亚洲影院高清在线| 一本色道综合亚洲| 亚洲美女91| 亚洲韩日在线| 国产亚洲欧美日韩日本| 欧美性猛交xxxx免费看久久久| 久久国产精品99国产| 亚洲欧美成人一区二区三区| 日韩一级精品| 亚洲精品小视频在线观看| 免费在线成人av| 久久亚洲精品一区| 久久蜜桃av一区精品变态类天堂| 亚洲精品1区2区| 在线日韩av片| 亚洲高清视频在线| 精久久久久久| 精品av久久久久电影| 国产亚洲欧美中文| 国产一区久久久| 国产亚洲美州欧州综合国| 国产麻豆视频精品| 国产农村妇女精品一区二区| 欧美午夜国产| 欧美日韩在线视频一区二区| 欧美日韩午夜激情| 国产精品第13页| 国产精品美女午夜av| 国产精品久久7| 国产美女诱惑一区二区| 国产精品永久免费在线| 欧美日韩亚洲不卡| 欧美.www| 久久亚洲一区二区| 香蕉国产精品偷在线观看不卡| 亚洲欧美国产高清va在线播| 日韩一级黄色片| 91久久香蕉国产日韩欧美9色| 欧美ab在线视频| 美女图片一区二区| 欧美88av| 日韩写真在线| 欧美在线免费视屏| 久久精品91久久香蕉加勒比| 久久精品一区二区| 欧美成人免费全部| 欧美新色视频| 国产精品私人影院| 国产亚洲精品久久久久久| 亚洲电影网站| 亚洲激情二区| 亚洲自拍偷拍色片视频| 久久综合九色综合欧美狠狠| 亚洲国产毛片完整版| 一区二区三区www| 久久久久综合| 国产精品国产三级国产专区53 | 国产精品免费一区二区三区观看| 国产日韩精品久久| 亚洲精品视频在线| 亚洲一区久久久| 免费亚洲电影| 一片黄亚洲嫩模| 久久精品国内一区二区三区| 欧美日韩亚洲综合在线| 伊伊综合在线| 久久国产免费看| 亚洲欧洲在线视频| 久久久久青草大香线综合精品| 国产精品xvideos88| 亚洲国产精品一区二区三区| 一区二区动漫| 欧美激情视频网站| 久久国产天堂福利天堂| 国产精品久久国产精品99gif| 亚洲激情成人| 免费成人黄色av| 久久精品欧美日韩| 国产一区二区久久久| 西西人体一区二区| 亚洲精品在线一区二区| 美女网站在线免费欧美精品| 国模精品一区二区三区| 午夜精品国产更新| 9色porny自拍视频一区二区| 欧美精品三区| 欧美高清在线视频| 亚洲视频1区| 欧美全黄视频| 亚洲福利视频二区| 久久精品国产v日韩v亚洲| 99精品视频免费观看视频| 另类天堂视频在线观看| 国产日韩欧美精品| 欧美一区二区大片| 中国成人黄色视屏| 国产精品久久久久久久电影 | 亚洲第一天堂无码专区| 久久免费国产| 久久爱www久久做| 国内伊人久久久久久网站视频| 欧美在线一二三| 一区二区不卡在线视频 午夜欧美不卡'| 久久精品国产亚洲一区二区| 激情丁香综合| 欧美黑人一区二区三区| 欧美1区2区| 一本久久综合亚洲鲁鲁| 亚洲色在线视频| 国产欧美在线视频| 久久精品成人欧美大片古装| 欧美在线影院在线视频| 亚洲国产激情| 亚洲免费久久| 国产精品理论片| 久久精品人人做人人爽电影蜜月| 欧美一级免费视频| 好看不卡的中文字幕| 欧美激情视频在线播放| 欧美精品免费视频| 亚洲免费在线观看视频| 久久精品一区二区国产| 亚洲国产欧美久久| 亚洲精品欧美一区二区三区| 国产精品亚洲精品| 欧美a级一区二区| 欧美性大战久久久久久久蜜臀| 久久久久久久一区| 欧美日本一道本在线视频| 欧美一二三区精品| 欧美风情在线观看| 久久精品在线播放| 欧美黑人在线观看| 欧美怡红院视频| 欧美精品一区三区在线观看| 久久爱www.| 欧美日韩国产首页| 久久性色av| 国产精品视频男人的天堂| 欧美高清视频一区二区| 国产色视频一区| 亚洲精品欧美一区二区三区| 黄色工厂这里只有精品| 宅男精品视频| 日韩性生活视频| 久久久久久久久伊人| 欧美一区二区免费| 久久中文欧美| 欧美日韩一区三区| 欧美一区二区三区视频在线观看| 蜜臀久久久99精品久久久久久| 午夜精品影院| 欧美日韩中文在线| 你懂的亚洲视频| 国内欧美视频一区二区| 一区二区三区|亚洲午夜| 国产无遮挡一区二区三区毛片日本| 亚洲精品一区在线观看香蕉| 亚洲电影网站| 亚洲欧美一区二区三区在线| 亚洲一区二区毛片| 欧美日韩99| 亚洲精品久久久久| 亚洲精品少妇30p| 欧美wwwwww| 亚洲国产精品尤物yw在线观看 | 欧美在线免费观看视频|