Skip to content

Commit 3bb369c

Browse files
committed
Use libpthread primitives for OpenBSD mutexes.
There has been some discussion as to whether this is the right approach, centered around internal pointers in the underlying mutex structure. After much thought, let's commit this for now. The argument: * While it is true that OpenBSD has futex(2) and in fact is used in the underlying implementations in Dispatch. I'm not confident right now creating robust locking primitives by hand from futexes. It would be ideal to just delegate all of this to Dispatch, but Dispatch doesn't expose a ready-use API for mutexes. Cobbling one together might be possible, but that would take some time and finesse. * While recent versions of C and C++ have language support for mutexes, they are implemented in many cases by libpthread anyway, so there is nothing inherently gained right now by not using the pthread API other than portability. * While the concern for internal pointers for the pthread API is important, the OpenBSD is mitigated by the fact that pthread_mutex_t is pointer-valued on the platform. The concern that this might not always be the case is mitigated by the fact that this commit does not attempt to use the pthread implementation as a catch-all for all platforms. * The alternative is to use MutexUnavailable, but given Foundation has some dependencies on Mutex, this may cause problems elsewhere throughout the port.
1 parent 1d38956 commit 3bb369c

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

stdlib/public/Synchronization/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ set(SWIFT_SYNCHRONIZATION_WINDOWS_SOURCES
8080
Mutex/WindowsImpl.swift
8181
)
8282

83+
# OpenBSD sources
84+
85+
set(SWIFT_SYNCHRONIZATION_OPENBSD_SOURCES
86+
Mutex/Mutex.swift
87+
Mutex/OpenBSDImpl.swift
88+
)
89+
8390
set(SWIFT_SYNCHRNOIZATION_SWIFT_FLAGS
8491
${SWIFT_STANDARD_LIBRARY_SWIFT_FLAGS}
8592
"-enable-builtin-module"
@@ -115,6 +122,8 @@ add_swift_target_library(swiftSynchronization ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES
115122
${SWIFT_SYNCHRONIZATION_WINDOWS_SOURCES}
116123
SWIFT_SOURCES_DEPENDS_FREEBSD
117124
${SWIFT_SYNCHRONIZATION_FREEBSD_SOURCES}
125+
SWIFT_SOURCES_DEPENDS_OPENBSD
126+
${SWIFT_SYNCHRONIZATION_OPENBSD_SOURCES}
118127
SWIFT_SOURCES_DEPENDS_FREESTANDING
119128
Mutex/MutexUnavailable.swift
120129

@@ -140,6 +149,8 @@ add_swift_target_library(swiftSynchronization ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES
140149
WinSDK
141150
SWIFT_MODULE_DEPENDS_FREEBSD
142151
Glibc
152+
SWIFT_MODULE_DEPENDS_OPENBSD
153+
Glibc
143154

144155
SWIFT_COMPILE_FLAGS
145156
${SWIFT_SYNCHRNOIZATION_SWIFT_FLAGS}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift Atomics open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import Glibc
14+
15+
@available(SwiftStdlib 6.0, *)
16+
@frozen
17+
@_staticExclusiveOnly
18+
public struct _MutexHandle: ~Copyable {
19+
@usableFromInline
20+
let value: _Cell<pthread_mutex_t?>
21+
22+
@available(SwiftStdlib 6.0, *)
23+
@_alwaysEmitIntoClient
24+
@_transparent
25+
public init() {
26+
var mx = pthread_mutex_t(bitPattern: 0)
27+
pthread_mutex_init(&mx, nil)
28+
value = _Cell(mx)
29+
}
30+
31+
@available(SwiftStdlib 6.0, *)
32+
@_alwaysEmitIntoClient
33+
@_transparent
34+
internal borrowing func _lock() {
35+
pthread_mutex_lock(value._address)
36+
}
37+
38+
@available(SwiftStdlib 6.0, *)
39+
@_alwaysEmitIntoClient
40+
@_transparent
41+
internal borrowing func _tryLock() -> Bool {
42+
pthread_mutex_trylock(value._address) != 0
43+
}
44+
45+
@available(SwiftStdlib 6.0, *)
46+
@_alwaysEmitIntoClient
47+
@_transparent
48+
internal borrowing func _unlock() {
49+
pthread_mutex_unlock(value._address)
50+
}
51+
52+
@available(SwiftStdlib 6.0, *)
53+
@_alwaysEmitIntoClient
54+
@_transparent
55+
deinit {
56+
pthread_mutex_destroy(value._address)
57+
}
58+
}

0 commit comments

Comments
 (0)