# 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.

- A thread was started.
  In other words, either `OS_WakeupThread()` or `OS_WakeupThreadDirect()` was called.
- A thread was put to sleep.
  In other words, `OS_SleepThread()` was called.
- The wait for another thread to end has started.
  `OS_JoinThread()` was called.
- A thread has ended.
  The function the thread was executing has ended and `OS_ExitThread()` was called.
- A thread re-scheduling was called.
  `OS_RescheduleThread()` was called.
- A thread priority has changed.
  `OS_SetThreadPriority()` was called.

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