Skip to content

[stdlib/msvc] Runtime with MSVC library (Part) #2829

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

Merged
merged 1 commit into from
Jun 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
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 include/swift/Runtime/Mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

#if (defined(__APPLE__) || defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__))
#include "swift/Runtime/MutexPThread.h"
#elif defined(_MSC_VER)
#include "swift/Runtime/MutexWin32.h"
#else
#error "Implement equivalent of MutexPThread.h/cpp for your platform."
#endif
Expand Down
95 changes: 95 additions & 0 deletions include/swift/Runtime/MutexWin32.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
//===--- MutexWin32.h - ---------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Mutex, ConditionVariable, Read/Write lock, and Scoped lock implementations
// using Windows Slim Reader/Writer Locks and Conditional Variables.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_RUNTIME_MUTEX_WIN32_H
#define SWIFT_RUNTIME_MUTEX_WIN32_H

#include <windows.h>

namespace swift {

typedef CONDITION_VARIABLE ConditionHandle;
typedef SRWLOCK MutexHandle;
typedef SRWLOCK ReadWriteLockHandle;

#define CONDITION_SUPPORTS_CONSTEXPR 1
#define MUTEX_SUPPORTS_CONSTEXPR 1
#define READWRITELOCK_SUPPORTS_CONSTEXPR 1

struct ConditionPlatformHelper {
static constexpr ConditionHandle staticInit() {
return CONDITION_VARIABLE_INIT;
};
static void init(ConditionHandle &condition) {
InitializeConditionVariable(&condition);
}
static void destroy(ConditionHandle &condition) {}
static void notifyOne(ConditionHandle &condition) {
WakeConditionVariable(&condition);
}
static void notifyAll(ConditionHandle &condition) {
WakeAllConditionVariable(&condition);
}
static void wait(ConditionHandle &condition, MutexHandle &mutex);
};

struct MutexPlatformHelper {
static constexpr MutexHandle staticInit() { return SRWLOCK_INIT; }
static void init(MutexHandle &mutex, bool checked = false) {
InitializeSRWLock(&mutex);
}
static void destroy(MutexHandle &mutex) {}
static void lock(MutexHandle &mutex) { AcquireSRWLockExclusive(&mutex); }
static void unlock(MutexHandle &mutex) { ReleaseSRWLockExclusive(&mutex); }
static bool try_lock(MutexHandle &mutex) {
return TryAcquireSRWLockExclusive(&mutex) != 0;
}
// The unsafe versions don't do error checking.
static void unsafeLock(MutexHandle &mutex) {
AcquireSRWLockExclusive(&mutex);
}
static void unsafeUnlock(MutexHandle &mutex) {
ReleaseSRWLockExclusive(&mutex);
}
};

struct ReadWriteLockPlatformHelper {
static constexpr ReadWriteLockHandle staticInit() { return SRWLOCK_INIT; }
static void init(ReadWriteLockHandle &rwlock) { InitializeSRWLock(&rwlock); }
static void destroy(ReadWriteLockHandle &rwlock) {}
static void readLock(ReadWriteLockHandle &rwlock) {
AcquireSRWLockShared(&rwlock);
}
static bool try_readLock(ReadWriteLockHandle &rwlock) {
return TryAcquireSRWLockShared(&rwlock) != 0;
}
static void readUnlock(ReadWriteLockHandle &rwlock) {
ReleaseSRWLockShared(&rwlock);
}
static void writeLock(ReadWriteLockHandle &rwlock) {
AcquireSRWLockExclusive(&rwlock);
}
static bool try_writeLock(ReadWriteLockHandle &rwlock) {
return TryAcquireSRWLockExclusive(&rwlock) != 0;
}
static void writeUnlock(ReadWriteLockHandle &rwlock) {
ReleaseSRWLockExclusive(&rwlock);
}
};
}

#endif
2 changes: 2 additions & 0 deletions stdlib/public/SwiftShims/LibcShims.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ namespace swift { extern "C" {
// the current platform in the runtime code.
#if defined(__linux__) && defined (__arm__) && !defined(__android__)
typedef int __swift_ssize_t;
#elif defined(_MSC_VER)
typedef long long __swift_ssize_t;
#else
typedef long int __swift_ssize_t;
#endif
Expand Down
13 changes: 11 additions & 2 deletions stdlib/public/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,17 @@ if(SWIFT_RUNTIME_ENABLE_LEAK_CHECKER)
endif()

set(swift_runtime_port_sources)
if("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN")
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
set(swift_runtime_port_sources
MutexWin32.cpp
CygwinPort.cpp)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN")
set(swift_runtime_port_sources
MutexPThread.cpp
CygwinPort.cpp)
else()
set(swift_runtime_port_sources
MutexPThread.cpp)
endif()

list(APPEND swift_runtime_compile_flags
Expand Down Expand Up @@ -48,7 +56,6 @@ set(swift_runtime_sources
KnownMetadata.cpp
Metadata.cpp
MetadataLookup.cpp
MutexPThread.cpp
Once.cpp
Portability.cpp
ProtocolConformance.cpp
Expand All @@ -60,6 +67,8 @@ set(swift_runtime_sources
set(LLVM_OPTIONAL_SOURCES
Remangle.cpp
swift_sections.S
MutexPThread.cpp
MutexWin32.cpp
CygwinPort.cpp
${swift_runtime_sources}
${swift_runtime_objc_sources}
Expand Down
3 changes: 2 additions & 1 deletion stdlib/public/runtime/CygwinPort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ uint8_t *swift::_swift_getSectionDataPE(void *handle, const char *sectionName,

return nullptr;
}

#if !defined(_MSC_VER)
void swift::_swift_once_f(uintptr_t *predicate, void *context,
void (*function)(void *)) {
// FIXME: This implementation does a global lock, which is much worse than
Expand All @@ -148,3 +148,4 @@ void swift::_swift_once_f(uintptr_t *predicate, void *context,
} else
swiftOnceMutex.unlock();
}
#endif
2 changes: 2 additions & 0 deletions stdlib/public/runtime/HeapObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
#include <cstring>
#include <cstdio>
#include <cstdlib>
#if !defined(_MSC_VER)
#include <unistd.h>
#endif
#include "../SwiftShims/RuntimeShims.h"
#if SWIFT_OBJC_INTEROP
# include <objc/NSObject.h>
Expand Down
32 changes: 32 additions & 0 deletions stdlib/public/runtime/MutexWin32.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//===--- MutexWin32.cpp - -------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Mutex, ConditionVariable, Read/Write lock, and Scoped lock implementations
// using Windows Slim Reader/Writer Locks and Conditional Variables.
//
//===----------------------------------------------------------------------===//

#include "swift/Runtime/Mutex.h"
#include "swift/Runtime/Debug.h"

using namespace swift;

void ConditionPlatformHelper::wait(CONDITION_VARIABLE &condition,
SRWLOCK &mutex) {
BOOL result = SleepConditionVariableSRW(&condition, &mutex, INFINITE, 0);
if (result == FALSE) {
DWORD errorcode = GetLastError();
fatalError(/* flags = */ 0,
"'SleepConditionVariableSRW()' failed with error code %d\n",
errorcode);
}
}
60 changes: 46 additions & 14 deletions stdlib/public/stubs/Assert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,41 @@

#include "swift/Runtime/Config.h"
#include "swift/Runtime/Debug.h"
#include <cstdarg>
#include <cstdint>
#include <stdio.h>
#include <stdlib.h>

using namespace swift;

static int swift_asprintf(char **strp, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
#if defined(_MSC_VER)
int len = _vscprintf(fmt, args);
if (len < 0) {
va_end(args);
return -1;
}
char *buffer = static_cast<char *>(malloc(len + 1));
if (!buffer) {
va_end(args);
return -1;
}
int result = vsprintf(buffer, fmt, args);
if (result < 0) {
va_end(args);
free(buffer);
return -1;
}
*strp = buffer;
#else
int result = vasprintf(strp, fmt, args);
#endif
va_end(args);
return result;
}

// Report a fatal error to system console, stderr, and crash logs.
// <prefix>: <message>: file <file>, line <line>\n
// The message may be omitted by passing messageLength=0.
Expand All @@ -33,10 +62,11 @@ _swift_stdlib_reportFatalErrorInFile(const char *prefix, intptr_t prefixLength,
uintptr_t line,
uint32_t flags) {
char *log;
asprintf(&log, "%.*s: %.*s%sfile %.*s, line %zu\n", (int)prefixLength, prefix,
(int)messageLength, message, (messageLength ? ": " : ""),
(int)fileLength, file, (size_t)line);

swift_asprintf(&log, "%.*s: %.*s%sfile %.*s, line %zu\n", (int)prefixLength,
prefix, (int)messageLength, message,
(messageLength ? ": " : ""), (int)fileLength, file,
(size_t)line);

swift_reportError(flags, log);
free(log);
}
Expand All @@ -52,9 +82,9 @@ _swift_stdlib_reportFatalError(const char *prefix,
intptr_t messageLength,
uint32_t flags) {
char *log;
asprintf(&log, "%.*s: %.*s\n", (int)prefixLength, prefix,
(int)messageLength, message);
swift_asprintf(&log, "%.*s: %.*s\n", (int)prefixLength, prefix,
(int)messageLength, message);

swift_reportError(flags, log);
free(log);
}
Expand All @@ -69,10 +99,11 @@ _swift_stdlib_reportUnimplementedInitializerInFile(
intptr_t initNameLength, const char *file, intptr_t fileLength,
uintptr_t line, uintptr_t column, uint32_t flags) {
char *log;
asprintf(&log, "%.*s: %zu: %zu: fatal error: use of unimplemented "
"initializer '%.*s' for class '%.*s'\n",
(int)fileLength, file, (size_t)line, (size_t)column,
(int)initNameLength, initName, (int)classNameLength, className);
swift_asprintf(&log, "%.*s: %zu: %zu: fatal error: use of unimplemented "
"initializer '%.*s' for class '%.*s'\n",
(int)fileLength, file, (size_t)line, (size_t)column,
(int)initNameLength, initName, (int)classNameLength,
className);

swift_reportError(flags, log);
free(log);
Expand All @@ -89,9 +120,10 @@ _swift_stdlib_reportUnimplementedInitializer(const char *className,
intptr_t initNameLength,
uint32_t flags) {
char *log;
asprintf(&log, "fatal error: use of unimplemented "
"initializer '%.*s' for class '%.*s'\n",
(int)initNameLength, initName, (int)classNameLength, className);
swift_asprintf(&log, "fatal error: use of unimplemented "
"initializer '%.*s' for class '%.*s'\n",
(int)initNameLength, initName, (int)classNameLength,
className);

swift_reportError(flags, log);
free(log);
Expand Down
12 changes: 6 additions & 6 deletions stdlib/public/stubs/UnicodeNormalization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class ASCIICollation {
for (unsigned char c = 0; c < 128; ++c) {
UErrorCode ErrorCode = U_ZERO_ERROR;
intptr_t NumCollationElts = 0;
#if defined(__CYGWIN__)
#if defined(__CYGWIN__) || defined(_MSC_VER)
UChar Buffer[1];
#else
uint16_t Buffer[1];
Expand Down Expand Up @@ -134,7 +134,7 @@ swift::_swift_stdlib_unicode_compare_utf16_utf16(const uint16_t *LeftString,
int32_t LeftLength,
const uint16_t *RightString,
int32_t RightLength) {
#if defined(__CYGWIN__)
#if defined(__CYGWIN__) || defined(_MSC_VER)
// ICU UChar type is platform dependent. In Cygwin, it is defined
// as wchar_t which size is 2. It seems that the underlying binary
// representation is same with swift utf16 representation.
Expand Down Expand Up @@ -163,7 +163,7 @@ swift::_swift_stdlib_unicode_compare_utf8_utf16(const char *LeftString,
UErrorCode ErrorCode = U_ZERO_ERROR;

uiter_setUTF8(&LeftIterator, LeftString, LeftLength);
#if defined(__CYGWIN__)
#if defined(__CYGWIN__) || defined(_MSC_VER)
uiter_setString(&RightIterator, reinterpret_cast<const UChar *>(RightString),
RightLength);
#else
Expand Down Expand Up @@ -220,7 +220,7 @@ swift::_swift_stdlib_unicode_compare_utf8_utf8(const char *LeftString,
static intptr_t hashChunk(const UCollator *Collator, intptr_t HashState,
const uint16_t *Str, uint32_t Length,
UErrorCode *ErrorCode) {
#if defined(__CYGWIN__)
#if defined(__CYGWIN__) || defined(_MSC_VER)
UCollationElements *CollationIterator = ucol_openElements(
Collator, reinterpret_cast<const UChar *>(Str), Length, ErrorCode);
#else
Expand Down Expand Up @@ -300,7 +300,7 @@ swift::_swift_stdlib_unicode_strToUpper(uint16_t *Destination,
const uint16_t *Source,
int32_t SourceLength) {
UErrorCode ErrorCode = U_ZERO_ERROR;
#if defined(__CYGWIN__)
#if defined(__CYGWIN__) || defined(_MSC_VER)
uint32_t OutputLength = u_strToUpper(reinterpret_cast<UChar *>(Destination),
DestinationCapacity,
reinterpret_cast<const UChar *>(Source),
Expand All @@ -327,7 +327,7 @@ swift::_swift_stdlib_unicode_strToLower(uint16_t *Destination,
const uint16_t *Source,
int32_t SourceLength) {
UErrorCode ErrorCode = U_ZERO_ERROR;
#if defined(__CYGWIN__)
#if defined(__CYGWIN__) || defined(_MSC_VER)
uint32_t OutputLength = u_strToLower(reinterpret_cast<UChar *>(Destination),
DestinationCapacity,
reinterpret_cast<const UChar *>(Source),
Expand Down