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 //
5 // Based on
6 // https://cs.chromium.org/chromium/src/v8/src/base/platform/semaphore.cc
7
8 #include "util/semaphore.h"
9
10 #include "base/logging.h"
11
12 #if defined(OS_WIN)
13 #include <windows.h>
14 #endif
15
16 #if defined(OS_MACOSX)
17
Semaphore(int count)18 Semaphore::Semaphore(int count) {
19 native_handle_ = dispatch_semaphore_create(count);
20 DCHECK(native_handle_);
21 }
22
~Semaphore()23 Semaphore::~Semaphore() {
24 dispatch_release(native_handle_);
25 }
26
Signal()27 void Semaphore::Signal() {
28 dispatch_semaphore_signal(native_handle_);
29 }
30
Wait()31 void Semaphore::Wait() {
32 dispatch_semaphore_wait(native_handle_, DISPATCH_TIME_FOREVER);
33 }
34
35 #elif defined(OS_POSIX)
36
Semaphore(int count)37 Semaphore::Semaphore(int count) {
38 DCHECK_GE(count, 0);
39 int result = sem_init(&native_handle_, 0, count);
40 DCHECK_EQ(0, result);
41 }
42
~Semaphore()43 Semaphore::~Semaphore() {
44 int result = sem_destroy(&native_handle_);
45 DCHECK_EQ(0, result);
46 }
47
Signal()48 void Semaphore::Signal() {
49 int result = sem_post(&native_handle_);
50 // This check may fail with <libc-2.21, which we use on the try bots, if the
51 // semaphore is destroyed while sem_post is still executed. A work around is
52 // to extend the lifetime of the semaphore.
53 CHECK_EQ(0, result);
54 }
55
Wait()56 void Semaphore::Wait() {
57 while (true) {
58 int result = sem_wait(&native_handle_);
59 if (result == 0)
60 return; // Semaphore was signalled.
61 // Signal caused spurious wakeup.
62 DCHECK_EQ(-1, result);
63 DCHECK_EQ(EINTR, errno);
64 }
65 }
66
67 #elif defined(OS_WIN)
68
Semaphore(int count)69 Semaphore::Semaphore(int count) {
70 DCHECK_GE(count, 0);
71 native_handle_ = ::CreateSemaphoreA(nullptr, count, 0x7FFFFFFF, nullptr);
72 DCHECK(native_handle_);
73 }
74
~Semaphore()75 Semaphore::~Semaphore() {
76 BOOL result = CloseHandle(native_handle_);
77 DCHECK(result);
78 }
79
Signal()80 void Semaphore::Signal() {
81 LONG dummy;
82 BOOL result = ReleaseSemaphore(native_handle_, 1, &dummy);
83 DCHECK(result);
84 }
85
Wait()86 void Semaphore::Wait() {
87 DWORD result = WaitForSingleObject(native_handle_, INFINITE);
88 DCHECK(result == WAIT_OBJECT_0);
89 }
90
91 #endif
92