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: 17972 $
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_Event.Signal();
181 task->m_Status = Task::STATUS_DONE;
182
183 m_pCurrentTask = NULL;
184 }
185 }
186
187 /*---------------------------------------------------------------------------*
188 Name: CancelTask
189
190 Description: タスクをキャンセルする
191
192 Arguments: task - キャンセルするタスク
193
194 Returns: None.
195 *---------------------------------------------------------------------------*/
CancelTask(Task * task)196 void TaskManager::CancelTask( Task* task )
197 {
198 if ( RemoveTask(task) ) {
199 return;
200 }
201
202 task->m_Event.Wait();
203 }
204
205 /*---------------------------------------------------------------------------*
206 Name: CancelTaskById
207
208 Description: ID指定で、タスクをキャンセルする
209
210 Arguments: id - キャンセルするタスクのID
211
212 Returns: None.
213 *---------------------------------------------------------------------------*/
CancelTaskById(u32 id)214 void TaskManager::CancelTaskById( u32 id )
215 {
216 RemoveTaskById(id);
217 }
218
219 /*---------------------------------------------------------------------------*
220 Name: CancelAllTask
221
222 Description: 全タスクをキャンセルする
223
224 Arguments: None.
225
226 Returns: None.
227 *---------------------------------------------------------------------------*/
CancelAllTask()228 void TaskManager::CancelAllTask()
229 {
230 // TODO
231 }
232
233 /*---------------------------------------------------------------------------*
234 Name: RemoveTask
235
236 Description: タスクを削除する
237
238 Arguments: task - 削除するタスク
239
240 Returns: 削除できたかどうか
241 *---------------------------------------------------------------------------*/
RemoveTask(Task * task)242 bool TaskManager::RemoveTask( Task* task )
243 {
244 nn::os::CriticalSection::ScopedLock scopeLock(m_CriticalSection);
245
246 for ( int i=0; i<PRIORITY_NUM; i++ )
247 {
248 TaskPriority priority = static_cast<TaskPriority>( i );
249 TaskList::Iterator itr = m_TaskList[ priority ].GetBeginIter();
250 while ( itr != m_TaskList[ priority ].GetEndIter() )
251 {
252 TaskList::Iterator curItr = itr++;
253 if ( &*curItr == task ) {
254 m_TaskList[ priority ].Erase( curItr );
255 curItr->m_Event.Signal();
256 curItr->m_Status = Task::STATUS_CANCEL;
257 return true;
258 }
259 }
260 }
261
262 return false;
263 }
264
265
266 /*---------------------------------------------------------------------------*
267 Name: RemoveTaskById
268
269 Description: タスクを削除する
270
271 Arguments: id - 削除するタスクのID
272
273 Returns: None.
274 *---------------------------------------------------------------------------*/
RemoveTaskById(u32 id)275 void TaskManager::RemoveTaskById( u32 id )
276 {
277 nn::os::CriticalSection::ScopedLock scopeLock(m_CriticalSection);
278
279 for ( int i=0; i<PRIORITY_NUM; i++ )
280 {
281 TaskPriority priority = static_cast<TaskPriority>( i );
282 TaskList::Iterator itr = m_TaskList[ priority ].GetBeginIter();
283 while ( itr != m_TaskList[ priority ].GetEndIter() )
284 {
285 TaskList::Iterator curItr = itr++;
286 if ( curItr->m_Id == id ) {
287 m_TaskList[ priority ].Erase( curItr );
288 curItr->m_Event.Signal();
289 curItr->m_Status = Task::STATUS_CANCEL;
290 }
291 }
292 }
293 }
294
295
296 /*---------------------------------------------------------------------------*
297 Name: WaitTask
298
299 Description: タスクが登録されるまで待つ
300
301 Arguments: None.
302
303 Returns: None.
304 *---------------------------------------------------------------------------*/
WaitTask()305 void TaskManager::WaitTask()
306 {
307 m_IsWaitTaskCancel = false;
308
309 while( GetNextTask() == NULL && ! m_IsWaitTaskCancel )
310 {
311 if ( m_BlockingQueue.Dequeue() == MESSAGE_APPEND )
312 {
313 break;
314 }
315 }
316 }
317
318 /*---------------------------------------------------------------------------*
319 Name: CancelWaitTask
320
321 Description: WaitTaskの処理をキャンセルする
322
323 Arguments: None.
324
325 Returns: None.
326 *---------------------------------------------------------------------------*/
CancelWaitTask()327 void TaskManager::CancelWaitTask()
328 {
329 m_IsWaitTaskCancel = true;
330
331 m_BlockingQueue.Enqueue( static_cast<uptr>( MESSAGE_APPEND ) );
332 }
333
334 } // namespace nw::snd::internal
335 } // namespace nw::snd
336 } // namespace nw
337
338