Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix FreeBSD build and test #1149

Merged
merged 2 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Sources/SwiftDocC/Benchmark/Benchmark.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public class Benchmark: Encodable {
public let platform = "Linux"
#elseif os(Android)
public let platform = "Android"
#elseif os(FreeBSD)
public let platform = "FreeBSD"
#else
public let platform = "unsupported"
#endif
Expand Down
9 changes: 9 additions & 0 deletions Sources/SwiftDocC/Benchmark/Metrics/PeakMemory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ extension Benchmark {
) else { return nil }
return Int64(pmcStats.PeakWorkingSetSize)
}
#elseif os(FreeBSD)
private static func peakMemory() -> Int64? {
var usage = rusage()
if (getrusage(RUSAGE_SELF, &usage) == -1) {
return nil
} else {
return Int64(usage.ru_maxrss * 1024)
}
}
#endif

public var result: MetricValue? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ private class LongRunningService: ExternalLinkResolving {
/// This private class is only used by the ``OutOfProcessReferenceResolver`` and shouldn't be used for general communication with other processes.
private class LongRunningProcess: ExternalLinkResolving {

#if os(macOS) || os(Linux) || os(Android)
#if os(macOS) || os(Linux) || os(Android) || os(FreeBSD)
private let process: Process

init(location: URL, errorOutputHandler: @escaping (String) -> Void) throws {
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftDocC/Model/Rendering/RenderContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public struct RenderContext {
)
}

#if os(macOS) || os(iOS) || os(Android) || os(Windows)
#if os(macOS) || os(iOS) || os(Android) || os(Windows) || os(FreeBSD)
// Concurrently render content on macOS/iOS, Windows & Android
let results: [(reference: ResolvedTopicReference, content: RenderReferenceStore.TopicContent)] = references.concurrentPerform { reference, results in
results.append((reference, renderContentFor(reference)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

#if os(Linux) || os(Android) || os(Windows)
#if os(Linux) || os(Android) || os(Windows) || os(FreeBSD)
/// A shim for non-ObjC targets that runs the given block of code.
///
/// The existence of this shim allows you the use of auto-release pools to optimize memory footprint on Darwin platforms while maintaining
Expand Down
13 changes: 13 additions & 0 deletions Sources/SwiftDocC/Utility/Synchronization.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ public class Synchronized<Value> {
#elseif os(Linux) || os(Android)
/// A lock type appropriate for the current platform.
var lock: UnsafeMutablePointer<pthread_mutex_t>
#elseif os(FreeBSD)
/// A lock type appropriate for the current platform.
var lock: UnsafeMutablePointer<pthread_mutex_t?>
#elseif os(Windows)
var lock: UnsafeMutablePointer<SRWLOCK>
#else
Expand All @@ -53,6 +56,10 @@ public class Synchronized<Value> {
lock = UnsafeMutablePointer<pthread_mutex_t>.allocate(capacity: 1)
lock.initialize(to: pthread_mutex_t())
pthread_mutex_init(lock, nil)
#elseif os(FreeBSD)
lock = UnsafeMutablePointer<pthread_mutex_t?>.allocate(capacity: 1)
lock.initialize(to: nil)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be an initialized to pthread_mutex_t() like above (or rolled into the same #if scopes as the above?

Copy link
Contributor Author

@michael-yuji michael-yuji Jan 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

he main difference on BSD (FreeBSD, OpenBSD) platforms is that the lock type is a pthread_mutex_t? instead of pthread_mutex_t. This is due to on the BSDs, pthread_mutex_t is in fact a struct pthread_mutex pointer, thus it does not come with a default .init() constructor and we need initialize it to nil instead.

ref: http://fxr.watson.org/fxr/source/sys/_pthreadtypes.h?v=FREEBSD-13-STABLE;im=10#L71

pthread_mutex_init(lock, nil)
#elseif os(Windows)
lock = UnsafeMutablePointer<SRWLOCK>.allocate(capacity: 1)
InitializeSRWLock(lock)
Expand All @@ -77,6 +84,9 @@ public class Synchronized<Value> {
#elseif os(Linux) || os(Android)
pthread_mutex_lock(lock)
defer { pthread_mutex_unlock(lock) }
#elseif os(FreeBSD)
pthread_mutex_lock(lock)
defer { pthread_mutex_unlock(lock) }
#elseif os(Windows)
AcquireSRWLockExclusive(lock)
defer { ReleaseSRWLockExclusive(lock) }
Expand Down Expand Up @@ -113,6 +123,9 @@ extension Lock {
#elseif os(Linux) || os(Android)
pthread_mutex_lock(lock)
defer { pthread_mutex_unlock(lock) }
#elseif os(FreeBSD)
pthread_mutex_lock(lock)
defer { pthread_mutex_unlock(lock) }
#elseif os(Windows)
AcquireSRWLockExclusive(lock)
defer { ReleaseSRWLockExclusive(lock) }
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftDocCUtilities/Utility/DirectoryMonitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import Foundation
import SwiftDocC

#if !os(Linux) && !os(Android) && !os(Windows)
#if !os(Linux) && !os(Android) && !os(Windows) && !os(FreeBSD)
import Darwin

/// A throttle object to filter events that come too fast.
Expand Down
2 changes: 2 additions & 0 deletions Sources/SwiftDocCUtilities/Utility/Signal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public struct Signal {
signalAction.__sigaction_handler = unsafeBitCast(callback, to: sigaction.__Unnamed_union___sigaction_handler.self)
#elseif os(Android)
signalAction.sa_handler = callback
#elseif os(FreeBSD)
signalAction.__sigaction_u.__sa_handler = callback
#else
signalAction.__sigaction_u = unsafeBitCast(callback, to: __sigaction_u.self)
#endif
Expand Down
2 changes: 1 addition & 1 deletion Sources/docc/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

#if os(macOS) || os(Linux) || os(Android) || os(Windows)
#if os(macOS) || os(Linux) || os(Android) || os(Windows) || os(FreeBSD)
import SwiftDocCUtilities

await Task {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class DocumentationSchemeHandlerTests: XCTestCase {
forResource: "LegacyBundle_DoNotUseInNewTests", withExtension: "docc", subdirectory: "Test Bundles")!

func testDocumentationSchemeHandler() {
#if !os(Linux) && !os(Android) && !os(Windows)
#if !os(Linux) && !os(Android) && !os(Windows) && !os(FreeBSD)
let topicSchemeHandler = DocumentationSchemeHandler(withTemplateURL: templateURL)

let request = URLRequest(url: baseURL.appendingPathComponent("/images/figure1.jpg"))
Expand All @@ -50,7 +50,7 @@ class DocumentationSchemeHandlerTests: XCTestCase {
}

func testSetData() {
#if !os(Linux) && !os(Android) && !os(Windows)
#if !os(Linux) && !os(Android) && !os(Windows) && !os(FreeBSD)
let topicSchemeHandler = DocumentationSchemeHandler(withTemplateURL: templateURL)

let data = "hello!".data(using: .utf8)!
Expand Down
2 changes: 1 addition & 1 deletion Tests/SwiftDocCTests/Servers/FileServerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ class FileServerTests: XCTestCase {
(response, data) = fileServer.response(to: failingRequest)
XCTAssertNil(data)
// Initializing a URLResponse with `nil` as MIME type in Linux returns nil
#if os(Linux) || os(Android) || os(Windows)
#if os(Linux) || os(Android) || os(Windows) || os(FreeBSD)
XCTAssertNil(response.mimeType)
#else
// Doing the same in macOS or iOS returns the default MIME type
Expand Down
2 changes: 1 addition & 1 deletion Tests/SwiftDocCTests/Utility/LMDBTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ final class SwiftLMDBTests: XCTestCase {
}

func testArrayOfInt() throws {
#if !os(Linux) && !os(Android) && !os(Windows)
#if !os(Linux) && !os(Android) && !os(Windows) && !os(FreeBSD)
let database = try environment.openDatabase()

var array: [UInt32] = []
Expand Down
2 changes: 1 addition & 1 deletion Tests/SwiftDocCUtilitiesTests/C+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import Foundation
#if os(Windows)
import ucrt
#elseif os(Linux) || os(Android)
#elseif os(Linux) || os(Android) || os(FreeBSD)
import Glibc
#else
import Darwin
Expand Down
10 changes: 5 additions & 5 deletions Tests/SwiftDocCUtilitiesTests/DirectoryMonitorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import XCTest
@testable import SwiftDocCUtilities

#if !os(Linux) && !os(Android) && !os(Windows)
#if !os(Linux) && !os(Android) && !os(Windows) && !os(FreeBSD)
fileprivate extension NSNotification.Name {
static let testNodeUpdated = NSNotification.Name(rawValue: "testNodeUpdated")
static let testDirectoryReloaded = NSNotification.Name(rawValue: "testDirectoryReloaded")
Expand All @@ -24,7 +24,7 @@ func fileURLsAreEqual(_ url1: URL, _ url2: URL) -> Bool {
#endif

class DirectoryMonitorTests: XCTestCase {
#if !os(Linux) && !os(Android) && !os(Windows)
#if !os(Linux) && !os(Android) && !os(Windows) && !os(FreeBSD)
// - MARK: Directory watching test infra

/// Method that automates setting up a directory monitor, setting up the relevant expectations for a test,
Expand Down Expand Up @@ -118,7 +118,7 @@ class DirectoryMonitorTests: XCTestCase {
/// Tests a succession of file system changes and verifies that they produce
/// the expected monitor events.
func testMonitorUpdates() throws {
#if !os(Linux) && !os(Android) && !os(Windows)
#if !os(Linux) && !os(Android) && !os(Windows) && !os(FreeBSD)

// Create temp folder & sub-folder.
let tempSubfolderURL = try createTemporaryDirectory(named: "subfolder")
Expand Down Expand Up @@ -167,7 +167,7 @@ class DirectoryMonitorTests: XCTestCase {
}

func testMonitorDoesNotTriggerUpdates() throws {
#if !os(Linux) && !os(Android) && !os(Windows)
#if !os(Linux) && !os(Android) && !os(Windows) && !os(FreeBSD)

// Create temp folder & sub-folder.
let tempSubfolderURL = try createTemporaryDirectory(named: "subfolder")
Expand Down Expand Up @@ -200,7 +200,7 @@ class DirectoryMonitorTests: XCTestCase {

/// Tests a zero sum change aggregation triggers an event.
func testMonitorZeroSumSizeChangesUpdates() throws {
#if !os(Linux) && !os(Android) && !os(Windows)
#if !os(Linux) && !os(Android) && !os(Windows) && !os(FreeBSD)

// Create temp folder & sub-folder.
let tempSubfolderURL = try createTemporaryDirectory(named: "subfolder")
Expand Down