A Sample Program with Two Threads

Below is a program that uses some of eCos' system calls. It creates two threads, each of which goes into an infinite loop in which it sleeps for a while (using cyg_thread_delay()). This code is found in the file twothreads.c in the examples directory.

eCos two-threaded program listing

#include <cyg/kernel/kapi.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

/* now declare (and allocate space for) some kernel objects,
  like the two threads we will use */
cyg_thread thread_s[2];	/* space for two thread objects */

char stack[2][4096];	/* space for two 4K stacks */

/* now the handles for the threads */
cyg_handle_t simple_threadA, simple_threadB;

/* and now variables for the procedure which is the thread */
cyg_thread_entry_t simple_program;

/* and now a mutex to protect calls to the C library */
cyg_mutex_t cliblock;

/* we install our own startup routine which sets up threads */
void cyg_user_start(void)
{
 printf("Entering twothreads' cyg_user_start() function\n");

 cyg_mutex_init(&cliblock);

 cyg_thread_create(4, simple_program, (cyg_addrword_t) 0,
	"Thread A", (void *) stack[0], 4096,
	&simple_threadA, &thread_s[0]);
 cyg_thread_create(4, simple_program, (cyg_addrword_t) 1,
	"Thread B", (void *) stack[1], 4096,
	&simple_threadB, &thread_s[1]);

 cyg_thread_resume(simple_threadA);
 cyg_thread_resume(simple_threadB);
}

/* this is a simple program which runs in a thread */
void simple_program(cyg_addrword_t data)
{
 int message = (int) data;
 int delay;

 printf("Beginning execution; thread data is %d\n", message);

 cyg_thread_delay(200);

 for (;;) {
 delay = 200 + (rand() % 50);

 /* note: printf() must be protected by a
 call to cyg_mutex_lock() */
 cyg_mutex_lock(&cliblock); {
 printf("Thread %d: and now a delay of %d clock ticks\n",
	message, delay);
 }
 cyg_mutex_unlock(&cliblock);
 cyg_thread_delay(delay);
 }
}

When you run the program (by typing continue at the (gdb) prompt) the output should look like this:

Starting program: BASE_DIR/examples/twothreads.exe
Entering twothreads' cyg_user_start()
function
Beginning execution; thread data is 0
Beginning execution; thread data is 1
Thread 0: and now a delay of 240 clock ticks
Thread 1: and now a delay of 225 clock ticks
Thread 1: and now a delay of 234 clock ticks
Thread 0: and now a delay of 231 clock ticks
Thread 1: and now a delay of 224 clock ticks
Thread 0: and now a delay of 249 clock ticks
Thread 1: and now a delay of 202 clock ticks
Thread 0: and now a delay of 235 clock ticks

Figure 13-1 shows how this multitasking program executes. Note that apart from the thread creation system calls, this program also creates and uses a mutex for synchronization between the printf() calls in the two threads. This is because the C library standard I/O (by default) is configured not to be thread-safe, which means that if more than one thread is using standard I/O they might corrupt each other. This is fixed by a mutual exclusion (or mutex) lockout mechanism: the threads do not call printf() until cyg_mutex_lock() has returned, which only happens when the other thread calls cyg_mutex_unlock().

You could avoid using the mutex by configuring the C library to be thread-safe (by selecting the component CYGSEM_LIBC_STDIO_THREAD_SAFE_STREAMS).