新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > Linux內(nèi)核同步機(jī)制的自旋鎖原理

        Linux內(nèi)核同步機(jī)制的自旋鎖原理

        作者: 時間:2010-06-22 來源:網(wǎng)絡(luò) 收藏

        一、

        本文引用地址:http://www.104case.com/article/151777.htm

        鎖是專為防止多處理器并發(fā)而引入的一種鎖,它在中大量應(yīng)用于中斷處理等部分(對于單處理器來說,防止中斷處理中的并發(fā)可簡單采用關(guān)閉中斷的方式,即在標(biāo)志寄存器中關(guān)閉/打開中斷標(biāo)志位,不需要鎖)。

        自旋就是自己連續(xù)的循環(huán)等待。如果你有抱著你的愛人旋轉(zhuǎn)的經(jīng)歷,那么你應(yīng)該知道一件事情,為了安全,你不能旋轉(zhuǎn)太久,你的愛人如果頭昏,也想你早日釋放。是的,自旋的缺點(diǎn),就是它頻繁的循環(huán)直到等待鎖的釋放,將它用于可以快速完成的代碼中才好。

        自旋不能搶占,但能中斷。

        相關(guān)話題:SMP和cpu。多個cpu和單個cpu。很多書說自旋鎖只能在多處理機(jī)中使用,這是不正確的。

        首先定義
        Spinlock_t lock;
        對不起,我只能找到arm平臺的鎖了
        /*
        * ARMv6 Spin-locking.
        *
        * We (exclusively) read the old value, and decrement it. If it
        * hits zero, we may have won the lock, so we try (exclusively)
        * storing it.
        *
        * Unlocked value: 0
        * Locked value: 1
        */
        typedef struct {
        volatile unsigned int lock;
        #ifdef CONFIG_PREEMPT
        unsigned int break_lock;
        #endif
        } spinlock_t;
        補(bǔ)上x86平臺
        #define SPINLOCK_MAGIC0x1D244B3C
        typedef struct {
        unsigned long magic;
        volatile unsigned long lock;
        volatile unsigned int babble;
        const char *module; // 所屬模塊
        char *owner;
        int oline;
        } spinlock_t;
        Lock為0時可以用,1是等待。0像鎖孔,當(dāng)沒有鑰匙插進(jìn)去時,它才可以插進(jìn)去


        怎么初始化呢?
        #define spin_lock_init(x)
        do {
        (x)->magic = SPINLOCK_MAGIC;
        (x)->lock = 0; ;0初始化,表示可用
        (x)->babble = 5;
        (x)->module = __FILE__;
        (x)->owner = NULL;
        (x)->oline = 0;
        } while (0)
        定義一個自旋鎖的方法很有意思,
        Spinlock_t lock=?????

        可以通過spin_lock
        Spin_lock_irqsave 來調(diào)用自旋鎖,后者不允許中斷。前者有可能在上鎖中發(fā)生中斷。
        還有spin_trylock 這是一個絕不妥協(xié)的函數(shù),它不等待。


        恢復(fù)為spin_unlock
        Spin_unlock_irqrestore

        考查下面代碼
        #define spin_lock_irqsave(lock, flags)_spin_lock_irqsave(lock, flags)
        #define _spin_lock_irqsave(lock, flags)
        do {
        local_irq_save(flags); 保存中斷請求標(biāo)志
        preempt_disable(); 不允許搶占
        _raw_spin_lock(lock);
        __acquire(lock);
        } while (0)

        二、自旋鎖綜合使用
        下面是一個使用的例子,你可以使用source insight查到它
        /* never called when PTRS_PER_PMD > 1 */
        void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused)
        {
        unsigned long flags; /* can be called from interrupt context */

        spin_lock_irqsave(pgd_lock, flags); 枷鎖
        pgd_list_del(pgd);
        spin_unlock_irqrestore(pgd_lock, flags); 釋放
        }

        中斷枷鎖
        #define spin_lock_irqsave(lock, flags)_spin_lock_irqsave(lock, flags)
        分析
        unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock)
        {
        unsigned long flags;

        local_irq_save(flags); 將寄存器存入flags,并關(guān)中斷
        preempt_disable(); 搶占鎖
        _raw_spin_lock_flags(lock, flags); 枷鎖
        return flags;
        }
        EXPORT_SYMBOL(_spin_lock_irqsave);

        linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)

        上一頁 1 2 下一頁

        評論


        相關(guān)推薦

        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 漾濞| 靖远县| 杨浦区| 登封市| 中卫市| 遵义县| 南宁市| 房山区| 青冈县| 文昌市| 册亨县| 台东县| 屏南县| 大新县| 顺平县| 龙胜| 和硕县| 台东县| 勐海县| 嘉义市| 息烽县| 桓台县| 蒙城县| 牙克石市| 盐山县| 白朗县| 怀化市| 泗水县| 花莲市| 梓潼县| 江阴市| 酒泉市| 海阳市| 龙陵县| 宜昌市| 左贡县| 锡林郭勒盟| 安溪县| 益阳市| 岑溪市| 凭祥市|