1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_TaskThread.cpp
4 
5   Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain proprietary
8   information of Nintendo and/or its licensed developers and are protected by
9   national and international copyright laws. They may not be disclosed to third
10   parties or copied or duplicated in any form, in whole or in part, without the
11   prior written consent of Nintendo.
12 
13   The content herein is highly confidential and should be handled accordingly.
14 
15   $Revision: 31311 $
16  *---------------------------------------------------------------------------*/
17 
18 #include "precompiled.h"
19 
20 #include <nw/snd/snd_TaskThread.h>
21 #include <nw/snd/snd_TaskManager.h>
22 #include <nw/snd/snd_DriverCommandManager.h>
23 
24 namespace nw {
25 namespace snd {
26 namespace internal {
27 
28 /*---------------------------------------------------------------------------*
29   Name:         TaskThread
30 
31   Description:  コンストラクタ
32 
33   Arguments:    なし
34 
35   Returns:      なし
36  *---------------------------------------------------------------------------*/
TaskThread()37 TaskThread::TaskThread()
38 : m_IsFinished( false ),
39   m_IsCreated( false )
40 {
41 }
42 
~TaskThread()43 TaskThread::~TaskThread()
44 {
45     if ( m_IsCreated )
46     {
47         Destroy();
48     }
49 }
50 
Create(s32 priority,ThreadStack & stack)51 bool TaskThread::Create( s32 priority, ThreadStack& stack )
52 {
53     NW_ALIGN4_ASSERT( stack.GetBaseAddress() );
54 
55     // 多重初期化チェック
56     if ( m_IsCreated )
57     {
58         Destroy();
59     }
60 
61     m_IsFinished = false;
62 
63     m_CriticalSection.Initialize();
64     bool result = m_Thread.TryStart(
65             ThreadFunc,
66             reinterpret_cast<uptr>(this),
67             stack,
68             priority ).IsSuccess();
69 
70     if ( result == false )
71     {
72         return false;
73     }
74 
75     m_IsCreated = true;
76 
77     return true;
78 }
79 
80 /*---------------------------------------------------------------------------*
81   Name:         Destroy
82 
83   Description:  タスクスレッドを終了する
84 
85   Arguments:    None.
86 
87   Returns:      None.
88  *---------------------------------------------------------------------------*/
Destroy()89 void TaskThread::Destroy()
90 {
91     if ( ! m_IsCreated )
92     {
93         return;
94     }
95 
96     // サウンドスレッド終了メッセージ送信
97     m_IsFinished = true;
98     TaskManager::GetInstance().CancelWaitTask();
99 
100     // スレッドの終了を待つ
101     m_Thread.Join();
102     m_Thread.Finalize();
103     m_CriticalSection.Finalize();
104 
105     m_IsCreated = false;
106 }
107 
108 /*---------------------------------------------------------------------------*
109   Name:         TaskThreadFunc
110 
111   Description:  サウンドスレッド関数
112 
113   Arguments:    arg - スレッドインスタンス
114 
115   Returns:      NULL
116  *---------------------------------------------------------------------------*/
ThreadFunc(uptr arg)117 void TaskThread::ThreadFunc( uptr arg )
118 {
119     TaskThread* taskThread = reinterpret_cast< TaskThread* >( arg );
120 
121     taskThread->ThreadProc();
122 }
123 
124 /*---------------------------------------------------------------------------*
125   Name:         TaskThreadProc
126 
127   Description:  タスクスレッドプロシージャ
128 
129   Arguments:    None.
130 
131   Returns:      None.
132  *---------------------------------------------------------------------------*/
ThreadProc()133 void TaskThread::ThreadProc()
134 {
135     while ( ! m_IsFinished )
136     {
137         TaskManager::GetInstance().WaitTask();
138         if ( m_IsFinished )
139         {
140             break;
141         }
142 
143         {
144             // NOTE: タスクスレッドのロック。
145             //
146             // SoundSystem::(Try)LockDataLoadThread 関数で外部からロックされることによって
147             // いったんスレッドが停止します。
148             //
149             // タスクスレッドはストリームデータのロードや、
150             // プレイヤーヒープへのデータロードを行いますが、
151             // 「スリープ中はファイルアクセス禁止」の制約に沿うため、
152             // このロックが追加されました。
153             nn::os::CriticalSection::ScopedLock lock( m_CriticalSection );
154             TaskManager::GetInstance().ExecuteTask();
155         }
156 
157         DriverCommandManager::GetInstanceForTaskThread().RecvCommandReply();
158     }
159 }
160 
GetInstance()161 TaskThread& TaskThread::GetInstance()
162 {
163     static TaskThread instance;
164     return instance;
165 }
166 
167 } // namespace nw::snd::internal
168 } // namespace nw::snd
169 } // namespace nw
170 
171