内核中的锁


内核进程的竞争:
    加锁:
       
    等锁的三种方法:
        1.如果没有锁,不等解锁直接返回
        2.如果没有锁,就睡着等待解锁,当拿到锁之后,就会被唤醒,这种就是睡眠锁   ----》信号量 / 互斥体
        3.如果没有锁,就一直要锁,这种最消耗cpu资源    ----》 自旋锁 ,举个例子:如果有两个人(进程),一个进门去喝水了,先把门锁住(加锁),喝着喝着,然后另一个人又敲门,他想进来喝水,但是现在门还没有解锁,然后他就一直敲门(消耗资源),直到等到另一个人出来(解锁)。

/arm_emb/sync_way :

同步的方法:

    处于进程上下文的,自旋锁和互斥体和信号量都能用,加锁力度比较小,一般选用自旋锁。
    注意:这里所说的加锁力度就是,举个例子假如说一个人进门喝水的时候,他一进门就把门锁住了 (加锁),然后自己以很短的时间就把水喝完了,而另一个人也想进来喝水,门还没开但是距离开门 (解锁) 的时间很短了,假如说他现在睡了,然后另外一个人又立马解锁了,这个时候他又要被唤醒,这就有点消耗资源,所以用自旋锁比较好,敲一会门,然后就开了

    处于中断上下文的,必然选择用自旋锁,不能使用原子操作,如果给中断中加入


    1.自旋锁:    非睡眠锁,中断上下文,必然是自旋锁,但是这个最消耗cpu资源

    /******************************************/

    进程和进程间的竞争
    
    spinlock_t spin;
    
    spin_lock_init(&spin);
    
    //加锁
    spin_lock(&spin);
    
    //解锁
    spin_unlock(&spin);

    /*******************************************/

    中断和进程的竞争
    
    注意:cpsid i //汇编就是将 cpsr 寄存器的第 i 位置 1
    
    spinlock_t spin;
    
    //禁止中断并加锁
    spin_lock_irqsave(&spin,cpsr);
    
    //解锁并恢复中断
    spin_unlock_irqrestore(&spin,cpsr);

    /******************************************/
    
    中断的下半部和进程之间的竞争
    
    spinlock_t spin;
    
    //禁止中断下半部并加锁
    spin_lock_bh(&spin);
    
    //解锁并恢复中断下半部
    spin_unlock_bh(&spin);
    
    /*******************************************/


        
    2.互斥体:  睡眠锁,只允许锁的持有者只有一个

    /******************************************/
    进程和进程间的竞争
    
    struct mutex mutex;
    
    mutex_init(&mutex);
    
    //加锁
    mutex_lock(&mutex);
    
    //解锁
    mutex_unlock(&mutex);
    
    /******************************************/


    3.信号量:    睡眠锁,可以设置锁的持有者个数

    /*******************************************/
    进程和进程间的竞争
    
    //实例化信号量的结构体
    struct semaphore sema;
    
    // @ val 锁的持有者的个数
    static inline void sema_init(struct semaphore *sem, int val)
    
    //加一操作
    down();
    //减一操作
    up();

    //尝试获得信号量,不等待
    down_trylock();

    
    /******************************************/

        
    4.原子操作: 针对全局的整型的变量,比如在做 i++ 操作的时候,会出现竞争,这就需要原子操作

        //v 是原子类型的全局变量
        atomic_t v;

        //如果返回 0 表示原子操作失败,
        if (!atomic_dec_and_test(&v)) {
            atomic_inc(&v);    //
          return -EBUSY;
        }
            
        atomic_inc(&mydev.v);


中断和进程的加锁解锁:

    bne 1b  //不相等的话,则跳转到此行以上的 1 标号那里去

    ldrex 的这个 ex 表示内存独占

    中断产生 GIC 不停的给 cpu 触发中断
    

posted @ 2016-06-01 09:17  winfu  阅读(441)  评论(0编辑  收藏  举报