130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/* 230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Copyright 2011 Google Inc. All Rights Reserved. 330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * 430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Licensed under the Apache License, Version 2.0 (the "License"); 530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * you may not use this file except in compliance with the License. 630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * You may obtain a copy of the License at 730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * 830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * http://www.apache.org/licenses/LICENSE-2.0 930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * 1030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Unless required by applicable law or agreed to in writing, software 1130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * distributed under the License is distributed on an "AS IS" BASIS, 1230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * See the License for the specific language governing permissions and 1430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * limitations under the License. 1530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun */ 1630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 1730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "test/platform_thread.h" 1830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnamespace sfntly { 2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (WIN32) 2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunDWORD __stdcall ThreadFunc(void* params) { 2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun PlatformThread::Delegate* delegate = 2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static_cast<PlatformThread::Delegate*>(params); 2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun delegate->ThreadMain(); 2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return 0; 2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool PlatformThread::Create(Delegate* delegate, 3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun PlatformThreadHandle* thread_handle) { 3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(thread_handle); 3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun *thread_handle = CreateThread(NULL, 0, ThreadFunc, delegate, 0, NULL); 3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun if (!(*thread_handle)) { 3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return false; 3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return true; 4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid PlatformThread::Join(PlatformThreadHandle thread_handle) { 4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(thread_handle); 4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun DWORD result = WaitForSingleObject(thread_handle, INFINITE); 4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(result == WAIT_OBJECT_0); 4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun CloseHandle(thread_handle); 4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid PlatformThread::Sleep(int32_t duration_ms) { 5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ::Sleep(duration_ms); 5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#else 5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid* ThreadFunc(void* params) { 5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun PlatformThread::Delegate* delegate = 5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static_cast<PlatformThread::Delegate*>(params); 6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun delegate->ThreadMain(); 6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return NULL; 6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool PlatformThread::Create(Delegate* delegate, 6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun PlatformThreadHandle* thread_handle) { 6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(thread_handle); 6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun bool success = false; 7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun pthread_attr_t attributes; 7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun pthread_attr_init(&attributes); 7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun success = !pthread_create(thread_handle, &attributes, ThreadFunc, delegate); 7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun pthread_attr_destroy(&attributes); 7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return success; 7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid PlatformThread::Join(PlatformThreadHandle thread_handle) { 8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun assert(thread_handle); 8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun pthread_join(thread_handle, NULL); 8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static 8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid PlatformThread::Sleep(int32_t duration_ms) { 8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun struct timespec sleep_time, remaining; 8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // Contains the portion of duration_ms >= 1 sec. 8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun sleep_time.tv_sec = duration_ms / 1000; 9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun duration_ms -= sleep_time.tv_sec * 1000; 9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // Contains the portion of duration_ms < 1 sec. 9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun sleep_time.tv_nsec = duration_ms * 1000 * 1000; // nanoseconds. 9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun while (nanosleep(&sleep_time, &remaining) == -1 && errno == EINTR) 9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun sleep_time = remaining; 9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif // WIN32 10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} // namespace sfntly 102