2 * Copyright (C) 2005-2011 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
23 #include "threads/platform/win/Win32Exception.h"
25 void CThread::SpawnThread(unsigned stacksize)
27 // Create in the suspended state, so that no matter the thread priorities and scheduled order, the handle will be assigned
28 // before the new thread exits.
29 m_ThreadOpaque.handle = CreateThread(NULL, stacksize, (LPTHREAD_START_ROUTINE)&staticThread, this, CREATE_SUSPENDED, &m_ThreadId);
30 if (m_ThreadOpaque.handle == NULL)
32 if (logger) logger->Log(LOGERROR, "%s - fatal error %d creating thread", __FUNCTION__, GetLastError());
36 if (ResumeThread(m_ThreadOpaque.handle) == -1)
37 if (logger) logger->Log(LOGERROR, "%s - fatal error %d resuming thread", __FUNCTION__, GetLastError());
41 void CThread::TermHandler()
43 CloseHandle(m_ThreadOpaque.handle);
44 m_ThreadOpaque.handle = NULL;
47 void CThread::SetThreadInfo()
49 const unsigned int MS_VC_EXCEPTION = 0x406d1388;
52 struct THREADNAME_INFO
54 DWORD dwType; // must be 0x1000
55 LPCSTR szName; // pointer to name (in same addr space)
56 DWORD dwThreadID; // thread ID (-1 caller thread)
57 DWORD dwFlags; // reserved for future use, most be zero
62 info.szName = m_ThreadName.c_str();
63 info.dwThreadID = m_ThreadId;
68 RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR *)&info);
70 __except(EXCEPTION_EXECUTE_HANDLER)
75 ThreadIdentifier CThread::GetCurrentThreadId()
77 return ::GetCurrentThreadId();
80 bool CThread::IsCurrentThread(const ThreadIdentifier tid)
82 return (::GetCurrentThreadId() == tid);
85 int CThread::GetMinPriority(void)
87 return(THREAD_PRIORITY_IDLE);
90 int CThread::GetMaxPriority(void)
92 return(THREAD_PRIORITY_HIGHEST);
95 int CThread::GetNormalPriority(void)
97 return(THREAD_PRIORITY_NORMAL);
100 int CThread::GetSchedRRPriority(void)
102 return GetNormalPriority();
105 bool CThread::SetPriority(const int iPriority)
107 bool bReturn = false;
109 CSingleLock lock(m_CriticalSection);
110 if (m_ThreadOpaque.handle)
112 bReturn = SetThreadPriority(m_ThreadOpaque.handle, iPriority) == TRUE;
118 int CThread::GetPriority()
120 CSingleLock lock(m_CriticalSection);
122 int iReturn = THREAD_PRIORITY_NORMAL;
123 if (m_ThreadOpaque.handle)
125 iReturn = GetThreadPriority(m_ThreadOpaque.handle);
130 bool CThread::WaitForThreadExit(unsigned int milliseconds)
134 CSingleLock lock(m_CriticalSection);
135 if (m_ThreadId && m_ThreadOpaque.handle != NULL)
137 // boost priority of thread we are waiting on to same as caller
138 int callee = GetThreadPriority(m_ThreadOpaque.handle);
139 int caller = GetThreadPriority(GetCurrentThread());
141 SetThreadPriority(m_ThreadOpaque.handle, caller);
144 bReturn = m_TermEvent.WaitMSec(milliseconds);
147 // restore thread priority if thread hasn't exited
148 if(caller > callee && m_ThreadOpaque.handle)
149 SetThreadPriority(m_ThreadOpaque.handle, callee);
154 int64_t CThread::GetAbsoluteUsage()
156 CSingleLock lock(m_CriticalSection);
158 if (!m_ThreadOpaque.handle)
162 FILETIME CreationTime, ExitTime, UserTime, KernelTime;
163 if( GetThreadTimes(m_ThreadOpaque.handle, &CreationTime, &ExitTime, &KernelTime, &UserTime ) )
165 time = (((uint64_t)UserTime.dwHighDateTime) << 32) + ((uint64_t)UserTime.dwLowDateTime);
166 time += (((uint64_t)KernelTime.dwHighDateTime) << 32) + ((uint64_t)KernelTime.dwLowDateTime);
171 float CThread::GetRelativeUsage()
173 unsigned int iTime = XbmcThreads::SystemClockMillis();
174 iTime *= 10000; // convert into 100ns tics
176 // only update every 1 second
177 if( iTime < m_iLastTime + 1000*10000 ) return m_fLastUsage;
179 int64_t iUsage = GetAbsoluteUsage();
181 if (m_iLastUsage > 0 && m_iLastTime > 0)
182 m_fLastUsage = (float)( iUsage - m_iLastUsage ) / (float)( iTime - m_iLastTime );
184 m_iLastUsage = iUsage;
190 void CThread::SetSignalHandlers()
192 // install win32 exception translator
193 win32_exception::install_handler();