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