13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Thread Library 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * --------------------------- 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Win32 implementation of thread management. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deThread.h" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if (DE_OS == DE_OS_WIN32 || DE_OS == DE_OS_WINCE) 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h" 2958da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos#include "deInt32.h" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define VC_EXTRALEAN 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define WIN32_LEAN_AND_MEAN 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <windows.h> 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/* Thread handle equals deThread in this implementation. */ 363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_STATIC_ASSERT(sizeof(deThread) >= sizeof(HANDLE)); 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef struct ThreadEntry_s 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deThreadFunc func; 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void* arg; 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} ThreadEntry; 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int mapPriority (deThreadPriority priority) 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (priority) 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case DE_THREADPRIORITY_LOWEST: return THREAD_PRIORITY_IDLE; 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case DE_THREADPRIORITY_LOW: return THREAD_PRIORITY_LOWEST; 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case DE_THREADPRIORITY_NORMAL: return THREAD_PRIORITY_NORMAL; 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case DE_THREADPRIORITY_HIGH: return THREAD_PRIORITY_ABOVE_NORMAL; 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case DE_THREADPRIORITY_HIGHEST: return THREAD_PRIORITY_HIGHEST; 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: DE_ASSERT(DE_FALSE); 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic DWORD __stdcall startThread (LPVOID entryPtr) 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ThreadEntry* entry = (ThreadEntry*)entryPtr; 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deThreadFunc func = entry->func; 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void* arg = entry->arg; 633fdee359c9eee4d6c1d823b23f7f64631b5945f8Jarkko Pöyry 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deFree(entry); 653fdee359c9eee4d6c1d823b23f7f64631b5945f8Jarkko Pöyry 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry func(arg); 673fdee359c9eee4d6c1d823b23f7f64631b5945f8Jarkko Pöyry 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 713c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeThread deThread_create (deThreadFunc func, void* arg, const deThreadAttributes* attributes) 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ThreadEntry* entry = (ThreadEntry*)deMalloc(sizeof(ThreadEntry)); 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry HANDLE thread = 0; 753fdee359c9eee4d6c1d823b23f7f64631b5945f8Jarkko Pöyry 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!entry) 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 783fdee359c9eee4d6c1d823b23f7f64631b5945f8Jarkko Pöyry 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry->func = func; 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry->arg = arg; 813fdee359c9eee4d6c1d823b23f7f64631b5945f8Jarkko Pöyry 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry thread = CreateThread(DE_NULL, 0, startThread, entry, 0, DE_NULL); 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!thread) 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deFree(entry); 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 883fdee359c9eee4d6c1d823b23f7f64631b5945f8Jarkko Pöyry 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (attributes) 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SetThreadPriority(thread, mapPriority(attributes->priority)); 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (deThread)thread; 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 953c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool deThread_join (deThread thread) 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry HANDLE handle = (HANDLE)thread; 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WaitForSingleObject(handle, INFINITE); 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_TRUE; 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid deThread_destroy (deThread thread) 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry HANDLE handle = (HANDLE)thread; 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CloseHandle(handle); 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid deSleep (deUint32 milliseconds) 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Sleep((DWORD)milliseconds); 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid deYield (void) 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1163fdee359c9eee4d6c1d823b23f7f64631b5945f8Jarkko Pöyry SwitchToThread(); 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11958da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulosstatic SYSTEM_LOGICAL_PROCESSOR_INFORMATION* getWin32ProcessorInfo (deUint32* numBytes) 12058da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos{ 12158da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos deUint32 curSize = (deUint32)sizeof(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)*8; 12258da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos SYSTEM_LOGICAL_PROCESSOR_INFORMATION* info = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION*)deMalloc(curSize); 12358da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 12458da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos for (;;) 12558da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos { 12658da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos DWORD inOutLen = curSize; 12758da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos DWORD err; 12858da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 12958da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos if (GetLogicalProcessorInformation(info, &inOutLen)) 13058da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos { 13158da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos *numBytes = inOutLen; 13258da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos return info; 13358da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos } 13458da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos else 13558da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos { 13658da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos err = GetLastError(); 13758da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 13858da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos if (err == ERROR_INSUFFICIENT_BUFFER) 13958da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos { 14058da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos curSize <<= 1; 14158da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos info = deRealloc(info, curSize); 14258da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos } 14358da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos else 14458da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos { 14558da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos deFree(info); 14658da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos return DE_NULL; 14758da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos } 14858da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos } 14958da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos } 15058da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos} 15158da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 15258da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulostypedef struct ProcessorInfo_s 15358da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos{ 15458da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos deUint32 numPhysicalCores; 15558da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos deUint32 numLogicalCores; 15658da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos} ProcessorInfo; 15758da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 15858da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulosvoid parseWin32ProcessorInfo (ProcessorInfo* dst, const SYSTEM_LOGICAL_PROCESSOR_INFORMATION* src, deUint32 numBytes) 15958da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos{ 16058da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos const SYSTEM_LOGICAL_PROCESSOR_INFORMATION* cur = src; 16158da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 16258da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos deMemset(dst, 0, sizeof(ProcessorInfo)); 16358da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 16458da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos while (((const deUint8*)cur - (const deUint8*)src) + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= numBytes) 16558da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos { 16658da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos if (cur->Relationship == RelationProcessorCore) 16758da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos { 16858da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos dst->numPhysicalCores += 1; 16958da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos#if (DE_PTR_SIZE == 8) 17058da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos dst->numLogicalCores += dePop64(cur->ProcessorMask); 17158da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos#else 17258da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos dst->numLogicalCores += dePop32(cur->ProcessorMask); 17358da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos#endif 17458da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos } 17558da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 17658da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos cur++; 17758da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos } 17858da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos} 17958da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 18058da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry HaulosdeBool getProcessorInfo (ProcessorInfo* info) 18158da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos{ 18258da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos deUint32 numBytes = 0; 18358da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos SYSTEM_LOGICAL_PROCESSOR_INFORMATION* rawInfo = getWin32ProcessorInfo(&numBytes); 18458da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 18558da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos if (!numBytes) 18658da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos return DE_FALSE; 18758da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 18858da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos parseWin32ProcessorInfo(info, rawInfo, numBytes); 18958da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos deFree(rawInfo); 19058da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 19158da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos return DE_TRUE; 19258da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos} 19358da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 19458da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry HaulosdeUint32 deGetNumTotalPhysicalCores (void) 19558da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos{ 19658da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos ProcessorInfo info; 19758da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 19858da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos if (!getProcessorInfo(&info)) 19958da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos return 1u; 20058da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 20158da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos return info.numPhysicalCores; 20258da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos} 20358da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 20458da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry HaulosdeUint32 deGetNumTotalLogicalCores (void) 20558da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos{ 20658da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos ProcessorInfo info; 20758da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 20858da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos if (!getProcessorInfo(&info)) 20958da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos return 1u; 21058da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 21158da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos return info.numLogicalCores; 21258da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos} 21358da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 21458da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry HaulosdeUint32 deGetNumAvailableLogicalCores (void) 21558da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos{ 21658da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos return deGetNumTotalLogicalCores(); 21758da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos} 21858da74f0a5e226f1ee74718fb2d5e46b14f12757Pyry Haulos 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* DE_OS */ 220