/*---------------------------------------------------------------------------* Project: NintendoWare File: snd_TaskManager.cpp Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision: 29467 $ *---------------------------------------------------------------------------*/ #include "precompiled.h" #include namespace nw { namespace snd { namespace internal { /*---------------------------------------------------------------------------* Name: GetInstance Description: シングルトンのインスタンスを取得する Arguments: なし Returns: インスタンス *---------------------------------------------------------------------------*/ TaskManager& TaskManager::GetInstance() { static TaskManager instance; return instance; } /*---------------------------------------------------------------------------* Name: TaskManager Description: コンストラクタ Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ TaskManager::TaskManager() : m_pCurrentTask( NULL ), m_IsWaitTaskCancel( false ) { } void TaskManager::Initialize() { m_CriticalSection.Initialize(); m_BlockingQueue.Initialize( m_MsgBuffer, THREAD_MESSAGE_BUFSIZE ); } void TaskManager::Finalize() { m_CriticalSection.Finalize(); m_BlockingQueue.Finalize(); } /*---------------------------------------------------------------------------* Name: AppendTask Description: タスクリストにタスクを登録 Arguments: task - 登録するタスク priority - タスクを登録するリストのプライオリティ Returns: None. *---------------------------------------------------------------------------*/ void TaskManager::AppendTask( Task* task, TaskPriority priority ) { NW_MINMAXLT_ASSERT( priority, 0, PRIORITY_NUM ); nn::os::CriticalSection::ScopedLock scopeLock(m_CriticalSection); task->m_Event.ClearSignal(); task->m_Status = Task::STATUS_APPEND; m_TaskList[ priority ].PushBack( task ); m_BlockingQueue.TryEnqueue( static_cast( MESSAGE_APPEND ) ); } /*---------------------------------------------------------------------------* Name: GetNextTask Description: 次のタスクを取得する Arguments: priority - タスクを抜き出すリストのプライオリティ doRemove - リストから削除するかどうか Returns: 取得したタスク *---------------------------------------------------------------------------*/ Task* TaskManager::GetNextTask( TaskPriority priority, bool doRemove ) { NW_MINMAXLT_ASSERT( priority, 0, PRIORITY_NUM ); nn::os::CriticalSection::ScopedLock scopeLock(m_CriticalSection); if ( m_TaskList[ priority ].IsEmpty() ) return NULL; Task* task = &m_TaskList[ priority ].GetFront(); if ( doRemove ) { m_TaskList[ priority ].PopFront(); } return task; } /*---------------------------------------------------------------------------* Name: PopTask Description: 最優先のタスクを取り出す Arguments: なし Returns: 取り出したタスク *---------------------------------------------------------------------------*/ Task* TaskManager::PopTask() { nn::os::CriticalSection::ScopedLock scopeLock(m_CriticalSection); Task* task = GetNextTask( PRIORITY_HIGH, true ); if ( task != NULL ) return task; task = GetNextTask( PRIORITY_MIDDLE, true ); if ( task != NULL ) return task; task = GetNextTask( PRIORITY_LOW, true ); if ( task != NULL ) return task; return NULL; } /*---------------------------------------------------------------------------* Name: PopTask Description: 最優先のタスクを取得する(リストから削除しない) Arguments: なし Returns: 取得したタスク *---------------------------------------------------------------------------*/ Task* TaskManager::GetNextTask() { Task* task = GetNextTask( PRIORITY_HIGH, false ); if ( task != NULL ) return task; task = GetNextTask( PRIORITY_MIDDLE, false ); if ( task != NULL ) return task; task = GetNextTask( PRIORITY_LOW, false ); if ( task != NULL ) return task; return NULL; } /*---------------------------------------------------------------------------* Name: ExecuteTask Description: 全てのタスクを実行する Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void TaskManager::ExecuteTask() { while ( 1 ) { Task* task = PopTask(); if ( task == NULL ) break; m_pCurrentTask = task; task->Execute(); task->m_Status = Task::STATUS_DONE; task->m_Event.Signal(); m_pCurrentTask = NULL; } } /*---------------------------------------------------------------------------* Name: CancelTask Description: タスクをキャンセルする Arguments: task - キャンセルするタスク Returns: None. *---------------------------------------------------------------------------*/ void TaskManager::CancelTask( Task* task ) { if ( RemoveTask(task) ) { return; } task->m_Event.Wait(); } /*---------------------------------------------------------------------------* Name: CancelTaskById Description: ID指定で、タスクをキャンセルする Arguments: id - キャンセルするタスクのID Returns: None. *---------------------------------------------------------------------------*/ void TaskManager::CancelTaskById( u32 id ) { RemoveTaskById(id); } /*---------------------------------------------------------------------------* Name: CancelAllTask Description: 全タスクをキャンセルする Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void TaskManager::CancelAllTask() { // TODO } /*---------------------------------------------------------------------------* Name: RemoveTask Description: タスクを削除する Arguments: task - 削除するタスク Returns: 削除できたかどうか *---------------------------------------------------------------------------*/ bool TaskManager::RemoveTask( Task* task ) { nn::os::CriticalSection::ScopedLock scopeLock(m_CriticalSection); for ( int i=0; i( i ); TaskList::Iterator itr = m_TaskList[ priority ].GetBeginIter(); while ( itr != m_TaskList[ priority ].GetEndIter() ) { TaskList::Iterator curItr = itr++; if ( &*curItr == task ) { m_TaskList[ priority ].Erase( curItr ); curItr->m_Status = Task::STATUS_CANCEL; curItr->m_Event.Signal(); return true; } } } return false; } /*---------------------------------------------------------------------------* Name: RemoveTaskById Description: タスクを削除する Arguments: id - 削除するタスクのID Returns: None. *---------------------------------------------------------------------------*/ void TaskManager::RemoveTaskById( u32 id ) { nn::os::CriticalSection::ScopedLock scopeLock(m_CriticalSection); for ( int i=0; i( i ); TaskList::Iterator itr = m_TaskList[ priority ].GetBeginIter(); while ( itr != m_TaskList[ priority ].GetEndIter() ) { TaskList::Iterator curItr = itr++; if ( curItr->m_Id == id ) { m_TaskList[ priority ].Erase( curItr ); curItr->m_Status = Task::STATUS_CANCEL; curItr->m_Event.Signal(); } } } } /*---------------------------------------------------------------------------* Name: WaitTask Description: タスクが登録されるまで待つ Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void TaskManager::WaitTask() { m_IsWaitTaskCancel = false; while( GetNextTask() == NULL && ! m_IsWaitTaskCancel ) { if ( m_BlockingQueue.Dequeue() == MESSAGE_APPEND ) { break; } } } /*---------------------------------------------------------------------------* Name: CancelWaitTask Description: WaitTaskの処理をキャンセルする Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void TaskManager::CancelWaitTask() { m_IsWaitTaskCancel = true; m_BlockingQueue.Enqueue( static_cast( MESSAGE_APPEND ) ); } } // namespace nw::snd::internal } // namespace nw::snd } // namespace nw