Contiki函数内的互斥

Mutual exclusion within a function Contiki

因为 Contiki 提供的内置列表不符合我的需要(使用太多内存),我已经实现了我自己的列表版本,该版本已针对我打算如何使用它进行了优化。

在任何时候,这些列表中的一个将由多个 processes/protothreads 操作(即 add/remove 个元素)。但是,additions/removals 不会出现在 process/protothread 块中,而是在一个函数中调用,该函数是通过 process/protothread.

发起的一系列函数调用调用的。

例如,

void funct2()
{
    // add or remove element from shared list
}

void func1()
{
    // some stuff
    func2();
    // more stuff
}

PROCESS_THREAD(temp1, ev, data)
{
    PROCESS_BEGIN();
    func1();
    PROCESS_END();
}

PROCESS_THREAD(temp2, ev, data)
{
    PROCESS_BEGIN();
    func1();
    PROCESS_END();
}

因此,我不能使用 Contiki 的内置机制来创建互斥量(通过使用 pt-sem.h),因为它必须出现在 process/protothread 块中。这是因为虽然我可以在实际进程块中创建一个锁(见下文),但这将导致阻塞进程的时间比必要的长得多

PROCESS_THREAD(temp2, ev, data)
{
    PROCESS_BEGIN();
    // get lock
    func1();
    // release lock
    PROCESS_END();
}

这是非常有问题的,因为从我的列表中添加和删除元素不是原子的;如果在向列表中删除或添加元素时发生中断,事情将无法正常运行。是否可以轻松地做我想做的事;即在函数调用中以原子方式从列表中添加和删除元素,而不是在 process/protothread 块中?

您似乎对原线程的作用感到困惑。 Protothread 方法是一种 合作 调度的形式。当执行流要求让出时,原线程只能在特定点让出。中断永远不能将执行流切换到另一个原线程。

所以,有两个不同的选择:

1) 如果您的列表同时从原线程和中断处理程序上下文访问,则您需要在禁用中断的情况下对列表进行所有修改。所以你的 lock/unlock 代码分别是 disable/enable 中断。

2) 如果您的列表只能从原线程访问,则不需要任何锁定。这是推荐的设计。

的确,使用 protothreads 的主要优点是在 99% 的情况下不需要锁。