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