Chinaunix

标题: 单核arm中spin_lock没有被实现,请问这时用什么机制在中断中做同步? [打印本页]

作者: tassard    时间: 2010-07-06 16:45
标题: 单核arm中spin_lock没有被实现,请问这时用什么机制在中断中做同步?
下面代码的运行平台是单核arm,使用spin_lock保证对reg_atomic_1和reg_atomic_2的原子访问,但是查阅一些资料后发现在单核arm平台上spin_lock没有实现!!那请问下面的代码要怎么在中断中做同步?谢谢。

附代码:

int reg_atomic_1 = 0;
int reg_atomic_2 = 0;

void test()
{
    unsigned long iflags;
    spin_lock_irqsave(lock, iflags);

    reg_atomic_1 = 1;
    reg_atomic_2 = 1;

    spin_unlock_irqrestore(lock, iflags);
}

static irqreturn_t irq_func(int irq, void *dev_id)
{
    unsigned long iflags;
    spin_lock_irqsave(lock, iflags);

    reg_atomic_1 = 2;
    reg_atomic_2 = 2;

    spin_unlock_irqrestore(lock, iflags);
}
作者: kgn28    时间: 2010-07-06 17:00
回复 1# tassard


    不需要修改吧,见这个帖子的讨论:http://linux.chinaunix.net/bbs/thread-1166513-1-1.html
作者: snail_314    时间: 2010-07-06 17:04
回复 1# tassard


    spin_lock不管在什么平台上都没有实现,因为,没有这个需求(既然都单核了,就不会出现非中断的执行序并行执行了).
但是,spin_lock未实现并不意味着spin_lock_irqsave是个空操作,它至少还有关中断\保护现场的操作,而spin_lock_irqrestore也有恢复现场\开中断的操作.所以,执行序和中断历程之间还是有保护的,赫赫
作者: jinxinxin163    时间: 2010-07-06 21:52
在up下,spin_lock_irqsave的功能退化为“关闭本地cpu的中断”,下面这个网址对你的问题应该有所帮助
http://blog.chinaunix.net/u2/73067/showart_2046163.html
作者: tassard    时间: 2010-07-07 15:58
谢谢各位,关于spin_lock_irq我明白了,但是还有个问题。
我查了下源代码,发现spin_lock_irq是会关闭中断的,但是spin_lock函数就不会,那既然这样的话,为什么kernel的handle_edge_irq会使用spin_lock函数而不是spin_lock_irq?这样会不会破坏共享数据?谢谢。

void
handle_edge_irq(unsigned int irq, struct irq_desc *desc)
{
        spin_lock(&desc->lock);

        desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);

        /*
         * If we're currently running this IRQ, or its disabled,
         * we shouldn't process the IRQ. Mark it pending, handle
         * the necessary masking and go out
         */
        if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) ||
                    !desc->action)) {
                desc->status |= (IRQ_PENDING | IRQ_MASKED);
                mask_ack_irq(desc, irq);
                goto out_unlock;
        }
        kstat_incr_irqs_this_cpu(irq, desc);

        /* Start handling the irq */
        if (desc->chip->ack)
                desc->chip->ack(irq);

        /* Mark the IRQ currently in progress.*/
        desc->status |= IRQ_INPROGRESS;

        do {
                struct irqaction *action = desc->action;
                irqreturn_t action_ret;

                if (unlikely(!action)) {
                        desc->chip->mask(irq);
                        goto out_unlock;
                }

                /*
                 * When another irq arrived while we were handling
                 * one, we could have masked the irq.
                 * Renable it, if it was not disabled in meantime.
                 */
                if (unlikely((desc->status &
                               (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) ==
                              (IRQ_PENDING | IRQ_MASKED))) {
                        desc->chip->unmask(irq);
                        desc->status &= ~IRQ_MASKED;
                }

                desc->status &= ~IRQ_PENDING;
                spin_unlock(&desc->lock);
                action_ret = handle_IRQ_event(irq, action);
                if (!noirqdebug)
                        note_interrupt(irq, desc, action_ret);
                spin_lock(&desc->lock);

        } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);

        desc->status &= ~IRQ_INPROGRESS;
out_unlock:
        spin_unlock(&desc->lock);
}
作者: nettom    时间: 2010-07-08 04:23
spin_lock 和spin_unlock使用的前提是中断处理程序和锁之间没有交互




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2