v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
semaphore.cc
Go to the documentation of this file.
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #include "platform/semaphore.h"
29 
30 #if V8_OS_MACOSX
31 #include <mach/mach_init.h>
32 #include <mach/task.h>
33 #endif
34 
35 #include <errno.h>
36 
37 #include "checks.h"
38 #include "platform/time.h"
39 
40 namespace v8 {
41 namespace internal {
42 
43 #if V8_OS_MACOSX
44 
45 Semaphore::Semaphore(int count) {
46  kern_return_t result = semaphore_create(
47  mach_task_self(), &native_handle_, SYNC_POLICY_FIFO, count);
48  ASSERT_EQ(KERN_SUCCESS, result);
49  USE(result);
50 }
51 
52 
53 Semaphore::~Semaphore() {
54  kern_return_t result = semaphore_destroy(mach_task_self(), native_handle_);
55  ASSERT_EQ(KERN_SUCCESS, result);
56  USE(result);
57 }
58 
59 
60 void Semaphore::Signal() {
61  kern_return_t result = semaphore_signal(native_handle_);
62  ASSERT_EQ(KERN_SUCCESS, result);
63  USE(result);
64 }
65 
66 
67 void Semaphore::Wait() {
68  while (true) {
69  kern_return_t result = semaphore_wait(native_handle_);
70  if (result == KERN_SUCCESS) return; // Semaphore was signalled.
71  ASSERT_EQ(KERN_ABORTED, result);
72  }
73 }
74 
75 
76 bool Semaphore::WaitFor(const TimeDelta& rel_time) {
77  TimeTicks now = TimeTicks::Now();
78  TimeTicks end = now + rel_time;
79  while (true) {
80  mach_timespec_t ts;
81  if (now >= end) {
82  // Return immediately if semaphore was not signalled.
83  ts.tv_sec = 0;
84  ts.tv_nsec = 0;
85  } else {
86  ts = (end - now).ToMachTimespec();
87  }
88  kern_return_t result = semaphore_timedwait(native_handle_, ts);
89  if (result == KERN_SUCCESS) return true; // Semaphore was signalled.
90  if (result == KERN_OPERATION_TIMED_OUT) return false; // Timeout.
91  ASSERT_EQ(KERN_ABORTED, result);
92  now = TimeTicks::Now();
93  }
94 }
95 
96 #elif V8_OS_POSIX
97 
98 Semaphore::Semaphore(int count) {
99  ASSERT(count >= 0);
100  int result = sem_init(&native_handle_, 0, count);
101  ASSERT_EQ(0, result);
102  USE(result);
103 }
104 
105 
106 Semaphore::~Semaphore() {
107  int result = sem_destroy(&native_handle_);
108  ASSERT_EQ(0, result);
109  USE(result);
110 }
111 
112 
113 void Semaphore::Signal() {
114  int result = sem_post(&native_handle_);
115  ASSERT_EQ(0, result);
116  USE(result);
117 }
118 
119 
120 void Semaphore::Wait() {
121  while (true) {
122  int result = sem_wait(&native_handle_);
123  if (result == 0) return; // Semaphore was signalled.
124  // Signal caused spurious wakeup.
125  ASSERT_EQ(-1, result);
126  ASSERT_EQ(EINTR, errno);
127  }
128 }
129 
130 
131 bool Semaphore::WaitFor(const TimeDelta& rel_time) {
132  // Compute the time for end of timeout.
133  const Time time = Time::NowFromSystemTime() + rel_time;
134  const struct timespec ts = time.ToTimespec();
135 
136  // Wait for semaphore signalled or timeout.
137  while (true) {
138  int result = sem_timedwait(&native_handle_, &ts);
139  if (result == 0) return true; // Semaphore was signalled.
140 #if V8_LIBC_GLIBC && !V8_GLIBC_PREREQ(2, 4)
141  if (result > 0) {
142  // sem_timedwait in glibc prior to 2.3.4 returns the errno instead of -1.
143  errno = result;
144  result = -1;
145  }
146 #endif
147  if (result == -1 && errno == ETIMEDOUT) {
148  // Timed out while waiting for semaphore.
149  return false;
150  }
151  // Signal caused spurious wakeup.
152  ASSERT_EQ(-1, result);
153  ASSERT_EQ(EINTR, errno);
154  }
155 }
156 
157 #elif V8_OS_WIN
158 
159 Semaphore::Semaphore(int count) {
160  ASSERT(count >= 0);
161  native_handle_ = ::CreateSemaphoreA(NULL, count, 0x7fffffff, NULL);
162  ASSERT(native_handle_ != NULL);
163 }
164 
165 
166 Semaphore::~Semaphore() {
167  BOOL result = CloseHandle(native_handle_);
168  ASSERT(result);
169  USE(result);
170 }
171 
172 
173 void Semaphore::Signal() {
174  LONG dummy;
175  BOOL result = ReleaseSemaphore(native_handle_, 1, &dummy);
176  ASSERT(result);
177  USE(result);
178 }
179 
180 
181 void Semaphore::Wait() {
182  DWORD result = WaitForSingleObject(native_handle_, INFINITE);
183  ASSERT(result == WAIT_OBJECT_0);
184  USE(result);
185 }
186 
187 
188 bool Semaphore::WaitFor(const TimeDelta& rel_time) {
189  TimeTicks now = TimeTicks::Now();
190  TimeTicks end = now + rel_time;
191  while (true) {
192  int64_t msec = (end - now).InMilliseconds();
193  if (msec >= static_cast<int64_t>(INFINITE)) {
194  DWORD result = WaitForSingleObject(native_handle_, INFINITE - 1);
195  if (result == WAIT_OBJECT_0) {
196  return true;
197  }
198  ASSERT(result == WAIT_TIMEOUT);
199  now = TimeTicks::Now();
200  } else {
201  DWORD result = WaitForSingleObject(
202  native_handle_, (msec < 0) ? 0 : static_cast<DWORD>(msec));
203  if (result == WAIT_TIMEOUT) {
204  return false;
205  }
206  ASSERT(result == WAIT_OBJECT_0);
207  return true;
208  }
209  }
210 }
211 
212 #endif // V8_OS_MACOSX
213 
214 } } // namespace v8::internal
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
Definition: flags.cc:269
void Signal(const v8::FunctionCallbackInfo< v8::Value > &args)
#define ASSERT(condition)
Definition: checks.h:329
typedef DWORD(__stdcall *DLL_FUNC_TYPE(SymGetOptions))(VOID)
typedef BOOL(__stdcall *DLL_FUNC_TYPE(SymInitialize))(IN HANDLE hProcess
#define ASSERT_EQ(v1, v2)
Definition: checks.h:330
void USE(T)
Definition: globals.h:341