• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 嵌入式系統 > 設計應用 > Linux內核同步機制的自旋鎖原理及綜合應用實例

    Linux內核同步機制的自旋鎖原理及綜合應用實例

    作者: 時間:2012-03-30 來源:網絡 收藏

    一、

    本文引用地址:http://www.czjhyjcfj.com/article/149309.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_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像鎖孔,當沒有鑰匙插進去時,它才可以插進去


    怎么初始化呢?
    #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 來調用自旋鎖,后者不允許中斷。前者有可能在上鎖中發生中斷。
    還有spin_trylock 這是一個絕不妥協的函數,它不等待。


    恢復為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);

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

    上一頁 1 2 下一頁

    評論


    相關推薦

    技術專區

    關閉
    主站蜘蛛池模板: 图片| 吉木萨尔县| 蒙阴县| 天峨县| 霍山县| 玛多县| 灵武市| 化隆| 临西县| 阿尔山市| 休宁县| 屏东县| 博野县| 南宁市| 进贤县| 桓台县| 贺州市| 霸州市| 漳浦县| 连城县| 岑溪市| 贺兰县| 阜新| 中超| 五指山市| 衡南县| 石台县| 孙吴县| 南澳县| 南昌市| 台江县| 温州市| 共和县| 昌邑市| 盘山县| 敦化市| 长乐市| 阿尔山市| 宜春市| 孙吴县| 临漳县|