Thread (Overview)


Introduction

A thread system is integrated into the NitroSDK. Each thread has an independent context and, by all appearances, is a mechanism that can make multiple modules operate in parallel.

A maximum of 16 threads can be created. (This is the default configuration.) This value is defined with OS_THREAD_MAX_NUM in $NitroSDK/include/nitro/os/common/thread.h. The maximum number of threads can be changed to 32 by altering this value. However, doing so requires more than just alterations to the header file—the library must also be rebuilt.

Call OS_InitThread() to initialize the thread system. Since calling OS_Init() will initialize the thread system by default, there is no need to call it in the application.

Use OS_IsThreadAvailable() to check whether or not the thread system has been initialized.

Since the program's own thread creation with OS_InitThread() and the creation of an idle thread is performed at thread system initialization, two threads will have already started at this point.


Thread State

The threads created with OS_CreateThread() cannot immediately be executed. These threads are still in a "pause state". Use OS_WakeupThreadDirect() to put them into an "executable state". (There are some cases where they are then executed as-is.)

The thread settings include an argument for priority. The thread with the highest priority among the threads in an executable state will run first. The priority is set when the thread is created, but it can be changed by using OS_SetThreadPriority(). The priorities range from 0 - 31. 0 is the highest-priority thread. If two or more threads have the same priority, it is uncertain which thread takes precedence. Also, there is a special idle thread with priority 32. This thread does nothing. Thread priorities can be obtained with OS_GetThreadPriority().

If a thread is ended with OS_ExitThread(), it will transition to the "end state".


Switching Threads

Below is a list of events that could possibly cause thread switching.

Thread switching also occurs if the message functions OS_SendMessage() or OS_ReceiveMessage() are blocked (because the system is in block mode), or if there is a thread with a higher priority that is waiting for a message to be sent or received.

There are also times when thread switching occurs due to thread exclusion control via mutex. This switching occurs when a thread is locked with OS_LockMutex(), and when a thread with a higher priority is unlocked with OS_UnlockMutex().


Interrupts and Switching Threads

Even if the function that causes thread switching is called inside the interrupt handler, the thread does not switch immediately. The fact that that event occurred is recorded and, when exiting from the handler, the control moves to the highest-priority executable thread.

In the example below, a function has been called that can switch the three threads (wakeup thread1, wakeup thread2, and wakeup thread3), but at that point it does nothing. When exiting from the interrupt handler, examine all threads and select a thread to be executed from among the executable threads.

In this diagram, it is assumed that the thread switched when there was an interrupt from thread0. If there is no need for thread switching to occur when executing thread0, the interrupts will need to be disabled. There is also the condition that thread0 not call a function that causes an interrupt.


Waking Up All Threads

Until control moves to a location where there is a separate thread, there may be cases where that thread wants to stop its execution. There may also be cases where multiple threads are to be awakened at the same time. In such cases, it is convenient to use the thread queue for wakeup.

By initializing the thread queue with OS_InitThreadQueue() and registering the threads for that queue with OS_SleepThread(), the registered threads will use that thread queue as an argument and go to sleep until OS_WakeupThread() is called. If OS_WakeupThread() is called, the threads registered in the designated thread queue will all go into an executable state, and thread re-scheduling will occur. (As a result, the thread priority of the executable threads will determine whether or not thread switching will occur.)


Thread Joining

It is possible to pause the currently running thread until a certain thread has ended. This operation appears as if the currently running thread and the ending thread have joined, therefore this will be called thread joining throughout this reference.

When in the paused state, the thread that is ending registers the thread for the internal thread queue with OS_JoinThread(). When the thread ends,the "joining" can take place by using the thread queue as an argument and calling OS_WakeupThread(). Multiple threads can be joined to a single thread.


Waiting... (Sleep)

It is possible to designate a time and use OS_Sleep() to go into a sleep mode for waiting. However, in order to do so, OS_InitTick() and OS_InitAlarm() must be called to initialize the tick system and the alarm system.

See Also

An Overview of OS Functions (Thread)

Revision History

11/09/2004 Initial version