Skip to content

Commit 8053070

Browse files
committed
Merge pull request #2829 from tinysun212/pr-stdlib-msvc-2
2 parents fb83d45 + be815aa commit 8053070

File tree

9 files changed

+198
-23
lines changed

9 files changed

+198
-23
lines changed

include/swift/Runtime/Mutex.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
#if (defined(__APPLE__) || defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__))
2424
#include "swift/Runtime/MutexPThread.h"
25+
#elif defined(_MSC_VER)
26+
#include "swift/Runtime/MutexWin32.h"
2527
#else
2628
#error "Implement equivalent of MutexPThread.h/cpp for your platform."
2729
#endif

include/swift/Runtime/MutexWin32.h

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
//===--- MutexWin32.h - ---------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// Mutex, ConditionVariable, Read/Write lock, and Scoped lock implementations
14+
// using Windows Slim Reader/Writer Locks and Conditional Variables.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef SWIFT_RUNTIME_MUTEX_WIN32_H
19+
#define SWIFT_RUNTIME_MUTEX_WIN32_H
20+
21+
#include <windows.h>
22+
23+
namespace swift {
24+
25+
typedef CONDITION_VARIABLE ConditionHandle;
26+
typedef SRWLOCK MutexHandle;
27+
typedef SRWLOCK ReadWriteLockHandle;
28+
29+
#define CONDITION_SUPPORTS_CONSTEXPR 1
30+
#define MUTEX_SUPPORTS_CONSTEXPR 1
31+
#define READWRITELOCK_SUPPORTS_CONSTEXPR 1
32+
33+
struct ConditionPlatformHelper {
34+
static constexpr ConditionHandle staticInit() {
35+
return CONDITION_VARIABLE_INIT;
36+
};
37+
static void init(ConditionHandle &condition) {
38+
InitializeConditionVariable(&condition);
39+
}
40+
static void destroy(ConditionHandle &condition) {}
41+
static void notifyOne(ConditionHandle &condition) {
42+
WakeConditionVariable(&condition);
43+
}
44+
static void notifyAll(ConditionHandle &condition) {
45+
WakeAllConditionVariable(&condition);
46+
}
47+
static void wait(ConditionHandle &condition, MutexHandle &mutex);
48+
};
49+
50+
struct MutexPlatformHelper {
51+
static constexpr MutexHandle staticInit() { return SRWLOCK_INIT; }
52+
static void init(MutexHandle &mutex, bool checked = false) {
53+
InitializeSRWLock(&mutex);
54+
}
55+
static void destroy(MutexHandle &mutex) {}
56+
static void lock(MutexHandle &mutex) { AcquireSRWLockExclusive(&mutex); }
57+
static void unlock(MutexHandle &mutex) { ReleaseSRWLockExclusive(&mutex); }
58+
static bool try_lock(MutexHandle &mutex) {
59+
return TryAcquireSRWLockExclusive(&mutex) != 0;
60+
}
61+
// The unsafe versions don't do error checking.
62+
static void unsafeLock(MutexHandle &mutex) {
63+
AcquireSRWLockExclusive(&mutex);
64+
}
65+
static void unsafeUnlock(MutexHandle &mutex) {
66+
ReleaseSRWLockExclusive(&mutex);
67+
}
68+
};
69+
70+
struct ReadWriteLockPlatformHelper {
71+
static constexpr ReadWriteLockHandle staticInit() { return SRWLOCK_INIT; }
72+
static void init(ReadWriteLockHandle &rwlock) { InitializeSRWLock(&rwlock); }
73+
static void destroy(ReadWriteLockHandle &rwlock) {}
74+
static void readLock(ReadWriteLockHandle &rwlock) {
75+
AcquireSRWLockShared(&rwlock);
76+
}
77+
static bool try_readLock(ReadWriteLockHandle &rwlock) {
78+
return TryAcquireSRWLockShared(&rwlock) != 0;
79+
}
80+
static void readUnlock(ReadWriteLockHandle &rwlock) {
81+
ReleaseSRWLockShared(&rwlock);
82+
}
83+
static void writeLock(ReadWriteLockHandle &rwlock) {
84+
AcquireSRWLockExclusive(&rwlock);
85+
}
86+
static bool try_writeLock(ReadWriteLockHandle &rwlock) {
87+
return TryAcquireSRWLockExclusive(&rwlock) != 0;
88+
}
89+
static void writeUnlock(ReadWriteLockHandle &rwlock) {
90+
ReleaseSRWLockExclusive(&rwlock);
91+
}
92+
};
93+
}
94+
95+
#endif

stdlib/public/SwiftShims/LibcShims.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ namespace swift { extern "C" {
3131
// the current platform in the runtime code.
3232
#if defined(__linux__) && defined (__arm__) && !defined(__android__)
3333
typedef int __swift_ssize_t;
34+
#elif defined(_MSC_VER)
35+
typedef long long __swift_ssize_t;
3436
#else
3537
typedef long int __swift_ssize_t;
3638
#endif

stdlib/public/runtime/CMakeLists.txt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,17 @@ if(SWIFT_RUNTIME_ENABLE_LEAK_CHECKER)
1818
endif()
1919

2020
set(swift_runtime_port_sources)
21-
if("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN")
21+
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
2222
set(swift_runtime_port_sources
23+
MutexWin32.cpp
2324
CygwinPort.cpp)
25+
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN")
26+
set(swift_runtime_port_sources
27+
MutexPThread.cpp
28+
CygwinPort.cpp)
29+
else()
30+
set(swift_runtime_port_sources
31+
MutexPThread.cpp)
2432
endif()
2533

2634
list(APPEND swift_runtime_compile_flags
@@ -48,7 +56,6 @@ set(swift_runtime_sources
4856
KnownMetadata.cpp
4957
Metadata.cpp
5058
MetadataLookup.cpp
51-
MutexPThread.cpp
5259
Once.cpp
5360
Portability.cpp
5461
ProtocolConformance.cpp
@@ -60,6 +67,8 @@ set(swift_runtime_sources
6067
set(LLVM_OPTIONAL_SOURCES
6168
Remangle.cpp
6269
swift_sections.S
70+
MutexPThread.cpp
71+
MutexWin32.cpp
6372
CygwinPort.cpp
6473
${swift_runtime_sources}
6574
${swift_runtime_objc_sources}

stdlib/public/runtime/CygwinPort.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ uint8_t *swift::_swift_getSectionDataPE(void *handle, const char *sectionName,
133133

134134
return nullptr;
135135
}
136-
136+
#if !defined(_MSC_VER)
137137
void swift::_swift_once_f(uintptr_t *predicate, void *context,
138138
void (*function)(void *)) {
139139
// FIXME: This implementation does a global lock, which is much worse than
@@ -148,3 +148,4 @@ void swift::_swift_once_f(uintptr_t *predicate, void *context,
148148
} else
149149
swiftOnceMutex.unlock();
150150
}
151+
#endif

stdlib/public/runtime/HeapObject.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
#include <cstring>
2929
#include <cstdio>
3030
#include <cstdlib>
31+
#if !defined(_MSC_VER)
3132
#include <unistd.h>
33+
#endif
3234
#include "../SwiftShims/RuntimeShims.h"
3335
#if SWIFT_OBJC_INTEROP
3436
# include <objc/NSObject.h>

stdlib/public/runtime/MutexWin32.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//===--- MutexWin32.cpp - -------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// Mutex, ConditionVariable, Read/Write lock, and Scoped lock implementations
14+
// using Windows Slim Reader/Writer Locks and Conditional Variables.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#include "swift/Runtime/Mutex.h"
19+
#include "swift/Runtime/Debug.h"
20+
21+
using namespace swift;
22+
23+
void ConditionPlatformHelper::wait(CONDITION_VARIABLE &condition,
24+
SRWLOCK &mutex) {
25+
BOOL result = SleepConditionVariableSRW(&condition, &mutex, INFINITE, 0);
26+
if (result == FALSE) {
27+
DWORD errorcode = GetLastError();
28+
fatalError(/* flags = */ 0,
29+
"'SleepConditionVariableSRW()' failed with error code %d\n",
30+
errorcode);
31+
}
32+
}

stdlib/public/stubs/Assert.cpp

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,41 @@
1616

1717
#include "swift/Runtime/Config.h"
1818
#include "swift/Runtime/Debug.h"
19+
#include <cstdarg>
1920
#include <cstdint>
2021
#include <stdio.h>
2122
#include <stdlib.h>
2223

2324
using namespace swift;
2425

26+
static int swift_asprintf(char **strp, const char *fmt, ...) {
27+
va_list args;
28+
va_start(args, fmt);
29+
#if defined(_MSC_VER)
30+
int len = _vscprintf(fmt, args);
31+
if (len < 0) {
32+
va_end(args);
33+
return -1;
34+
}
35+
char *buffer = static_cast<char *>(malloc(len + 1));
36+
if (!buffer) {
37+
va_end(args);
38+
return -1;
39+
}
40+
int result = vsprintf(buffer, fmt, args);
41+
if (result < 0) {
42+
va_end(args);
43+
free(buffer);
44+
return -1;
45+
}
46+
*strp = buffer;
47+
#else
48+
int result = vasprintf(strp, fmt, args);
49+
#endif
50+
va_end(args);
51+
return result;
52+
}
53+
2554
// Report a fatal error to system console, stderr, and crash logs.
2655
// <prefix>: <message>: file <file>, line <line>\n
2756
// The message may be omitted by passing messageLength=0.
@@ -33,10 +62,11 @@ _swift_stdlib_reportFatalErrorInFile(const char *prefix, intptr_t prefixLength,
3362
uintptr_t line,
3463
uint32_t flags) {
3564
char *log;
36-
asprintf(&log, "%.*s: %.*s%sfile %.*s, line %zu\n", (int)prefixLength, prefix,
37-
(int)messageLength, message, (messageLength ? ": " : ""),
38-
(int)fileLength, file, (size_t)line);
39-
65+
swift_asprintf(&log, "%.*s: %.*s%sfile %.*s, line %zu\n", (int)prefixLength,
66+
prefix, (int)messageLength, message,
67+
(messageLength ? ": " : ""), (int)fileLength, file,
68+
(size_t)line);
69+
4070
swift_reportError(flags, log);
4171
free(log);
4272
}
@@ -52,9 +82,9 @@ _swift_stdlib_reportFatalError(const char *prefix,
5282
intptr_t messageLength,
5383
uint32_t flags) {
5484
char *log;
55-
asprintf(&log, "%.*s: %.*s\n", (int)prefixLength, prefix,
56-
(int)messageLength, message);
57-
85+
swift_asprintf(&log, "%.*s: %.*s\n", (int)prefixLength, prefix,
86+
(int)messageLength, message);
87+
5888
swift_reportError(flags, log);
5989
free(log);
6090
}
@@ -69,10 +99,11 @@ _swift_stdlib_reportUnimplementedInitializerInFile(
6999
intptr_t initNameLength, const char *file, intptr_t fileLength,
70100
uintptr_t line, uintptr_t column, uint32_t flags) {
71101
char *log;
72-
asprintf(&log, "%.*s: %zu: %zu: fatal error: use of unimplemented "
73-
"initializer '%.*s' for class '%.*s'\n",
74-
(int)fileLength, file, (size_t)line, (size_t)column,
75-
(int)initNameLength, initName, (int)classNameLength, className);
102+
swift_asprintf(&log, "%.*s: %zu: %zu: fatal error: use of unimplemented "
103+
"initializer '%.*s' for class '%.*s'\n",
104+
(int)fileLength, file, (size_t)line, (size_t)column,
105+
(int)initNameLength, initName, (int)classNameLength,
106+
className);
76107

77108
swift_reportError(flags, log);
78109
free(log);
@@ -89,9 +120,10 @@ _swift_stdlib_reportUnimplementedInitializer(const char *className,
89120
intptr_t initNameLength,
90121
uint32_t flags) {
91122
char *log;
92-
asprintf(&log, "fatal error: use of unimplemented "
93-
"initializer '%.*s' for class '%.*s'\n",
94-
(int)initNameLength, initName, (int)classNameLength, className);
123+
swift_asprintf(&log, "fatal error: use of unimplemented "
124+
"initializer '%.*s' for class '%.*s'\n",
125+
(int)initNameLength, initName, (int)classNameLength,
126+
className);
95127

96128
swift_reportError(flags, log);
97129
free(log);

stdlib/public/stubs/UnicodeNormalization.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class ASCIICollation {
9393
for (unsigned char c = 0; c < 128; ++c) {
9494
UErrorCode ErrorCode = U_ZERO_ERROR;
9595
intptr_t NumCollationElts = 0;
96-
#if defined(__CYGWIN__)
96+
#if defined(__CYGWIN__) || defined(_MSC_VER)
9797
UChar Buffer[1];
9898
#else
9999
uint16_t Buffer[1];
@@ -134,7 +134,7 @@ swift::_swift_stdlib_unicode_compare_utf16_utf16(const uint16_t *LeftString,
134134
int32_t LeftLength,
135135
const uint16_t *RightString,
136136
int32_t RightLength) {
137-
#if defined(__CYGWIN__)
137+
#if defined(__CYGWIN__) || defined(_MSC_VER)
138138
// ICU UChar type is platform dependent. In Cygwin, it is defined
139139
// as wchar_t which size is 2. It seems that the underlying binary
140140
// representation is same with swift utf16 representation.
@@ -163,7 +163,7 @@ swift::_swift_stdlib_unicode_compare_utf8_utf16(const char *LeftString,
163163
UErrorCode ErrorCode = U_ZERO_ERROR;
164164

165165
uiter_setUTF8(&LeftIterator, LeftString, LeftLength);
166-
#if defined(__CYGWIN__)
166+
#if defined(__CYGWIN__) || defined(_MSC_VER)
167167
uiter_setString(&RightIterator, reinterpret_cast<const UChar *>(RightString),
168168
RightLength);
169169
#else
@@ -220,7 +220,7 @@ swift::_swift_stdlib_unicode_compare_utf8_utf8(const char *LeftString,
220220
static intptr_t hashChunk(const UCollator *Collator, intptr_t HashState,
221221
const uint16_t *Str, uint32_t Length,
222222
UErrorCode *ErrorCode) {
223-
#if defined(__CYGWIN__)
223+
#if defined(__CYGWIN__) || defined(_MSC_VER)
224224
UCollationElements *CollationIterator = ucol_openElements(
225225
Collator, reinterpret_cast<const UChar *>(Str), Length, ErrorCode);
226226
#else
@@ -300,7 +300,7 @@ swift::_swift_stdlib_unicode_strToUpper(uint16_t *Destination,
300300
const uint16_t *Source,
301301
int32_t SourceLength) {
302302
UErrorCode ErrorCode = U_ZERO_ERROR;
303-
#if defined(__CYGWIN__)
303+
#if defined(__CYGWIN__) || defined(_MSC_VER)
304304
uint32_t OutputLength = u_strToUpper(reinterpret_cast<UChar *>(Destination),
305305
DestinationCapacity,
306306
reinterpret_cast<const UChar *>(Source),
@@ -327,7 +327,7 @@ swift::_swift_stdlib_unicode_strToLower(uint16_t *Destination,
327327
const uint16_t *Source,
328328
int32_t SourceLength) {
329329
UErrorCode ErrorCode = U_ZERO_ERROR;
330-
#if defined(__CYGWIN__)
330+
#if defined(__CYGWIN__) || defined(_MSC_VER)
331331
uint32_t OutputLength = u_strToLower(reinterpret_cast<UChar *>(Destination),
332332
DestinationCapacity,
333333
reinterpret_cast<const UChar *>(Source),

0 commit comments

Comments
 (0)