Skip to content

Commit decd65d

Browse files
authored
Merge pull request #21356 from compnerd/harness
StdlibUnittest: port the test harness to Windows
2 parents 4891507 + b7e21da commit decd65d

File tree

6 files changed

+200
-21
lines changed

6 files changed

+200
-21
lines changed

stdlib/private/StdlibUnittest/CMakeLists.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ if (NOT IS_BUILD_TYPE_OPTIMIZED)
1010
list(APPEND swift_stdlib_unittest_compile_flags "-DSWIFT_STDLIB_DEBUG")
1111
endif()
1212

13-
# TODO: support this on non-POSIX platforms. It cannot be currently as it
14-
# depends on pthreads.
1513
add_swift_target_library(swiftStdlibUnittest ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB
1614
# This file should be listed the first. Module name is inferred from the
1715
# filename.
@@ -42,7 +40,8 @@ add_swift_target_library(swiftStdlibUnittest ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES}
4240
SWIFT_MODULE_DEPENDS_FREEBSD Glibc
4341
SWIFT_MODULE_DEPENDS_CYGWIN Glibc
4442
SWIFT_MODULE_DEPENDS_HAIKU Glibc
43+
SWIFT_MODULE_DEPENDS_WINDOWS MSVCRT WinSDK
4544
SWIFT_COMPILE_FLAGS ${swift_stdlib_unittest_compile_flags}
46-
TARGET_SDKS ALL_POSIX_PLATFORMS
4745
INSTALL_IN_COMPONENT stdlib-experimental)
46+
set_source_files_properties(InspectValue.cpp PROPERTIES COMPILE_FLAGS -std=c++14)
4847

stdlib/private/StdlibUnittest/InterceptTraps.cpp

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,37 +13,77 @@
1313
#include <stdio.h>
1414
#include <signal.h>
1515
#include <string.h>
16+
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
1617
#include <unistd.h>
18+
#endif
19+
#if defined(_WIN32)
20+
#include <io.h>
21+
#include <process.h>
22+
#include <stdlib.h>
23+
#define WIN32_LEAN_AND_MEAN
24+
#include <Windows.h>
25+
#endif
1726

1827
#include "swift/Runtime/Config.h"
1928

2029
static void CrashCatcher(int Sig) {
2130
const char *Msg;
2231
switch (Sig) {
2332
case SIGILL: Msg = "CRASHED: SIGILL\n"; break;
24-
case SIGTRAP: Msg = "CRASHED: SIGTRAP\n"; break;
2533
case SIGABRT: Msg = "CRASHED: SIGABRT\n"; break;
2634
case SIGFPE: Msg = "CRASHED: SIGFPE\n"; break;
27-
case SIGBUS: Msg = "CRASHED: SIGBUS\n"; break;
2835
case SIGSEGV: Msg = "CRASHED: SIGSEGV\n"; break;
36+
#if !defined(_WIN32)
37+
case SIGTRAP: Msg = "CRASHED: SIGTRAP\n"; break;
38+
case SIGBUS: Msg = "CRASHED: SIGBUS\n"; break;
2939
case SIGSYS: Msg = "CRASHED: SIGSYS\n"; break;
40+
#endif
3041
default: Msg = "CRASHED: SIG????\n"; break;
3142
}
43+
#if defined(_WIN32)
44+
_write(_fileno(stderr), Msg, strlen(Msg));
45+
#else
3246
write(STDERR_FILENO, Msg, strlen(Msg));
47+
#endif
3348
_exit(0);
3449
}
3550

51+
#if defined(_WIN32)
52+
static LONG WINAPI
53+
VectoredCrashHandler(PEXCEPTION_POINTERS ExceptionInfo) {
54+
switch (ExceptionInfo->ExceptionRecord->ExceptionCode) {
55+
case EXCEPTION_ILLEGAL_INSTRUCTION:
56+
_write(_fileno(stderr), "CRASHED: SIGTRAP\n", 17);
57+
_exit(0);
58+
59+
case EXCEPTION_DATATYPE_MISALIGNMENT:
60+
_write(_fileno(stderr), "CRASHED: SIGBUS\n", 16);
61+
_exit(0);
62+
}
63+
64+
return EXCEPTION_CONTINUE_SEARCH;
65+
}
66+
#endif
67+
3668
SWIFT_CC(swift) SWIFT_RUNTIME_LIBRARY_VISIBILITY extern "C"
3769
void installTrapInterceptor() {
3870
// Disable buffering on stdout so that everything is printed before crashing.
3971
setbuf(stdout, 0);
4072

73+
#if defined(_WIN32)
74+
_set_abort_behavior(1, _WRITE_ABORT_MSG);
75+
#endif
76+
4177
signal(SIGILL, CrashCatcher);
42-
signal(SIGTRAP, CrashCatcher);
4378
signal(SIGABRT, CrashCatcher);
4479
signal(SIGFPE, CrashCatcher);
45-
signal(SIGBUS, CrashCatcher);
4680
signal(SIGSEGV, CrashCatcher);
81+
#if defined(_WIN32)
82+
AddVectoredExceptionHandler(TRUE, VectoredCrashHandler);
83+
#else
84+
signal(SIGTRAP, CrashCatcher);
85+
signal(SIGBUS, CrashCatcher);
4786
signal(SIGSYS, CrashCatcher);
87+
#endif
4888
}
4989

stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public func getFloat32(_ x: Float32) -> Float32 { return _opaqueIdentity(x) }
7171
@inline(never)
7272
public func getFloat64(_ x: Float64) -> Float64 { return _opaqueIdentity(x) }
7373

74-
#if arch(i386) || arch(x86_64)
74+
#if !os(Windows) && (arch(i386) || arch(x86_64))
7575
@inline(never)
7676
public func getFloat80(_ x: Float80) -> Float80 { return _opaqueIdentity(x) }
7777
#endif

stdlib/private/StdlibUnittest/RaceTest.swift

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ import SwiftPrivateThreadExtras
4343
import Darwin
4444
#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Cygwin) || os(Haiku)
4545
import Glibc
46+
#elseif os(Windows)
47+
import MSVCRT
48+
import WinSDK
4649
#endif
4750

4851
#if _runtime(_ObjC)
@@ -508,6 +511,36 @@ func _workerThreadOneTrial<RT>(
508511
}
509512

510513
/// One-shot sleep in one thread, allowing interrupt by another.
514+
#if os(Windows)
515+
class _InterruptibleSleep {
516+
let event: HANDLE?
517+
var completed: Bool = false
518+
519+
init() {
520+
self.event = CreateEventW(nil, TRUE, FALSE, nil)
521+
precondition(self.event != nil)
522+
}
523+
524+
deinit {
525+
CloseHandle(self.event)
526+
}
527+
528+
func sleep(durationInSeconds duration: Int) {
529+
guard completed == false else { return }
530+
531+
let result: DWORD = WaitForSingleObject(event, DWORD(duration * 1000))
532+
precondition(result == WAIT_OBJECT_0)
533+
534+
completed = true
535+
}
536+
537+
func wake() {
538+
guard completed == false else { return }
539+
let result: BOOL = SetEvent(self.event)
540+
precondition(result == TRUE)
541+
}
542+
}
543+
#else
511544
class _InterruptibleSleep {
512545
let writeEnd: CInt
513546
let readEnd: CInt
@@ -550,6 +583,13 @@ class _InterruptibleSleep {
550583
precondition(ret >= 0)
551584
}
552585
}
586+
#endif
587+
588+
#if os(Windows)
589+
typealias ThreadHandle = HANDLE
590+
#else
591+
typealias ThreadHandle = pthread_t
592+
#endif
553593

554594
public func runRaceTest<RT : RaceTestWithPerTrialData>(
555595
_: RT.Type,
@@ -600,8 +640,8 @@ public func runRaceTest<RT : RaceTestWithPerTrialData>(
600640
_ = timeoutReached.fetchAndAdd(1)
601641
}
602642

603-
var testTids = [pthread_t]()
604-
var alarmTid: pthread_t
643+
var testTids = [ThreadHandle]()
644+
var alarmTid: ThreadHandle
605645

606646
// Create the master thread.
607647
do {

stdlib/private/StdlibUnittest/StdlibCoreExtras.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import SwiftPrivateLibcExtras
1616
import Darwin
1717
#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Cygwin) || os(Haiku)
1818
import Glibc
19+
#elseif os(Windows)
20+
import MSVCRT
1921
#endif
2022

2123
#if _runtime(_ObjC)
@@ -73,6 +75,7 @@ func findSubstring(_ string: String, _ substring: String) -> String.Index? {
7375
#endif
7476
}
7577

78+
#if !os(Windows)
7679
public func createTemporaryFile(
7780
_ fileNamePrefix: String, _ fileNameSuffix: String, _ contents: String
7881
) -> String {
@@ -95,6 +98,7 @@ public func createTemporaryFile(
9598
}
9699
return fileName
97100
}
101+
#endif
98102

99103
public final class Box<T> {
100104
public init(_ value: T) { self.value = value }

0 commit comments

Comments
 (0)