contikicontiki-process

How to run parallel processes in Contiki


I want to create two processes that should be executed parallelly. I am trying with following code:

PROCESS(hello_world_process, "Hello world process");
PROCESS(hello_world_process2, "Hello world process2");
AUTOSTART_PROCESSES(&hello_world_process,&hello_world_process2);
/*---------------------------------------------------------------------------*/
int i;
void program1(void)
{
    for (i=0;i<10;i++)
    {
        printf("%d from 1st process\n",i);  
    }
}

void program2(void)
{
    for (i=0;i<10;i++)
    {
        printf("%d from IIund process\n",i);    
    }
}


PROCESS_THREAD(hello_world_process, ev, data)
{
    PROCESS_BEGIN();
    program1();
    PROCESS_END();
}
PROCESS_THREAD(hello_world_process2, ev, data)
{
    PROCESS_BEGIN();
    program2();
    PROCESS_END();
}

But the second process is getting started after the completion of the first process.

Output:

Contiki-list-1532-g2ca33d4 started with IPV6, RPL
Rime started with address 1.2.3.4.5.6.7.8
MAC nullmac RDC nullrdc NETWORK sicslowpan
Tentative link-local IPv6 address fe80:0000:0000:0000:0302:0304:0506:0708
0 from 1st process
1 from 1st process
2 from 1st process
3 from 1st process
4 from 1st process
5 from 1st process
6 from 1st process
7 from 1st process
8 from 1st process
9 from 1st process
0 from IIund process
1 from IIund process
2 from IIund process
3 from IIund process
4 from IIund process
5 from IIund process
6 from IIund process
7 from IIund process
8 from IIund process
9 from IIund process

How I can execute both these processes parallelly?


Solution

  • Contiki processes are based on Dunkel's protothreads: http://dunkels.com/adam/pt/

    As such, they have some specifics:

    1. They are a form of cooperative multithreading. That means, the source code should explicitly tell at which point to yield the execution; this is not preemptive multithreading, where switching between threads happens automatically.
    2. They are implemented in C, a language that does not have good support for this out the box, so all protothread operations are limited to the main process function. Functions that are called from the main process function cannot yield, only the main function can.
    3. The processes share a common stack. The concept of thread-local (process-local) variable does not exist; static variables must be used instead to preserve values across multiple invocations of a single process.

    Your code has all of these problems:

    Try this code instead:

    PROCESS_THREAD(hello_world_process, ev, data)
    {
        static int i;
        PROCESS_BEGIN();
        for (i=0;i<10;i++)
        {
            printf("%d from 1st process\n",i);  
            process_poll(&hello_world_process2);
            PROCESS_YIELD();
        }
        PROCESS_END();
    }
    
    PROCESS_THREAD(hello_world_process2, ev, data)
    {
        static int i;
        PROCESS_BEGIN();
        for (i=0;i<10;i++)
        {
            printf("%d from IIund process\n",i);
            process_poll(&hello_world_process);
            PROCESS_YIELD();
        }
        PROCESS_END();
    }