在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > Linux同步機制自旋鎖原理及其應用

            Linux同步機制自旋鎖原理及其應用

            作者: 時間:2012-04-05 來源:網絡 收藏

            一、

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

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

            本文引用地址:http://www.biyoush.com/article/257593.htm

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

            相關話題:SMP和cpu。多個cpu和單個cpu。很多書說自旋鎖只能在多處理機中使用,這是不正確的。
            首先定義
            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;
            補上x86平臺
            #define SPINLOCK_MAGIC 0x1D244B3C
            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像鎖孔,當沒有鑰匙插進去時,它才可以插進去。

            怎么初始化呢?

            #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 來調用自旋鎖,后者不允許中斷。前者有可能在上鎖中發(fā)生中斷。
            還有spin_trylock 這是一個絕不妥協(xié)的函數,它不等待。

            恢復為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); 保存中斷請求標志
            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,并關中斷
            preempt_disable(); 搶占鎖
            _raw_spin_lock_flags(lock, flags); 枷鎖
            return flags;
            }
            EXPORT_SYMBOL(_spin_lock_irqsave);
            繼續(xù)
            /* For spinlocks etc */
            #define local_irq_save(x) __asm__ __volatile__(pushfl ; popl %0 ; cli:=g (x): /* no input */ :memory)
            將標志寄存器的內容放在內存x中。請查看gcc匯編
            繼續(xù)
            static inline void _raw_spin_lock_flags (spinlock_t *lock, unsigned long flags)
            {
            #ifdef CONFIG_DEBUG_SPINLOCK
            if (unlikely(lock->magic != SPINLOCK_MAGIC)) {
            printk(eip: %p , __builtin_return_address(0));
            BUG();
            }
            #endif
            __asm__ __volatile__(
            spin_lock_string_flags
            :=m (lock->slock) : r (flags) : memory);
            }
            繼續(xù)
            #define spin_lock_string_flags
            1:
            lock ; decb %0 ;lock總線鎖住,原子操作
            jns 4f
            2:
            testl $0x200, %1
            jz 3f
            sti
            3:
            rep;nop
            cmpb $0, %0
            jle 3b
            cli
            jmp 1b
            4:
            理解一下大概意思,就可以了。當lock-1后大于等于0就可以關中斷繼續(xù)執(zhí)行了,否則nop空操作。Nop期間,cpu可以執(zhí)行其他任務的代碼。
            解鎖
            #define spin_unlock_irqrestore(lock, flags) _spin_unlock_irqrestore(lock, flags)
            void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
            {
            _raw_spin_unlock(lock);
            local_irq_restore(flags);
            preempt_enable();
            }
            static inline void _raw_spin_unlock(spinlock_t *lock)
            {
            #ifdef CONFIG_DEBUG_SPINLOCK
            BUG_ON(lock->magic != SPINLOCK_MAGIC);
            BUG_ON(!spin_is_locked(lock));
            #endif
            __asm__ __volatile__(
            spin_unlock_string
            );
            }
            Raw赤裸的解鎖,表示最低沉的解鎖原理。
            #define spin_unlock_string
            xchgb %b0, %1
            :=q (oldval), =m (lock->slock)
            :0 (oldval) : memory
            加1.解鎖

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


            評論


            相關推薦

            技術專區(qū)

            關閉