1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: snd_TaskManager.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: 29467 $
14 *---------------------------------------------------------------------------*/
15
16 #include "precompiled.h"
17
18 #include <nw/snd/snd_TaskManager.h>
19
20 namespace nw {
21 namespace snd {
22 namespace internal {
23
24 /*---------------------------------------------------------------------------*
25 Name: GetInstance
26
27 Description: シングルトンのインスタンスを取得する
28
29 Arguments: なし
30
31 Returns: インスタンス
32 *---------------------------------------------------------------------------*/
GetInstance()33 TaskManager& TaskManager::GetInstance()
34 {
35 static TaskManager instance;
36 return instance;
37 }
38
39 /*---------------------------------------------------------------------------*
40 Name: TaskManager
41
42 Description: コンストラクタ
43
44 Arguments: None.
45
46 Returns: None.
47 *---------------------------------------------------------------------------*/
TaskManager()48 TaskManager::TaskManager()
49 : m_pCurrentTask( NULL ),
50 m_IsWaitTaskCancel( false )
51 {
52 }
53
Initialize()54 void TaskManager::Initialize()
55 {
56 m_CriticalSection.Initialize();
57 m_BlockingQueue.Initialize( m_MsgBuffer, THREAD_MESSAGE_BUFSIZE );
58 }
59
Finalize()60 void TaskManager::Finalize()
61 {
62 m_CriticalSection.Finalize();
63 m_BlockingQueue.Finalize();
64 }
65
66 /*---------------------------------------------------------------------------*
67 Name: AppendTask
68
69 Description: タスクリストにタスクを登録
70
71 Arguments: task - 登録するタスク
72 priority - タスクを登録するリストのプライオリティ
73
74 Returns: None.
75 *---------------------------------------------------------------------------*/
AppendTask(Task * task,TaskPriority priority)76 void TaskManager::AppendTask( Task* task, TaskPriority priority )
77 {
78 NW_MINMAXLT_ASSERT( priority, 0, PRIORITY_NUM );
79
80 nn::os::CriticalSection::ScopedLock scopeLock(m_CriticalSection);
81
82 task->m_Event.ClearSignal();
83 task->m_Status = Task::STATUS_APPEND;
84 m_TaskList[ priority ].PushBack( task );
85 m_BlockingQueue.TryEnqueue( static_cast<uptr>( MESSAGE_APPEND ) );
86 }
87
88 /*---------------------------------------------------------------------------*
89 Name: GetNextTask
90
91 Description: 次のタスクを取得する
92
93 Arguments: priority - タスクを抜き出すリストのプライオリティ
94 doRemove - リストから削除するかどうか
95
96 Returns: 取得したタスク
97 *---------------------------------------------------------------------------*/
GetNextTask(TaskPriority priority,bool doRemove)98 Task* TaskManager::GetNextTask( TaskPriority priority, bool doRemove )
99 {
100 NW_MINMAXLT_ASSERT( priority, 0, PRIORITY_NUM );
101
102 nn::os::CriticalSection::ScopedLock scopeLock(m_CriticalSection);
103
104 if ( m_TaskList[ priority ].IsEmpty() ) return NULL;
105
106 Task* task = &m_TaskList[ priority ].GetFront();
107 if ( doRemove ) {
108 m_TaskList[ priority ].PopFront();
109 }
110 return task;
111 }
112
113 /*---------------------------------------------------------------------------*
114 Name: PopTask
115
116 Description: 最優先のタスクを取り出す
117
118 Arguments: なし
119
120 Returns: 取り出したタスク
121 *---------------------------------------------------------------------------*/
PopTask()122 Task* TaskManager::PopTask()
123 {
124 nn::os::CriticalSection::ScopedLock scopeLock(m_CriticalSection);
125
126 Task* task = GetNextTask( PRIORITY_HIGH, true );
127 if ( task != NULL ) return task;
128
129 task = GetNextTask( PRIORITY_MIDDLE, true );
130 if ( task != NULL ) return task;
131
132 task = GetNextTask( PRIORITY_LOW, true );
133 if ( task != NULL ) return task;
134
135 return NULL;
136 }
137
138 /*---------------------------------------------------------------------------*
139 Name: PopTask
140
141 Description: 最優先のタスクを取得する(リストから削除しない)
142
143 Arguments: なし
144
145 Returns: 取得したタスク
146 *---------------------------------------------------------------------------*/
GetNextTask()147 Task* TaskManager::GetNextTask()
148 {
149 Task* task = GetNextTask( PRIORITY_HIGH, false );
150 if ( task != NULL ) return task;
151
152 task = GetNextTask( PRIORITY_MIDDLE, false );
153 if ( task != NULL ) return task;
154
155 task = GetNextTask( PRIORITY_LOW, false );
156 if ( task != NULL ) return task;
157
158 return NULL;
159 }
160
161 /*---------------------------------------------------------------------------*
162 Name: ExecuteTask
163
164 Description: 全てのタスクを実行する
165
166 Arguments: None.
167
168 Returns: None.
169 *---------------------------------------------------------------------------*/
ExecuteTask()170 void TaskManager::ExecuteTask()
171 {
172 while ( 1 )
173 {
174 Task* task = PopTask();
175 if ( task == NULL ) break;
176
177 m_pCurrentTask = task;
178
179 task->Execute();
180 task->m_Status = Task::STATUS_DONE;
181 task->m_Event.Signal();
182 m_pCurrentTask = NULL;
183 }
184 }
185
186 /*---------------------------------------------------------------------------*
187 Name: CancelTask
188
189 Description: タスクをキャンセルする
190
191 Arguments: task - キャンセルするタスク
192
193 Returns: None.
194 *---------------------------------------------------------------------------*/
CancelTask(Task * task)195 void TaskManager::CancelTask( Task* task )
196 {
197 if ( RemoveTask(task) ) {
198 return;
199 }
200
201 task->m_Event.Wait();
202 }
203
204 /*---------------------------------------------------------------------------*
205 Name: CancelTaskById
206
207 Description: ID指定で、タスクをキャンセルする
208
209 Arguments: id - キャンセルするタスクのID
210
211 Returns: None.
212 *---------------------------------------------------------------------------*/
CancelTaskById(u32 id)213 void TaskManager::CancelTaskById( u32 id )
214 {
215 RemoveTaskById(id);
216 }
217
218 /*---------------------------------------------------------------------------*
219 Name: CancelAllTask
220
221 Description: 全タスクをキャンセルする
222
223 Arguments: None.
224
225 Returns: None.
226 *---------------------------------------------------------------------------*/
CancelAllTask()227 void TaskManager::CancelAllTask()
228 {
229 // TODO
230 }
231
232 /*---------------------------------------------------------------------------*
233 Name: RemoveTask
234
235 Description: タスクを削除する
236
237 Arguments: task - 削除するタスク
238
239 Returns: 削除できたかどうか
240 *---------------------------------------------------------------------------*/
RemoveTask(Task * task)241 bool TaskManager::RemoveTask( Task* task )
242 {
243 nn::os::CriticalSection::ScopedLock scopeLock(m_CriticalSection);
244
245 for ( int i=0; i<PRIORITY_NUM; i++ )
246 {
247 TaskPriority priority = static_cast<TaskPriority>( i );
248 TaskList::Iterator itr = m_TaskList[ priority ].GetBeginIter();
249 while ( itr != m_TaskList[ priority ].GetEndIter() )
250 {
251 TaskList::Iterator curItr = itr++;
252 if ( &*curItr == task ) {
253 m_TaskList[ priority ].Erase( curItr );
254 curItr->m_Status = Task::STATUS_CANCEL;
255 curItr->m_Event.Signal();
256 return true;
257 }
258 }
259 }
260
261 return false;
262 }
263
264
265 /*---------------------------------------------------------------------------*
266 Name: RemoveTaskById
267
268 Description: タスクを削除する
269
270 Arguments: id - 削除するタスクのID
271
272 Returns: None.
273 *---------------------------------------------------------------------------*/
RemoveTaskById(u32 id)274 void TaskManager::RemoveTaskById( u32 id )
275 {
276 nn::os::CriticalSection::ScopedLock scopeLock(m_CriticalSection);
277
278 for ( int i=0; i<PRIORITY_NUM; i++ )
279 {
280 TaskPriority priority = static_cast<TaskPriority>( i );
281 TaskList::Iterator itr = m_TaskList[ priority ].GetBeginIter();
282 while ( itr != m_TaskList[ priority ].GetEndIter() )
283 {
284 TaskList::Iterator curItr = itr++;
285 if ( curItr->m_Id == id ) {
286 m_TaskList[ priority ].Erase( curItr );
287 curItr->m_Status = Task::STATUS_CANCEL;
288 curItr->m_Event.Signal();
289 }
290 }
291 }
292 }
293
294
295 /*---------------------------------------------------------------------------*
296 Name: WaitTask
297
298 Description: タスクが登録されるまで待つ
299
300 Arguments: None.
301
302 Returns: None.
303 *---------------------------------------------------------------------------*/
WaitTask()304 void TaskManager::WaitTask()
305 {
306 m_IsWaitTaskCancel = false;
307
308 while( GetNextTask() == NULL && ! m_IsWaitTaskCancel )
309 {
310 if ( m_BlockingQueue.Dequeue() == MESSAGE_APPEND )
311 {
312 break;
313 }
314 }
315 }
316
317 /*---------------------------------------------------------------------------*
318 Name: CancelWaitTask
319
320 Description: WaitTaskの処理をキャンセルする
321
322 Arguments: None.
323
324 Returns: None.
325 *---------------------------------------------------------------------------*/
CancelWaitTask()326 void TaskManager::CancelWaitTask()
327 {
328 m_IsWaitTaskCancel = true;
329
330 m_BlockingQueue.Enqueue( static_cast<uptr>( MESSAGE_APPEND ) );
331 }
332
333 } // namespace nw::snd::internal
334 } // namespace nw::snd
335 } // namespace nw
336
337