5. Synchronization Objects

This chapter provides information about the class of synchronization objects that are provided with the OS library in the CTR-SDK.

5.1. Mutex and Critical Section Objects

Mutex objects and critical section objects are synchronization objects that are locked and released. These objects can be used for purposes of exclusive control. When such an object is locked by a thread, access to the resource from other threads is prohibited until the locking thread has released its lock.

As synchronization objects, mutex and critical section objects work basically the same way. But because of the points noted below, the use of critical section objects is highly recommended.

  • Faster speeds are realized with critical section objects in situations where large amounts of memory are used and where there are no conflicts in locking the objects.
  • There are limits on the number of mutex objects that can be created, but there are no such limits on critical section objects, and you can make as many of the objects as memory allows.

However, critical section objects do not inherit the thread priority and in some cases may end up with the opposite priority. As a result, you must be careful about exclusive control among threads with different priorities.

5.2. Event and LightEvent Objects

LightEvent (nn::os::LightEvent class), which is the provided light version of Event (nn::os::Event class), works the same as Event except for small differences, such as the inability to specify timeouts and the waiting for multiple objects. There are limits on the number of Event objects that you can create, but there are no such limits on LightEvent, and you can make as many of the objects as memory allows.

In some cases when using the CTR-SDK libraries, event objects are required. The use of LightEvent is recommended where threads are synchronized in the application.

In the code example shown below, the process of waiting by multiple objects is replicated using LightEvent.

Code 5-1. Example of Using LightEvent to Replicate WaitAny
nn::os::LightEvent event1, event2;
{
    event1.Initialize(false);
    event2.Initialize(false);
}
// ...
{
    while(!(event1.TryWait() | event2.TryWait()))
        nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(1));
}

LightEvent is initialized as an auto-reset event to wait for any of the LightEvent objects to become the signal state.

Code 5-2. Example of Using LightEvent to Replicate WaitAll
nn::os::LightEvent event1, event2;
{
    event1.Initialize(true);
    event2.Initialize(true);
}
// ...
{
    while(!(event1.TryWait() & event2.TryWait()))
        nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(1));
    // Clear Signal
    event1.ClearSignal();
    event2.ClearSignal();
}

This code example uses a manual reset event. If an auto-reset event had been used, the signal state would have been deleted by the TryWait function, and you would need to implement some measure like storing the bitwise OR in a bool type variable.

5.3. Semaphore and LightSemaphore Objects

The relation between Semaphore (nn::os::Semaphore class) and LightSemaphore (nn::os::LightSemaphore class) is the same as that between Event and LightEvent.


CONFIDENTIAL