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

天下

記錄修行的印記

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>
            国产日韩成人精品| 国产精品99免费看 | 亚洲精品欧美在线| 欧美大片91| 在线一区二区三区四区| 9i看片成人免费高清| 国产精品成人一区二区三区吃奶| 亚洲午夜一区| 午夜精品久久久久久久久久久| 国产精品一区二区黑丝| 久久久久久久精| 美女黄色成人网| 一区二区三区欧美| 午夜精品久久久久99热蜜桃导演| 国产小视频国产精品| 免费永久网站黄欧美| 欧美日韩成人一区| 久久精品国产免费看久久精品| 久久久一区二区三区| 日韩一级黄色大片| 午夜激情亚洲| 亚洲乱码国产乱码精品精可以看| 一区电影在线观看| 韩国一区电影| 99综合在线| 亚洲高清久久网| 一区二区三区四区五区精品视频| 国内久久视频| 亚洲区免费影片| 国产私拍一区| 99国产精品久久久久久久| 国产亚洲视频在线观看| 亚洲精品午夜| 在线观看视频亚洲| 一区二区三区四区五区精品| 亚洲高清毛片| 亚洲欧美资源在线| 一区二区三区视频在线看| 久久久久免费视频| 性久久久久久久久| 亚洲国产成人久久综合| 国产麻豆午夜三级精品| 亚洲国产成人av好男人在线观看| 国产精品综合久久久| 亚洲国产小视频在线观看| 国产主播一区二区三区四区| 99精品视频免费观看| 亚洲黄网站在线观看| 久久成人精品电影| 欧美一区免费视频| 欧美午夜一区二区福利视频| 欧美激情一区二区三区在线视频观看| 国产老肥熟一区二区三区| 日韩视频免费在线| 亚洲美洲欧洲综合国产一区| 久久女同精品一区二区| 久久久久久久波多野高潮日日| 国产精品久久久久7777婷婷| 日韩午夜在线观看视频| 亚洲乱码视频| 欧美激情影院| 亚洲日本中文字幕免费在线不卡| 亚洲国产成人午夜在线一区| 久久婷婷蜜乳一本欲蜜臀| 久久综合久色欧美综合狠狠| 国产日韩亚洲欧美| 欧美在线视频一区二区| 久久国产综合精品| 国产亚洲激情视频在线| 久久福利一区| 久久亚洲精品一区| 在线观看亚洲视频啊啊啊啊| 久久久xxx| 欧美高清视频在线观看| 亚洲精品一区二区在线| 欧美极品aⅴ影院| 亚洲欧洲偷拍精品| 亚洲午夜国产一区99re久久 | 久久中文精品| 国产欧美日韩综合一区在线观看| 亚洲午夜一区二区三区| 欧美亚洲视频| 国内精品久久久久伊人av| 久久精品二区三区| 欧美高清在线视频观看不卡| 91久久久在线| 欧美日韩一区二区三区视频| 亚洲深夜福利视频| 久久综合导航| 亚洲精品欧洲精品| 欧美性事在线| 久久国产欧美日韩精品| 亚洲高清视频一区| 小黄鸭精品密入口导航| 一区二区亚洲欧洲国产日韩| 欧美成在线视频| 一本色道久久加勒比精品| 亚洲欧美日韩一区在线| 欧美xxxx在线观看| 午夜一级在线看亚洲| 久久人人爽人人爽| 亚洲美女网站| 国产亚洲欧美aaaa| 欧美激情第10页| 午夜精品福利在线| 亚洲精品少妇| 国产一区二区三区久久悠悠色av | 亚洲欧美日韩爽爽影院| 免费国产自线拍一欧美视频| 一本在线高清不卡dvd| 国产日韩精品入口| 欧美精品久久天天躁| 欧美一级在线播放| 日韩亚洲国产精品| 免费在线观看成人av| 久久精品日产第一区二区三区| 激情久久久久久久久久久久久久久久| 欧美大片18| 欧美在线综合视频| 一本一道久久综合狠狠老精东影业| 久久久久久久网| 亚洲欧美美女| 一区二区精品国产| 亚洲国产日韩美| 国产一区亚洲一区| 国产精品色午夜在线观看| 欧美成人自拍| 久久午夜色播影院免费高清| 亚洲自拍16p| 一区二区国产日产| 亚洲日本中文字幕| 欧美激情精品久久久久久久变态| 欧美一区二区三区视频免费| 99精品国产一区二区青青牛奶 | 玖玖视频精品| 久久免费黄色| 欧美中文在线观看| 亚洲欧美日韩精品久久奇米色影视| 91久久亚洲| 亚洲大胆人体视频| 欧美成人性生活| 美女日韩在线中文字幕| 久久青青草综合| 久久综合导航| 欧美不卡视频| 欧美激情91| 亚洲国产精品日韩| 亚洲国产精品一区二区第一页| 欧美成在线观看| 亚洲电影在线播放| 亚洲精品美女| 中日韩美女免费视频网址在线观看| 日韩小视频在线观看| 亚洲精品久久久蜜桃| 亚洲另类自拍| 亚洲综合色网站| 欧美一区二区三区四区高清| 欧美在线日韩| 米奇777在线欧美播放| 欧美国产亚洲精品久久久8v| 欧美黄色大片网站| 欧美视频一区二| 国产女精品视频网站免费 | 欧美成年人在线观看| 欧美色图天堂网| 国产欧美精品久久| 在线观看亚洲a| 亚洲伦理一区| 亚洲欧美日韩一区| 久久亚洲一区二区三区四区| 欧美刺激性大交免费视频| 亚洲日本一区二区三区| 亚洲综合色在线| 久久亚洲综合色| 欧美日韩国产精品一区| 国产欧美精品va在线观看| 亚洲国产精品一区二区尤物区| 一区二区精品在线观看| 久久久久久久久久久久久女国产乱| 亚洲大片av| 亚洲欧美日韩高清| 老司机凹凸av亚洲导航| 日韩视频中午一区| 欧美在线视频一区二区| 欧美日韩一区二区高清| 国产中文一区二区三区| av成人动漫| 久久婷婷国产麻豆91天堂| 亚洲理论电影网| 久久久久9999亚洲精品| 国产精品久久久久91| 最新日韩中文字幕| 久久久夜精品| 亚洲无人区一区| 欧美大片专区| 今天的高清视频免费播放成人 | 亚洲国产精品嫩草影院| 欧美亚洲免费| 亚洲精品日本| 老司机亚洲精品|