2

I am working with contiki and trying to understand the terminology used in it. I am observing certain words such as yield, stackless here and there on internet. Some examples

PROCESS_EVENT_CONTINUE : This event is sent by the kernel to a process that is waiting in a PROCESS_YIELD() statement.
PROCESS_YIELD(); // Wait for any event, equivalent to PROCESS_WAIT_EVENT().
PROCESS_WAIT_UNTIL(); // Wait for a given condition; may not yield the process.

Does yielding a process means, executing a process in contiki. Also what does it mean that contiki is stackless.

Richard Chambers
  • 16,643
  • 4
  • 81
  • 106

2 Answers2

5

Contiki uses so-called protothreads (a Contiki-specific term) in order to support multiple application-level processes in this OS. Protothread is just a fancy name for a programming abstraction known as coroutine in computer science.

"Yield" in this context is short for "yield execution" (i.e. give up execution). It means "let other protothreads to execute until an event appears that is addressed to the current protothread". Such events can be generated both by other protothreads and by interrupt handler functions. The "wait" macros are similar, but allow to yield and wait for specific events or conditions.

Contiki protothreads are stackless in the sense that they all share the same global stack of execution, as opposed to "real" threads which typically get their own stack space. As a consequence, the values local variables are not preserved in Contiki protothreads across yields. For example, doing this is undefined behavior:

 int i = 1;
 PROCESS_YIELD();
 printf("i=%d\n", i); // <- prints garbage

The traditional Contiki way how deal with this limitation is to declare all protothread-local variables as static:

 static int i = 1;
 PROCESS_YIELD();
 printf("i=%d\n", i);

Other options is to use global variables, of course, but having a lot of global variables is bad programming style. The benefit of static variables declared inside protothread functions is that they are hidden from other functions (including other protothreads), even though at the low level they are allocated in the global static memory region.

kfx
  • 8,136
  • 3
  • 28
  • 52
  • very helpful. so a protothread can yield , or wait for an event, in the mean time while it is waiting another protothread can execute and can generate the event. now the first process will check the event and run the event routine. then after completing the event routine, process 1 will wait again or yield and control will return to process 2. – Mlo Bootloader Jan 05 '16 at 18:15
  • is waiting and yielding same? Also if there is a common stack, all variables of a process, will be visible to other processes? – Mlo Bootloader Jan 05 '16 at 18:15
1

In the general case, to "Yield" in any OS means to synchronously invoke the scheduler (i.e. on demand rather then through interrupt) in order to give the opportunity of control to some other thread. In an RTOS such a feature would only affect threads of the same priority, and may be used in addition or instead of pre-emptive round-robin scheduling is required. Most RTOS do not have an explicit yield function, or in some cases (such as VxWorks) the same effect can be achieved using a zero length delay.

In a cooperative scheduler such as that in Contiki, such a function is necessary to allow other threads to run in an otherwise non-blocking thread. A thread always has control until it calls a bocking or yielding function.

The cooperative nature of Contiki's scheduler mean that it cannot be classified as an RTOS. It may be possible to achieve real-time behaviour suitable to a specific application, but only through careful and appropriate application design, rather the through intrinsic scheduler behaviour.

Clifford
  • 88,407
  • 13
  • 85
  • 165