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
25 void CThread::Create(bool bAutoDelete, unsigned stacksize)
29 CLog::Log(LOGERROR, "%s - fatal error creating thread- old thread id not null", __FUNCTION__);
32 m_iLastTime = XbmcThreads::SystemClockMillis() * 10000;
35 m_bAutoDelete = bAutoDelete;
41 m_ThreadOpaque.handle = CreateThread(NULL,stacksize, (LPTHREAD_START_ROUTINE)&staticThread, this, 0, &m_ThreadId);
42 if (m_ThreadOpaque.handle == NULL)
44 CLog::Log(LOGERROR, "%s - fatal error creating thread", __FUNCTION__);
48 void CThread::TermHandler()
50 CloseHandle(m_ThreadOpaque.handle);
51 m_ThreadOpaque.handle = NULL;
54 void CThread::SetThreadInfo()
56 const unsigned int MS_VC_EXCEPTION = 0x406d1388;
57 struct THREADNAME_INFO
59 DWORD dwType; // must be 0x1000
60 LPCSTR szName; // pointer to name (in same addr space)
61 DWORD dwThreadID; // thread ID (-1 caller thread)
62 DWORD dwFlags; // reserved for future use, most be zero
66 info.szName = m_ThreadName.c_str();
67 info.dwThreadID = m_ThreadId;
72 RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR *)&info);
79 ThreadIdentifier CThread::GetCurrentThreadId()
81 return ::GetCurrentThreadId();
84 bool CThread::IsCurrentThread(const ThreadIdentifier tid)
86 return (::GetCurrentThreadId() == tid);
89 int CThread::GetMinPriority(void)
91 return(THREAD_PRIORITY_IDLE);
94 int CThread::GetMaxPriority(void)
96 return(THREAD_PRIORITY_HIGHEST);
99 int CThread::GetNormalPriority(void)
101 return(THREAD_PRIORITY_NORMAL);
104 int CThread::GetSchedRRPriority(void)
106 return GetNormalPriority();
109 bool CThread::SetPriority(const int iPriority)
111 bool bReturn = false;
113 CSingleLock lock(m_CriticalSection);
114 if (m_ThreadOpaque.handle)
116 bReturn = SetThreadPriority(m_ThreadOpaque.handle, iPriority) == TRUE;
122 int CThread::GetPriority()
124 CSingleLock lock(m_CriticalSection);
126 int iReturn = THREAD_PRIORITY_NORMAL;
127 if (m_ThreadOpaque.handle)
129 iReturn = GetThreadPriority(m_ThreadOpaque.handle);
134 bool CThread::WaitForThreadExit(unsigned int milliseconds)
138 CSingleLock lock(m_CriticalSection);
139 if (m_ThreadId && m_ThreadOpaque.handle != NULL)
141 // boost priority of thread we are waiting on to same as caller
142 int callee = GetThreadPriority(m_ThreadOpaque.handle);
143 int caller = GetThreadPriority(GetCurrentThread());
145 SetThreadPriority(m_ThreadOpaque.handle, caller);
148 bReturn = m_TermEvent.WaitMSec(milliseconds);
151 // restore thread priority if thread hasn't exited
152 if(caller > callee && m_ThreadOpaque.handle)
153 SetThreadPriority(m_ThreadOpaque.handle, callee);
158 int64_t CThread::GetAbsoluteUsage()
160 CSingleLock lock(m_CriticalSection);
162 if (!m_ThreadOpaque.handle)
166 FILETIME CreationTime, ExitTime, UserTime, KernelTime;
167 if( GetThreadTimes(m_ThreadOpaque.handle, &CreationTime, &ExitTime, &KernelTime, &UserTime ) )
169 time = (((uint64_t)UserTime.dwHighDateTime) << 32) + ((uint64_t)UserTime.dwLowDateTime);
170 time += (((uint64_t)KernelTime.dwHighDateTime) << 32) + ((uint64_t)KernelTime.dwLowDateTime);
175 float CThread::GetRelativeUsage()
177 unsigned int iTime = XbmcThreads::SystemClockMillis();
178 iTime *= 10000; // convert into 100ns tics
180 // only update every 1 second
181 if( iTime < m_iLastTime + 1000*10000 ) return m_fLastUsage;
183 int64_t iUsage = GetAbsoluteUsage();
185 if (m_iLastUsage > 0 && m_iLastTime > 0)
186 m_fLastUsage = (float)( iUsage - m_iLastUsage ) / (float)( iTime - m_iLastTime );
188 m_iLastUsage = iUsage;
194 int64_t CThread::GetCurrentThreadUsage()
196 HANDLE h = GetCurrentThread();
199 FILETIME CreationTime, ExitTime, UserTime, KernelTime;
200 if( GetThreadTimes(h, &CreationTime, &ExitTime, &KernelTime, &UserTime ) )
202 time = (((uint64_t)UserTime.dwHighDateTime) << 32) + ((uint64_t)UserTime.dwLowDateTime);
203 time += (((uint64_t)KernelTime.dwHighDateTime) << 32) + ((uint64_t)KernelTime.dwLowDateTime);