V8 Project
semaphore.cc
Go to the documentation of this file.
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 #if V8_OS_MACOSX
8 #include <mach/mach_init.h>
9 #include <mach/task.h>
10 #endif
11 
12 #include <errno.h>
13 
14 #include "src/base/logging.h"
16 #include "src/base/platform/time.h"
17 
18 namespace v8 {
19 namespace base {
20 
21 #if V8_OS_MACOSX
22 
23 Semaphore::Semaphore(int count) {
24  kern_return_t result = semaphore_create(
25  mach_task_self(), &native_handle_, SYNC_POLICY_FIFO, count);
26  DCHECK_EQ(KERN_SUCCESS, result);
27  USE(result);
28 }
29 
30 
31 Semaphore::~Semaphore() {
32  kern_return_t result = semaphore_destroy(mach_task_self(), native_handle_);
33  DCHECK_EQ(KERN_SUCCESS, result);
34  USE(result);
35 }
36 
37 
38 void Semaphore::Signal() {
39  kern_return_t result = semaphore_signal(native_handle_);
40  DCHECK_EQ(KERN_SUCCESS, result);
41  USE(result);
42 }
43 
44 
45 void Semaphore::Wait() {
46  while (true) {
47  kern_return_t result = semaphore_wait(native_handle_);
48  if (result == KERN_SUCCESS) return; // Semaphore was signalled.
49  DCHECK_EQ(KERN_ABORTED, result);
50  }
51 }
52 
53 
54 bool Semaphore::WaitFor(const TimeDelta& rel_time) {
55  TimeTicks now = TimeTicks::Now();
56  TimeTicks end = now + rel_time;
57  while (true) {
58  mach_timespec_t ts;
59  if (now >= end) {
60  // Return immediately if semaphore was not signalled.
61  ts.tv_sec = 0;
62  ts.tv_nsec = 0;
63  } else {
64  ts = (end - now).ToMachTimespec();
65  }
66  kern_return_t result = semaphore_timedwait(native_handle_, ts);
67  if (result == KERN_SUCCESS) return true; // Semaphore was signalled.
68  if (result == KERN_OPERATION_TIMED_OUT) return false; // Timeout.
69  DCHECK_EQ(KERN_ABORTED, result);
70  now = TimeTicks::Now();
71  }
72 }
73 
74 #elif V8_OS_POSIX
75 
76 Semaphore::Semaphore(int count) {
77  DCHECK(count >= 0);
78  int result = sem_init(&native_handle_, 0, count);
79  DCHECK_EQ(0, result);
80  USE(result);
81 }
82 
83 
84 Semaphore::~Semaphore() {
85  int result = sem_destroy(&native_handle_);
86  DCHECK_EQ(0, result);
87  USE(result);
88 }
89 
90 
91 void Semaphore::Signal() {
92  int result = sem_post(&native_handle_);
93  DCHECK_EQ(0, result);
94  USE(result);
95 }
96 
97 
98 void Semaphore::Wait() {
99  while (true) {
100  int result = sem_wait(&native_handle_);
101  if (result == 0) return; // Semaphore was signalled.
102  // Signal caused spurious wakeup.
103  DCHECK_EQ(-1, result);
104  DCHECK_EQ(EINTR, errno);
105  }
106 }
107 
108 
109 bool Semaphore::WaitFor(const TimeDelta& rel_time) {
110 #if V8_OS_NACL
111  // PNaCL doesn't support sem_timedwait, do ugly busy waiting.
112  ElapsedTimer timer;
113  timer.Start();
114  do {
115  int result = sem_trywait(&native_handle_);
116  if (result == 0) return true;
117  DCHECK(errno == EAGAIN || errno == EINTR);
118  } while (!timer.HasExpired(rel_time));
119  return false;
120 #else
121  // Compute the time for end of timeout.
122  const Time time = Time::NowFromSystemTime() + rel_time;
123  const struct timespec ts = time.ToTimespec();
124 
125  // Wait for semaphore signalled or timeout.
126  while (true) {
127  int result = sem_timedwait(&native_handle_, &ts);
128  if (result == 0) return true; // Semaphore was signalled.
129 #if V8_LIBC_GLIBC && !V8_GLIBC_PREREQ(2, 4)
130  if (result > 0) {
131  // sem_timedwait in glibc prior to 2.3.4 returns the errno instead of -1.
132  errno = result;
133  result = -1;
134  }
135 #endif
136  if (result == -1 && errno == ETIMEDOUT) {
137  // Timed out while waiting for semaphore.
138  return false;
139  }
140  // Signal caused spurious wakeup.
141  DCHECK_EQ(-1, result);
142  DCHECK_EQ(EINTR, errno);
143  }
144 #endif
145 }
146 
147 #elif V8_OS_WIN
148 
149 Semaphore::Semaphore(int count) {
150  DCHECK(count >= 0);
151  native_handle_ = ::CreateSemaphoreA(NULL, count, 0x7fffffff, NULL);
152  DCHECK(native_handle_ != NULL);
153 }
154 
155 
156 Semaphore::~Semaphore() {
157  BOOL result = CloseHandle(native_handle_);
158  DCHECK(result);
159  USE(result);
160 }
161 
162 
163 void Semaphore::Signal() {
164  LONG dummy;
165  BOOL result = ReleaseSemaphore(native_handle_, 1, &dummy);
166  DCHECK(result);
167  USE(result);
168 }
169 
170 
171 void Semaphore::Wait() {
172  DWORD result = WaitForSingleObject(native_handle_, INFINITE);
173  DCHECK(result == WAIT_OBJECT_0);
174  USE(result);
175 }
176 
177 
178 bool Semaphore::WaitFor(const TimeDelta& rel_time) {
179  TimeTicks now = TimeTicks::Now();
180  TimeTicks end = now + rel_time;
181  while (true) {
182  int64_t msec = (end - now).InMilliseconds();
183  if (msec >= static_cast<int64_t>(INFINITE)) {
184  DWORD result = WaitForSingleObject(native_handle_, INFINITE - 1);
185  if (result == WAIT_OBJECT_0) {
186  return true;
187  }
188  DCHECK(result == WAIT_TIMEOUT);
189  now = TimeTicks::Now();
190  } else {
191  DWORD result = WaitForSingleObject(
192  native_handle_, (msec < 0) ? 0 : static_cast<DWORD>(msec));
193  if (result == WAIT_TIMEOUT) {
194  return false;
195  }
196  DCHECK(result == WAIT_OBJECT_0);
197  return true;
198  }
199  }
200 }
201 
202 #endif // V8_OS_MACOSX
203 
204 } } // namespace v8::base
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
Definition: logging.h:205
#define DCHECK_EQ(v1, v2)
Definition: logging.h:206
void USE(T)
Definition: macros.h:322
typedef DWORD(__stdcall *DLL_FUNC_TYPE(SymGetOptions))(VOID)
typedef BOOL(__stdcall *DLL_FUNC_TYPE(SymInitialize))(IN HANDLE hProcess
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20