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

天下

記錄修行的印記

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精品国自产| 美女性感视频久久久| 91久久国产精品91久久性色| 久久精品官网| 欧美一区二区三区视频免费| 在线播放视频一区| 亚洲福利国产| 欧美日韩国产综合视频在线观看中文| 亚洲色图综合久久| 另类av一区二区| 欧美区日韩区| 99热在线精品观看| 99亚洲一区二区| 欧美日韩激情小视频| 亚洲精选久久| 欧美亚洲免费在线| 国产欧美日韩免费看aⅴ视频| 久久综合一区| 国产欧美日韩在线| 99re视频这里只有精品| 99成人免费视频| 久久久久久尹人网香蕉| 久久精品国产亚洲a| 国产小视频国产精品| 一区二区高清在线观看| 99www免费人成精品| 久久综合五月天婷婷伊人| 欧美在线综合视频| 欧美一区二区免费| 国产一区二区三区奇米久涩| 亚洲欧美日韩国产成人精品影院| 亚洲私拍自拍| 亚洲尤物视频在线| 麻豆成人在线| 欧美大色视频| 亚洲精品1区2区| 久久久久久久久久久久久女国产乱 | 一本色道久久综合亚洲精品小说| 久久国产精彩视频| 亚洲一区二区在线免费观看视频| 曰本成人黄色| 国语自产精品视频在线看| 国产精品国产三级国产普通话三级| 嫩草成人www欧美| 久久综合中文色婷婷| 久久久久国产成人精品亚洲午夜| 欧美亚洲一级片| 午夜宅男久久久| 久久精品水蜜桃av综合天堂| 国产色视频一区| 欧美日韩精品系列| 久久久精品一区二区三区| 亚洲一区影院| 亚洲激情女人| 亚洲国产国产亚洲一二三| 欧美在线91| 中日韩高清电影网| 亚洲精品一品区二品区三品区| 国产精品中文字幕欧美| 欧美日韩美女| 欧美另类99xxxxx| 美腿丝袜亚洲色图| 中文日韩在线视频| 国产日韩欧美在线一区| 亚洲天堂免费观看| 亚洲一区日韩在线| 久久久久国产成人精品亚洲午夜| 久久久久在线观看| 欧美成人亚洲成人| 国产精品美女一区二区在线观看 | 国产欧美一区二区三区国产幕精品| 欧美日韩视频不卡| 国产自产在线视频一区| 欧美韩日高清| 老司机精品视频一区二区三区| 这里只有精品视频在线| 亚洲国产高清aⅴ视频| 玖玖玖免费嫩草在线影院一区| 亚洲一区中文| 久久国产精品99久久久久久老狼| 这里只有精品视频| 亚洲欧美成aⅴ人在线观看| 经典三级久久| 国产亚洲精品高潮| 国产精品日日摸夜夜添夜夜av| 欧美日韩国产精品一区| 美女亚洲精品| 欧美/亚洲一区| 欧美人与性动交a欧美精品| 久久久噜噜噜久久久| 亚洲一品av免费观看| 在线一区免费观看| 欧美主播一区二区三区| 欧美影院在线| 欧美gay视频| av72成人在线| 午夜精品亚洲| 男人的天堂亚洲| 国产精品成人一区| 狠狠色狠狠色综合人人| 艳妇臀荡乳欲伦亚洲一区| 免费日韩av片| 国产欧美精品日韩| 亚洲区在线播放| 久久九九电影| 亚洲香蕉成视频在线观看| 另类欧美日韩国产在线| 国产精品久久国产愉拍| 亚洲精品美女91| 免费91麻豆精品国产自产在线观看| 91久久精品日日躁夜夜躁欧美| 亚洲午夜一区| 欧美日韩一区二区三区四区五区 | 媚黑女一区二区| 欧美亚洲专区| 一区二区三区**美女毛片| 久久福利毛片| 国产精品免费福利| 亚洲一区二区精品在线| 在线播放豆国产99亚洲| 久久激情视频| 午夜欧美不卡精品aaaaa| 欧美三级欧美一级| 在线综合欧美| 一本色道久久综合亚洲精品按摩 | 欧美肥婆在线| 国产一区二区在线观看免费| 影音国产精品| 久久蜜臀精品av| 久久欧美肥婆一二区| 亚洲黄色有码视频| 亚洲福利国产| 国产精品家庭影院| 久久综合九色综合久99| 欧美高清视频一区二区| 99re66热这里只有精品4| 亚洲私人影院在线观看| 国产欧美91| 亚洲狠狠丁香婷婷综合久久久| 欧美激情亚洲另类| 久久av一区二区三区| 亚洲欧美国产另类| 久久一区二区三区四区五区| 99热精品在线观看| 久久久久久久久综合| 亚洲性感美女99在线| 久久免费偷拍视频| 久久精品成人一区二区三区 | 激情综合视频| 日韩西西人体444www| 黑丝一区二区| 亚洲欧美久久久| 亚洲午夜精品17c| 欧美激情视频在线播放| 欧美高清在线视频观看不卡| 国产欧美大片| 亚洲综合99| 欧美在线免费观看亚洲| 国产精品福利在线观看网址| 亚洲免费成人| 一本色道综合亚洲| 欧美日韩免费一区二区三区视频| 欧美成人精品h版在线观看| 一区二区三区在线观看视频| 欧美影院久久久| 欧美不卡在线| 中国成人亚色综合网站| 欧美日韩爆操| 亚洲欧美日韩一区二区| 久久成人精品视频| 精品二区视频| 欧美精品久久久久久久免费观看| 欧美成人一区二免费视频软件| 亚洲国产高清自拍| 国产精品高潮呻吟久久| 午夜一级在线看亚洲| 亚洲成人在线视频播放 | 99精品视频免费观看视频| 欧美精品videossex性护士| 亚洲精品久久久久| 欧美日韩福利在线观看| 一本色道久久88综合日韩精品| 久久福利电影| 欧美中文字幕第一页| 毛片一区二区三区| 一区二区三区免费在线观看| 国产欧美一区二区三区视频| 老司机精品福利视频| 午夜免费电影一区在线观看| 亚洲精品亚洲人成人网| 看片网站欧美日韩| 亚洲美女诱惑| 精品av久久707|