0

Because the in built list provided by Contiki doesn't fit my needs (uses too much memory) I have implemented my own list version that has been optimized for how I intend to use it.

At any one time there will be a single one of these lists that will be operated on (i.e. add/remove elements) by multiple processes/protothreads. However, additions/removals do not occur within a process/protothread block, but instead are called within a function that is called through a series of function calls initiated by a process/protothread.

For example,

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();
}

As a result, I can't use Contiki's in built mechanisms to create a mutex (via using pt-sem.h) since it must appear within a process/protothread block. This is because while I could create a lock within the actual process block (see below), this will result in blocking processes for much longer than is necessary

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

This is very problematic since adding and removing elements from my list is not atomic; if an interrupt occurs while removing or adding an element to the list things will not behave properly. Is it possible to easily do what I want; namely atomically add and remove elements from a list within a function call as opposed to within a process/protothread block?

Richard Chambers
  • 16,643
  • 4
  • 81
  • 106
HXSP1947
  • 1,311
  • 1
  • 16
  • 39
  • _"additions/removals do not occur within a process/protothread block"_ is not true in your example `func1()` is called within a process block so therefore so is `func2()`, and anything called within either of those functions. The process block is not exited until `PROCESS_END()` is called. – Clifford May 28 '18 at 07:43
  • @Clifford his problem is that the semaphore code from `pt-sem.h` only work if called from the `PROCESS_THREAD` blocks, but not inside functions called from those blocks. – kfx May 29 '18 at 12:13
  • @kfx : As you say in your answer, if only accessed in cooperative threads, no mutex is necessary. I am not familiar with Contiki in particular, so I bow to your superior knowledge. Seems an odd design to me. – Clifford May 29 '18 at 15:00

1 Answers1

0

You seem to be confused about what protothreads do. The protothread approach is a form of cooperative scheduling. A protothread can only yield at specific points, when asked to yield by the execution flow. An interrupt can never switch the execution flow to another protothread.

So, there are two distinct options:

1) If your list is accessed both from protothread and from interrupt handler contexts, you need to do all modifications in the list with interrupts disabled. So your lock/unlock code is disable/enable interrupts, respectively.

2) If your list is only accessed from protothreads, you don't need any locking. This is the recommended design.

Indeed, the main advantage of using protothreads is that in 99% of cases locks are not needed.

kfx
  • 8,136
  • 3
  • 28
  • 52