summaryrefslogtreecommitdiffstats
path: root/tinySAK/winrt
diff options
context:
space:
mode:
authorMamadou DIOP <bossiel@yahoo.fr>2016-02-23 22:00:35 +0100
committerMamadou DIOP <bossiel@yahoo.fr>2016-02-23 22:00:35 +0100
commit50dfb4359619563012997bc3ddafb7667741066c (patch)
treedb234c1edc3240a653363b5735fc4077af4b8720 /tinySAK/winrt
parent94b2219209038e05dd26395f6fb700be4d1062c0 (diff)
downloaddoubango-50dfb4359619563012997bc3ddafb7667741066c.zip
doubango-50dfb4359619563012997bc3ddafb7667741066c.tar.gz
Add new QoS implementation
Code formatting
Diffstat (limited to 'tinySAK/winrt')
-rwxr-xr-xtinySAK/winrt/ThreadEmulation.cxx482
-rwxr-xr-xtinySAK/winrt/ThreadEmulation.h28
2 files changed, 244 insertions, 266 deletions
diff --git a/tinySAK/winrt/ThreadEmulation.cxx b/tinySAK/winrt/ThreadEmulation.cxx
index f863dc9..91f2294 100755
--- a/tinySAK/winrt/ThreadEmulation.cxx
+++ b/tinySAK/winrt/ThreadEmulation.cxx
@@ -21,335 +21,313 @@ using namespace Windows::System::Threading;
namespace ThreadEmulation
{
- // Stored data for CREATE_SUSPENDED and ResumeThread.
- struct PendingThreadInfo
- {
- LPTHREAD_START_ROUTINE lpStartAddress;
- LPVOID lpParameter;
- HANDLE completionEvent;
- int nPriority;
- };
-
- static map<HANDLE, PendingThreadInfo> pendingThreads;
- static mutex pendingThreadsLock;
-
-
- // Thread local storage.
- typedef vector<void*> ThreadLocalData;
-
- static __declspec(thread) ThreadLocalData* currentThreadData = nullptr;
- static set<ThreadLocalData*> allThreadData;
- static DWORD nextTlsIndex = 0;
- static vector<DWORD> freeTlsIndices;
- static mutex tlsAllocationLock;
-
-
- // Converts a Win32 thread priority to WinRT format.
- static WorkItemPriority GetWorkItemPriority(int nPriority)
- {
- if (nPriority < 0)
- return WorkItemPriority::Low;
- else if (nPriority > 0)
- return WorkItemPriority::High;
- else
- return WorkItemPriority::Normal;
- }
+// Stored data for CREATE_SUSPENDED and ResumeThread.
+struct PendingThreadInfo {
+ LPTHREAD_START_ROUTINE lpStartAddress;
+ LPVOID lpParameter;
+ HANDLE completionEvent;
+ int nPriority;
+};
+static map<HANDLE, PendingThreadInfo> pendingThreads;
+static mutex pendingThreadsLock;
- // Helper shared between CreateThread and ResumeThread.
- static void StartThread(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, HANDLE completionEvent, int nPriority)
- {
- auto workItemHandler = ref new WorkItemHandler([=](IAsyncAction^)
- {
- // Run the user callback.
- try
- {
- lpStartAddress(lpParameter);
- }
- catch (...) { }
- // Clean up any TLS allocations made by this thread.
- TlsShutdown();
+// Thread local storage.
+typedef vector<void*> ThreadLocalData;
- // Signal that the thread has completed.
- SetEvent(completionEvent);
- CloseHandle(completionEvent);
+static __declspec(thread) ThreadLocalData* currentThreadData = nullptr;
+static set<ThreadLocalData*> allThreadData;
+static DWORD nextTlsIndex = 0;
+static vector<DWORD> freeTlsIndices;
+static mutex tlsAllocationLock;
- }, CallbackContext::Any);
- ThreadPool::RunAsync(workItemHandler, GetWorkItemPriority(nPriority), WorkItemOptions::TimeSliced);
+// Converts a Win32 thread priority to WinRT format.
+static WorkItemPriority GetWorkItemPriority(int nPriority)
+{
+ if (nPriority < 0) {
+ return WorkItemPriority::Low;
+ }
+ else if (nPriority > 0) {
+ return WorkItemPriority::High;
+ }
+ else {
+ return WorkItemPriority::Normal;
}
+}
- _Use_decl_annotations_ HANDLE WINAPI CreateThread(LPSECURITY_ATTRIBUTES unusedThreadAttributes, SIZE_T unusedStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD unusedThreadId)
- {
- // Validate parameters.
- assert(unusedThreadAttributes == nullptr);
- assert(unusedStackSize == 0);
- assert((dwCreationFlags & ~CREATE_SUSPENDED) == 0);
- assert(unusedThreadId == nullptr);
+// Helper shared between CreateThread and ResumeThread.
+static void StartThread(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, HANDLE completionEvent, int nPriority)
+{
+ auto workItemHandler = ref new WorkItemHandler([=](IAsyncAction^) {
+ // Run the user callback.
+ try {
+ lpStartAddress(lpParameter);
+ }
+ catch (...) { }
- // Create a handle that will be signalled when the thread has completed.
- HANDLE threadHandle = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
+ // Clean up any TLS allocations made by this thread.
+ TlsShutdown();
- if (!threadHandle)
- return nullptr;
+ // Signal that the thread has completed.
+ SetEvent(completionEvent);
+ CloseHandle(completionEvent);
- // Make a copy of the handle for internal use. This is necessary because
- // the caller is responsible for closing the handle returned by CreateThread,
- // and they may do that before or after the thread has finished running.
- HANDLE completionEvent;
-
- if (!DuplicateHandle(GetCurrentProcess(), threadHandle, GetCurrentProcess(), &completionEvent, 0, false, DUPLICATE_SAME_ACCESS))
- {
- CloseHandle(threadHandle);
- return nullptr;
- }
+ }, CallbackContext::Any);
- try
- {
- if (dwCreationFlags & CREATE_SUSPENDED)
- {
- // Store info about a suspended thread.
- PendingThreadInfo info;
+ ThreadPool::RunAsync(workItemHandler, GetWorkItemPriority(nPriority), WorkItemOptions::TimeSliced);
+}
- info.lpStartAddress = lpStartAddress;
- info.lpParameter = lpParameter;
- info.completionEvent = completionEvent;
- info.nPriority = 0;
- lock_guard<mutex> lock(pendingThreadsLock);
+_Use_decl_annotations_ HANDLE WINAPI CreateThread(LPSECURITY_ATTRIBUTES unusedThreadAttributes, SIZE_T unusedStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD unusedThreadId)
+{
+ // Validate parameters.
+ assert(unusedThreadAttributes == nullptr);
+ assert(unusedStackSize == 0);
+ assert((dwCreationFlags & ~CREATE_SUSPENDED) == 0);
+ assert(unusedThreadId == nullptr);
- pendingThreads[threadHandle] = info;
- }
- else
- {
- // Start the thread immediately.
- StartThread(lpStartAddress, lpParameter, completionEvent, 0);
- }
-
- return threadHandle;
- }
- catch (...)
- {
- // Clean up if thread creation fails.
- CloseHandle(threadHandle);
- CloseHandle(completionEvent);
+ // Create a handle that will be signalled when the thread has completed.
+ HANDLE threadHandle = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
- return nullptr;
- }
+ if (!threadHandle) {
+ return nullptr;
}
+ // Make a copy of the handle for internal use. This is necessary because
+ // the caller is responsible for closing the handle returned by CreateThread,
+ // and they may do that before or after the thread has finished running.
+ HANDLE completionEvent;
- _Use_decl_annotations_ DWORD WINAPI ResumeThread(HANDLE hThread)
- {
- lock_guard<mutex> lock(pendingThreadsLock);
+ if (!DuplicateHandle(GetCurrentProcess(), threadHandle, GetCurrentProcess(), &completionEvent, 0, false, DUPLICATE_SAME_ACCESS)) {
+ CloseHandle(threadHandle);
+ return nullptr;
+ }
- // Look up the requested thread.
- auto threadInfo = pendingThreads.find(hThread);
+ try {
+ if (dwCreationFlags & CREATE_SUSPENDED) {
+ // Store info about a suspended thread.
+ PendingThreadInfo info;
- if (threadInfo == pendingThreads.end())
- {
- // Can only resume threads while they are in CREATE_SUSPENDED state.
- assert(false);
- return (DWORD)-1;
- }
+ info.lpStartAddress = lpStartAddress;
+ info.lpParameter = lpParameter;
+ info.completionEvent = completionEvent;
+ info.nPriority = 0;
- // Start the thread.
- try
- {
- PendingThreadInfo& info = threadInfo->second;
+ lock_guard<mutex> lock(pendingThreadsLock);
- StartThread(info.lpStartAddress, info.lpParameter, info.completionEvent, info.nPriority);
+ pendingThreads[threadHandle] = info;
}
- catch (...)
- {
- return (DWORD)-1;
+ else {
+ // Start the thread immediately.
+ StartThread(lpStartAddress, lpParameter, completionEvent, 0);
}
- // Remove this thread from the pending list.
- pendingThreads.erase(threadInfo);
+ return threadHandle;
+ }
+ catch (...) {
+ // Clean up if thread creation fails.
+ CloseHandle(threadHandle);
+ CloseHandle(completionEvent);
- return 0;
+ return nullptr;
}
+}
- _Use_decl_annotations_ BOOL WINAPI SetThreadPriority(HANDLE hThread, int nPriority)
- {
- lock_guard<mutex> lock(pendingThreadsLock);
+_Use_decl_annotations_ DWORD WINAPI ResumeThread(HANDLE hThread)
+{
+ lock_guard<mutex> lock(pendingThreadsLock);
- // Look up the requested thread.
- auto threadInfo = pendingThreads.find(hThread);
+ // Look up the requested thread.
+ auto threadInfo = pendingThreads.find(hThread);
- if (threadInfo == pendingThreads.end())
- {
- // Can only set priority on threads while they are in CREATE_SUSPENDED state.
- return false;
- }
+ if (threadInfo == pendingThreads.end()) {
+ // Can only resume threads while they are in CREATE_SUSPENDED state.
+ assert(false);
+ return (DWORD)-1;
+ }
- // Store the new priority.
- threadInfo->second.nPriority = nPriority;
+ // Start the thread.
+ try {
+ PendingThreadInfo& info = threadInfo->second;
- return true;
+ StartThread(info.lpStartAddress, info.lpParameter, info.completionEvent, info.nPriority);
+ }
+ catch (...) {
+ return (DWORD)-1;
}
+ // Remove this thread from the pending list.
+ pendingThreads.erase(threadInfo);
- _Use_decl_annotations_ VOID WINAPI Sleep(DWORD dwMilliseconds)
- {
- static HANDLE singletonEvent = nullptr;
+ return 0;
+}
- HANDLE sleepEvent = singletonEvent;
- // Demand create the event.
- if (!sleepEvent)
- {
- sleepEvent = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
-
- if (!sleepEvent)
- return;
-
- HANDLE previousEvent = InterlockedCompareExchangePointerRelease(&singletonEvent, sleepEvent, nullptr);
-
- if (previousEvent)
- {
- // Back out if multiple threads try to demand create at the same time.
- CloseHandle(sleepEvent);
- sleepEvent = previousEvent;
- }
- }
+_Use_decl_annotations_ BOOL WINAPI SetThreadPriority(HANDLE hThread, int nPriority)
+{
+ lock_guard<mutex> lock(pendingThreadsLock);
+
+ // Look up the requested thread.
+ auto threadInfo = pendingThreads.find(hThread);
- // Emulate sleep by waiting with timeout on an event that is never signalled.
- WaitForSingleObjectEx(sleepEvent, dwMilliseconds, false);
+ if (threadInfo == pendingThreads.end()) {
+ // Can only set priority on threads while they are in CREATE_SUSPENDED state.
+ return false;
}
+ // Store the new priority.
+ threadInfo->second.nPriority = nPriority;
- DWORD WINAPI TlsAlloc()
- {
- lock_guard<mutex> lock(tlsAllocationLock);
-
- // Can we reuse a previously freed TLS slot?
- if (!freeTlsIndices.empty())
- {
- DWORD result = freeTlsIndices.back();
- freeTlsIndices.pop_back();
- return result;
- }
+ return true;
+}
- // Allocate a new TLS slot.
- return nextTlsIndex++;
- }
+_Use_decl_annotations_ VOID WINAPI Sleep(DWORD dwMilliseconds)
+{
+ static HANDLE singletonEvent = nullptr;
- _Use_decl_annotations_ BOOL WINAPI TlsFree(DWORD dwTlsIndex)
- {
- lock_guard<mutex> lock(tlsAllocationLock);
+ HANDLE sleepEvent = singletonEvent;
- assert(dwTlsIndex < nextTlsIndex);
- assert(find(freeTlsIndices.begin(), freeTlsIndices.end(), dwTlsIndex) == freeTlsIndices.end());
+ // Demand create the event.
+ if (!sleepEvent) {
+ sleepEvent = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
- // Store this slot for reuse by TlsAlloc.
- try
- {
- freeTlsIndices.push_back(dwTlsIndex);
- }
- catch (...)
- {
- return false;
+ if (!sleepEvent) {
+ return;
}
- // Zero the value for all threads that might be using this now freed slot.
- for each (auto threadData in allThreadData)
- {
- if (threadData->size() > dwTlsIndex)
- {
- threadData->at(dwTlsIndex) = nullptr;
- }
+ HANDLE previousEvent = InterlockedCompareExchangePointerRelease(&singletonEvent, sleepEvent, nullptr);
+
+ if (previousEvent) {
+ // Back out if multiple threads try to demand create at the same time.
+ CloseHandle(sleepEvent);
+ sleepEvent = previousEvent;
}
+ }
+
+ // Emulate sleep by waiting with timeout on an event that is never signalled.
+ WaitForSingleObjectEx(sleepEvent, dwMilliseconds, false);
+}
+
- return true;
+DWORD WINAPI TlsAlloc()
+{
+ lock_guard<mutex> lock(tlsAllocationLock);
+
+ // Can we reuse a previously freed TLS slot?
+ if (!freeTlsIndices.empty()) {
+ DWORD result = freeTlsIndices.back();
+ freeTlsIndices.pop_back();
+ return result;
}
+ // Allocate a new TLS slot.
+ return nextTlsIndex++;
+}
- _Use_decl_annotations_ LPVOID WINAPI TlsGetValue(DWORD dwTlsIndex)
- {
- ThreadLocalData* threadData = currentThreadData;
- if (threadData && threadData->size() > dwTlsIndex)
- {
- // Return the value of an allocated TLS slot.
- return threadData->at(dwTlsIndex);
- }
- else
- {
- // Default value for unallocated slots.
- return nullptr;
+_Use_decl_annotations_ BOOL WINAPI TlsFree(DWORD dwTlsIndex)
+{
+ lock_guard<mutex> lock(tlsAllocationLock);
+
+ assert(dwTlsIndex < nextTlsIndex);
+ assert(find(freeTlsIndices.begin(), freeTlsIndices.end(), dwTlsIndex) == freeTlsIndices.end());
+
+ // Store this slot for reuse by TlsAlloc.
+ try {
+ freeTlsIndices.push_back(dwTlsIndex);
+ }
+ catch (...) {
+ return false;
+ }
+
+ // Zero the value for all threads that might be using this now freed slot.
+ for each (auto threadData in allThreadData) {
+ if (threadData->size() > dwTlsIndex) {
+ threadData->at(dwTlsIndex) = nullptr;
}
}
+ return true;
+}
- _Use_decl_annotations_ BOOL WINAPI TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue)
- {
- ThreadLocalData* threadData = currentThreadData;
- if (!threadData)
- {
- // First time allocation of TLS data for this thread.
- try
- {
- threadData = new ThreadLocalData(dwTlsIndex + 1, nullptr);
-
- lock_guard<mutex> lock(tlsAllocationLock);
+_Use_decl_annotations_ LPVOID WINAPI TlsGetValue(DWORD dwTlsIndex)
+{
+ ThreadLocalData* threadData = currentThreadData;
+
+ if (threadData && threadData->size() > dwTlsIndex) {
+ // Return the value of an allocated TLS slot.
+ return threadData->at(dwTlsIndex);
+ }
+ else {
+ // Default value for unallocated slots.
+ return nullptr;
+ }
+}
- allThreadData.insert(threadData);
- currentThreadData = threadData;
- }
- catch (...)
- {
- if (threadData)
- delete threadData;
+_Use_decl_annotations_ BOOL WINAPI TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue)
+{
+ ThreadLocalData* threadData = currentThreadData;
+
+ if (!threadData) {
+ // First time allocation of TLS data for this thread.
+ try {
+ threadData = new ThreadLocalData(dwTlsIndex + 1, nullptr);
+
+ lock_guard<mutex> lock(tlsAllocationLock);
+
+ allThreadData.insert(threadData);
- return false;
+ currentThreadData = threadData;
+ }
+ catch (...) {
+ if (threadData) {
+ delete threadData;
}
+
+ return false;
}
- else if (threadData->size() <= dwTlsIndex)
- {
- // This thread already has a TLS data block, but it must be expanded to fit the specified slot.
- try
- {
- lock_guard<mutex> lock(tlsAllocationLock);
+ }
+ else if (threadData->size() <= dwTlsIndex) {
+ // This thread already has a TLS data block, but it must be expanded to fit the specified slot.
+ try {
+ lock_guard<mutex> lock(tlsAllocationLock);
- threadData->resize(dwTlsIndex + 1, nullptr);
- }
- catch (...)
- {
- return false;
- }
+ threadData->resize(dwTlsIndex + 1, nullptr);
}
+ catch (...) {
+ return false;
+ }
+ }
- // Store the new value for this slot.
- threadData->at(dwTlsIndex) = lpTlsValue;
+ // Store the new value for this slot.
+ threadData->at(dwTlsIndex) = lpTlsValue;
- return true;
- }
+ return true;
+}
- // Called at thread exit to clean up TLS allocations.
- void WINAPI TlsShutdown()
- {
- ThreadLocalData* threadData = currentThreadData;
+// Called at thread exit to clean up TLS allocations.
+void WINAPI TlsShutdown()
+{
+ ThreadLocalData* threadData = currentThreadData;
- if (threadData)
+ if (threadData) {
{
- {
- lock_guard<mutex> lock(tlsAllocationLock);
+ lock_guard<mutex> lock(tlsAllocationLock);
- allThreadData.erase(threadData);
- }
+ allThreadData.erase(threadData);
+ }
- currentThreadData = nullptr;
+ currentThreadData = nullptr;
- delete threadData;
- }
+ delete threadData;
}
+}
} \ No newline at end of file
diff --git a/tinySAK/winrt/ThreadEmulation.h b/tinySAK/winrt/ThreadEmulation.h
index 37deabc..b07bb13 100755
--- a/tinySAK/winrt/ThreadEmulation.h
+++ b/tinySAK/winrt/ThreadEmulation.h
@@ -34,20 +34,20 @@
namespace ThreadEmulation
{
- #ifndef CREATE_SUSPENDED
- #define CREATE_SUSPENDED 0x00000004
- #endif
+#ifndef CREATE_SUSPENDED
+#define CREATE_SUSPENDED 0x00000004
+#endif
- HANDLE WINAPI CreateThread(_In_opt_ LPSECURITY_ATTRIBUTES unusedThreadAttributes, _In_ SIZE_T unusedStackSize, _In_ LPTHREAD_START_ROUTINE lpStartAddress, _In_opt_ LPVOID lpParameter, _In_ DWORD dwCreationFlags, _Out_opt_ LPDWORD unusedThreadId);
- DWORD WINAPI ResumeThread(_In_ HANDLE hThread);
- BOOL WINAPI SetThreadPriority(_In_ HANDLE hThread, _In_ int nPriority);
-
- VOID WINAPI Sleep(_In_ DWORD dwMilliseconds);
+HANDLE WINAPI CreateThread(_In_opt_ LPSECURITY_ATTRIBUTES unusedThreadAttributes, _In_ SIZE_T unusedStackSize, _In_ LPTHREAD_START_ROUTINE lpStartAddress, _In_opt_ LPVOID lpParameter, _In_ DWORD dwCreationFlags, _Out_opt_ LPDWORD unusedThreadId);
+DWORD WINAPI ResumeThread(_In_ HANDLE hThread);
+BOOL WINAPI SetThreadPriority(_In_ HANDLE hThread, _In_ int nPriority);
- DWORD WINAPI TlsAlloc();
- BOOL WINAPI TlsFree(_In_ DWORD dwTlsIndex);
- LPVOID WINAPI TlsGetValue(_In_ DWORD dwTlsIndex);
- BOOL WINAPI TlsSetValue(_In_ DWORD dwTlsIndex, _In_opt_ LPVOID lpTlsValue);
-
- void WINAPI TlsShutdown();
+VOID WINAPI Sleep(_In_ DWORD dwMilliseconds);
+
+DWORD WINAPI TlsAlloc();
+BOOL WINAPI TlsFree(_In_ DWORD dwTlsIndex);
+LPVOID WINAPI TlsGetValue(_In_ DWORD dwTlsIndex);
+BOOL WINAPI TlsSetValue(_In_ DWORD dwTlsIndex, _In_opt_ LPVOID lpTlsValue);
+
+void WINAPI TlsShutdown();
}
OpenPOWER on IntegriCloud