1053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com/*
2053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com * Copyright 2011 Google Inc. All Rights Reserved.
3053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com *
4053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com * Licensed under the Apache License, Version 2.0 (the "License");
5053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com * you may not use this file except in compliance with the License.
6053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com * You may obtain a copy of the License at
7053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com *
8053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com *      http://www.apache.org/licenses/LICENSE-2.0
9053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com *
10053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com * Unless required by applicable law or agreed to in writing, software
11053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com * distributed under the License is distributed on an "AS IS" BASIS,
12053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com * See the License for the specific language governing permissions and
14053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com * limitations under the License.
15053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com */
16053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
17053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com#include "test/platform_thread.h"
18053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
19053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.comnamespace sfntly {
20053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
21053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com#if defined (WIN32)
22053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
23053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.comDWORD __stdcall ThreadFunc(void* params) {
24053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  PlatformThread::Delegate* delegate =
25053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com      static_cast<PlatformThread::Delegate*>(params);
26053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  delegate->ThreadMain();
27053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  return 0;
28053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com}
29053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
30053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com// static
31053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.combool PlatformThread::Create(Delegate* delegate,
32053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com                            PlatformThreadHandle* thread_handle) {
33053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  assert(thread_handle);
34053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  *thread_handle = CreateThread(NULL, 0, ThreadFunc, delegate, 0, NULL);
35053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  if (!(*thread_handle)) {
36053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com    return false;
37053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  }
38053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
39053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  return true;
40053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com}
41053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
42053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com// static
43053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.comvoid PlatformThread::Join(PlatformThreadHandle thread_handle) {
44053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  assert(thread_handle);
45053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  DWORD result = WaitForSingleObject(thread_handle, INFINITE);
46053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  assert(result == WAIT_OBJECT_0);
47053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  CloseHandle(thread_handle);
48053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com}
49053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
50053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com// static
51053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.comvoid PlatformThread::Sleep(int32_t duration_ms) {
52053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  ::Sleep(duration_ms);
53053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com}
54053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
55053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com#else
56053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
57053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.comvoid* ThreadFunc(void* params) {
58053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  PlatformThread::Delegate* delegate =
59053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com      static_cast<PlatformThread::Delegate*>(params);
60053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  delegate->ThreadMain();
61053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  return NULL;
62053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com}
63053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
64053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com// static
65053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.combool PlatformThread::Create(Delegate* delegate,
66053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com                            PlatformThreadHandle* thread_handle) {
67053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  assert(thread_handle);
68053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
69053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  bool success = false;
70053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  pthread_attr_t attributes;
71053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  pthread_attr_init(&attributes);
72053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  success = !pthread_create(thread_handle, &attributes, ThreadFunc, delegate);
73053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  pthread_attr_destroy(&attributes);
74053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
75053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  return success;
76053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com}
77053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
78053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com// static
79053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.comvoid PlatformThread::Join(PlatformThreadHandle thread_handle) {
80053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  assert(thread_handle);
81053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  pthread_join(thread_handle, NULL);
82053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com}
83053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
84053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com// static
85053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.comvoid PlatformThread::Sleep(int32_t duration_ms) {
86053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  struct timespec sleep_time, remaining;
87053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
88053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  // Contains the portion of duration_ms >= 1 sec.
89053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  sleep_time.tv_sec = duration_ms / 1000;
90053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  duration_ms -= sleep_time.tv_sec * 1000;
91053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
92053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  // Contains the portion of duration_ms < 1 sec.
93053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  sleep_time.tv_nsec = duration_ms * 1000 * 1000;  // nanoseconds.
94053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
95053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com  while (nanosleep(&sleep_time, &remaining) == -1 && errno == EINTR)
96053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com    sleep_time = remaining;
97053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com}
98053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
99053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com#endif  // WIN32
100053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com
101053885bde4e83c53465ea42257ba056d083afb07arthurhsu@google.com}  // namespace sfntly
102