mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
stdlib: split topic-focused modules out of StdlibUnittest
The new modules are: * SwiftUnstable -- assorted additions to the core standard library (more algorithms etc.) * SwiftUnstableDarwinExtras -- proposed additions to the Darwin overlay, not yet reviewed by the Darwin team. * SwiftUnstablePthreadExtras -- wrappers that make it possible to use pthread in Swift (they work around the lack of block-based API in pthread). In future these could be possibly folded into the Darwin overlay as well. These APIs are useful without StdlibUnittest for writing automation tools in Swift. Just like SwiftExperimental, none of these modules are exposed to extrenal users. Also, since these new modules can be compiled with -sil-serialize-all (unlike StdlibUnittest, where we can't apply the flag because of compiler bugs), standard library tests that need to run optimized code (like AtomicInt.swift) are *much* faster now. Swift SVN r25679
This commit is contained in:
@@ -120,6 +120,10 @@ MAP_STDLIB_TYPE("u_int16_t", UnsignedInt, 16, "UInt16", All, false, DoNothing)
|
||||
MAP_STDLIB_TYPE("u_int32_t", UnsignedInt, 32, "UInt32", All, false, DoNothing)
|
||||
MAP_STDLIB_TYPE("u_int64_t", UnsignedInt, 64, "UInt64", All, false, DoNothing)
|
||||
|
||||
// SwiftShims defines its own types.
|
||||
MAP_STDLIB_TYPE("__swift_ssize_t", SignedWord, 0, "Int", All, false,
|
||||
DefineOnly)
|
||||
|
||||
// stdarg.h types.
|
||||
// FIXME: why does this not catch va_list on x86_64?
|
||||
MAP_STDLIB_TYPE("va_list", VaList, 0, "CVaListPointer", All, false, DoNothing)
|
||||
|
||||
9
stdlib/darwin_extras/CMakeLists.txt
Normal file
9
stdlib/darwin_extras/CMakeLists.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
add_swift_library(swiftSwiftUnstableDarwinExtras SHARED IS_STDLIB
|
||||
# This file should be listed the first. Module name is inferred from the
|
||||
# filename.
|
||||
SwiftUnstableDarwinExtras.swift
|
||||
Subprocess.swift
|
||||
|
||||
SWIFT_COMPILE_FLAGS -Xfrontend -sil-serialize-all
|
||||
INSTALL_IN_COMPONENT stdlib-experimental)
|
||||
|
||||
@@ -10,80 +10,9 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import SwiftUnstable
|
||||
import Darwin
|
||||
|
||||
var _stdlib_FD_SETSIZE: CInt {
|
||||
return 1024
|
||||
}
|
||||
|
||||
struct _stdlib_fd_set {
|
||||
var _data: _UnitTestArray<UInt32>
|
||||
static var _wordBits: Int {
|
||||
return sizeof(UInt32) * 8
|
||||
}
|
||||
|
||||
init() {
|
||||
_data = _UnitTestArray<UInt32>(
|
||||
count: Int(_stdlib_FD_SETSIZE) / _stdlib_fd_set._wordBits,
|
||||
repeatedValue: 0)
|
||||
}
|
||||
|
||||
func isset(fd: CInt) -> Bool {
|
||||
let fdInt = Int(fd)
|
||||
return (
|
||||
_data[fdInt / _stdlib_fd_set._wordBits] &
|
||||
UInt32(1 << (fdInt % _stdlib_fd_set._wordBits))
|
||||
) != 0
|
||||
}
|
||||
|
||||
mutating func set(fd: CInt) {
|
||||
let fdInt = Int(fd)
|
||||
_data[fdInt / _stdlib_fd_set._wordBits] |=
|
||||
UInt32(1 << (fdInt % _stdlib_fd_set._wordBits))
|
||||
}
|
||||
|
||||
mutating func clear(fd: CInt) {
|
||||
let fdInt = Int(fd)
|
||||
_data[fdInt / _stdlib_fd_set._wordBits] &=
|
||||
~UInt32(1 << (fdInt % _stdlib_fd_set._wordBits))
|
||||
}
|
||||
|
||||
mutating func zero() {
|
||||
let count = _data.count
|
||||
return _data.withUnsafeMutableBufferPointer {
|
||||
(_data) in
|
||||
for i in 0..<count {
|
||||
_data[i] = 0
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func _stdlib_select(
|
||||
inout readfds: _stdlib_fd_set, inout writefds: _stdlib_fd_set,
|
||||
inout errorfds: _stdlib_fd_set, timeout: UnsafeMutablePointer<timeval>
|
||||
) -> CInt {
|
||||
return readfds._data.withUnsafeMutableBufferPointer {
|
||||
(readfds) in
|
||||
writefds._data.withUnsafeMutableBufferPointer {
|
||||
(writefds) in
|
||||
errorfds._data.withUnsafeMutableBufferPointer {
|
||||
(errorfds) in
|
||||
let readAddr = readfds.baseAddress
|
||||
let writeAddr = writefds.baseAddress
|
||||
let errorAddr = errorfds.baseAddress
|
||||
return select(
|
||||
_stdlib_FD_SETSIZE,
|
||||
UnsafeMutablePointer(readAddr),
|
||||
UnsafeMutablePointer(writeAddr),
|
||||
UnsafeMutablePointer(errorAddr),
|
||||
timeout)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Calls POSIX `pipe()`.
|
||||
func posixPipe() -> (readFD: CInt, writeFD: CInt) {
|
||||
var fds: _UnitTestArray<CInt> = [ -1, -1 ]
|
||||
@@ -99,7 +28,7 @@ func posixPipe() -> (readFD: CInt, writeFD: CInt) {
|
||||
|
||||
/// Start the same executable as a child process, redirecting its stdout and
|
||||
/// stderr.
|
||||
func spawnChild(args: _UnitTestArray<String>)
|
||||
public func spawnChild(args: _UnitTestArray<String>)
|
||||
-> (pid: pid_t, stdinFD: CInt, stdoutFD: CInt, stderrFD: CInt) {
|
||||
var fileActions = posix_spawn_file_actions_t()
|
||||
if posix_spawn_file_actions_init(&fileActions) != 0 {
|
||||
@@ -177,7 +106,7 @@ func spawnChild(args: _UnitTestArray<String>)
|
||||
return (pid, childStdin.writeFD, childStdout.readFD, childStderr.readFD)
|
||||
}
|
||||
|
||||
func readAll(fd: CInt) -> String {
|
||||
internal func _readAll(fd: CInt) -> String {
|
||||
var buffer = _UnitTestArray<UInt8>(count: 1024, repeatedValue: 0)
|
||||
var usedBytes = 0
|
||||
while true {
|
||||
@@ -199,7 +128,8 @@ func readAll(fd: CInt) -> String {
|
||||
UTF8.self, input: buffer[0..<usedBytes]).0
|
||||
}
|
||||
|
||||
func signalToString(signal: Int) -> String {
|
||||
|
||||
internal func _signalToString(signal: Int) -> String {
|
||||
switch CInt(signal) {
|
||||
case SIGILL: return "SIGILL"
|
||||
case SIGTRAP: return "SIGTRAP"
|
||||
@@ -212,30 +142,21 @@ func signalToString(signal: Int) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
enum ProcessTerminationStatus : Printable {
|
||||
public enum ProcessTerminationStatus : Printable {
|
||||
case Exit(Int)
|
||||
case Signal(Int)
|
||||
|
||||
var description: String {
|
||||
public var description: String {
|
||||
switch self {
|
||||
case .Exit(var status):
|
||||
return "Exit(\(status))"
|
||||
case .Signal(var signal):
|
||||
return "Signal(\(signalToString(signal)))"
|
||||
}
|
||||
}
|
||||
|
||||
var isSwiftTrap: Bool {
|
||||
switch self {
|
||||
case .Exit(var status):
|
||||
return false
|
||||
case .Signal(var signal):
|
||||
return CInt(signal) == SIGILL || CInt(signal) == SIGTRAP
|
||||
return "Signal(\(_signalToString(signal)))"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func posixWaitpid(pid: pid_t) -> ProcessTerminationStatus {
|
||||
public func posixWaitpid(pid: pid_t) -> ProcessTerminationStatus {
|
||||
var status: CInt = 0
|
||||
if waitpid(pid, &status, 0) < 0 {
|
||||
preconditionFailure("waitpid() failed")
|
||||
@@ -249,15 +170,15 @@ func posixWaitpid(pid: pid_t) -> ProcessTerminationStatus {
|
||||
preconditionFailure("did not understand what happened to child process")
|
||||
}
|
||||
|
||||
func runChild(args: _UnitTestArray<String>)
|
||||
public func runChild(args: _UnitTestArray<String>)
|
||||
-> (stdout: String, stderr: String, status: ProcessTerminationStatus) {
|
||||
let (pid, _, stdoutFD, stderrFD) = spawnChild(args)
|
||||
|
||||
// FIXME: reading stdout and stderr sequentially can block. Should use
|
||||
// select(). This is not so simple to implement because of:
|
||||
// <rdar://problem/17828358> Darwin module is missing fd_set-related macros
|
||||
let stdout = readAll(stdoutFD)
|
||||
let stderr = readAll(stderrFD)
|
||||
let stdout = _readAll(stdoutFD)
|
||||
let stderr = _readAll(stderrFD)
|
||||
|
||||
if close(stdoutFD) != 0 {
|
||||
preconditionFailure("close() failed")
|
||||
@@ -269,34 +190,6 @@ func runChild(args: _UnitTestArray<String>)
|
||||
return (stdout, stderr, status)
|
||||
}
|
||||
|
||||
//
|
||||
// Functions missing in `Darwin` module.
|
||||
//
|
||||
func _WSTATUS(status: CInt) -> CInt {
|
||||
return status & 0x7f
|
||||
}
|
||||
|
||||
var _WSTOPPED: CInt {
|
||||
return 0x7f
|
||||
}
|
||||
|
||||
func WIFEXITED(status: CInt) -> Bool {
|
||||
return _WSTATUS(status) == 0
|
||||
}
|
||||
|
||||
func WIFSIGNALED(status: CInt) -> Bool {
|
||||
return _WSTATUS(status) != _WSTOPPED && _WSTATUS(status) != 0
|
||||
}
|
||||
|
||||
func WEXITSTATUS(status: CInt) -> CInt {
|
||||
return (status >> 8) & 0xff
|
||||
}
|
||||
|
||||
func WTERMSIG(status: CInt) -> CInt {
|
||||
return _WSTATUS(status)
|
||||
}
|
||||
|
||||
@asmname("_NSGetEnviron")
|
||||
func _NSGetEnviron() -> UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<CChar>>>
|
||||
|
||||
|
||||
126
stdlib/darwin_extras/SwiftUnstableDarwinExtras.swift
Normal file
126
stdlib/darwin_extras/SwiftUnstableDarwinExtras.swift
Normal file
@@ -0,0 +1,126 @@
|
||||
//===--- DarwinExtras.swift -----------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2015 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import SwiftUnstable
|
||||
import Darwin
|
||||
|
||||
public func _stdlib_mkstemps(inout template: String, suffixlen: CInt) -> CInt {
|
||||
var utf8 = template.nulTerminatedUTF8
|
||||
let (fd, fileName) = utf8.withUnsafeMutableBufferPointer {
|
||||
(utf8) -> (CInt, String) in
|
||||
let fd = mkstemps(UnsafeMutablePointer(utf8.baseAddress), suffixlen)
|
||||
let fileName = String.fromCString(UnsafePointer(utf8.baseAddress))!
|
||||
return (fd, fileName)
|
||||
}
|
||||
template = fileName
|
||||
return fd
|
||||
}
|
||||
|
||||
public var _stdlib_FD_SETSIZE: CInt {
|
||||
return 1024
|
||||
}
|
||||
|
||||
public struct _stdlib_fd_set {
|
||||
var _data: _UnitTestArray<UInt32>
|
||||
static var _wordBits: Int {
|
||||
return sizeof(UInt32) * 8
|
||||
}
|
||||
|
||||
public init() {
|
||||
_data = _UnitTestArray<UInt32>(
|
||||
count: Int(_stdlib_FD_SETSIZE) / _stdlib_fd_set._wordBits,
|
||||
repeatedValue: 0)
|
||||
}
|
||||
|
||||
public func isset(fd: CInt) -> Bool {
|
||||
let fdInt = Int(fd)
|
||||
return (
|
||||
_data[fdInt / _stdlib_fd_set._wordBits] &
|
||||
UInt32(1 << (fdInt % _stdlib_fd_set._wordBits))
|
||||
) != 0
|
||||
}
|
||||
|
||||
public mutating func set(fd: CInt) {
|
||||
let fdInt = Int(fd)
|
||||
_data[fdInt / _stdlib_fd_set._wordBits] |=
|
||||
UInt32(1 << (fdInt % _stdlib_fd_set._wordBits))
|
||||
}
|
||||
|
||||
public mutating func clear(fd: CInt) {
|
||||
let fdInt = Int(fd)
|
||||
_data[fdInt / _stdlib_fd_set._wordBits] &=
|
||||
~UInt32(1 << (fdInt % _stdlib_fd_set._wordBits))
|
||||
}
|
||||
|
||||
public mutating func zero() {
|
||||
let count = _data.count
|
||||
return _data.withUnsafeMutableBufferPointer {
|
||||
(_data) in
|
||||
for i in 0..<count {
|
||||
_data[i] = 0
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func _stdlib_select(
|
||||
inout readfds: _stdlib_fd_set, inout writefds: _stdlib_fd_set,
|
||||
inout errorfds: _stdlib_fd_set, timeout: UnsafeMutablePointer<timeval>
|
||||
) -> CInt {
|
||||
return readfds._data.withUnsafeMutableBufferPointer {
|
||||
(readfds) in
|
||||
writefds._data.withUnsafeMutableBufferPointer {
|
||||
(writefds) in
|
||||
errorfds._data.withUnsafeMutableBufferPointer {
|
||||
(errorfds) in
|
||||
let readAddr = readfds.baseAddress
|
||||
let writeAddr = writefds.baseAddress
|
||||
let errorAddr = errorfds.baseAddress
|
||||
return select(
|
||||
_stdlib_FD_SETSIZE,
|
||||
UnsafeMutablePointer(readAddr),
|
||||
UnsafeMutablePointer(writeAddr),
|
||||
UnsafeMutablePointer(errorAddr),
|
||||
timeout)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Functions missing in `Darwin` module.
|
||||
//
|
||||
public func _WSTATUS(status: CInt) -> CInt {
|
||||
return status & 0x7f
|
||||
}
|
||||
|
||||
public var _WSTOPPED: CInt {
|
||||
return 0x7f
|
||||
}
|
||||
|
||||
public func WIFEXITED(status: CInt) -> Bool {
|
||||
return _WSTATUS(status) == 0
|
||||
}
|
||||
|
||||
public func WIFSIGNALED(status: CInt) -> Bool {
|
||||
return _WSTATUS(status) != _WSTOPPED && _WSTATUS(status) != 0
|
||||
}
|
||||
|
||||
public func WEXITSTATUS(status: CInt) -> CInt {
|
||||
return (status >> 8) & 0xff
|
||||
}
|
||||
|
||||
public func WTERMSIG(status: CInt) -> CInt {
|
||||
return _WSTATUS(status)
|
||||
}
|
||||
|
||||
10
stdlib/pthread_extras/CMakeLists.txt
Normal file
10
stdlib/pthread_extras/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
add_swift_library(swiftSwiftUnstablePthreadExtras SHARED IS_STDLIB
|
||||
# This file should be listed the first. Module name is inferred from the
|
||||
# filename.
|
||||
SwiftUnstablePthreadExtras.swift
|
||||
PthreadBarriers.swift
|
||||
SwiftBlockToCFunctionThunks.cpp
|
||||
|
||||
SWIFT_COMPILE_FLAGS -Xfrontend -sil-serialize-all
|
||||
INSTALL_IN_COMPONENT stdlib-experimental)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//===--- PthreadWrappers.swift --------------------------------------------===//
|
||||
//===--- SwiftUnstablePthreadExtras.swift ---------------------------------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
@@ -9,13 +9,14 @@
|
||||
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains wrappers for pthread APIs that are less painful to use
|
||||
// than the C APIs.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import Darwin
|
||||
|
||||
//
|
||||
// This file contains wrappers for functions in Darwin module.
|
||||
//
|
||||
|
||||
@asmname("swift_stdlib_getExecuteBlockFunctionPtr_VoidPtr_VoidPtr")
|
||||
func _stdlib_getExecuteBlockFunctionPtr_VoidPtr_VoidPtr()
|
||||
-> CFunctionPointer<((UnsafeMutablePointer<()>) -> UnsafeMutablePointer<()>)>
|
||||
@@ -49,7 +50,7 @@ func _stdlib_executeSwiftClosure<Param, Result>(
|
||||
return result
|
||||
}
|
||||
|
||||
/// Block-based wrapper `pthread_create`.
|
||||
/// Block-based wrapper for `pthread_create`.
|
||||
public func _stdlib_pthread_create_block<Argument, Result>(
|
||||
attr: UnsafePointer<pthread_attr_t>,
|
||||
start_routine: (Argument) -> Result,
|
||||
@@ -74,7 +75,7 @@ public func _stdlib_pthread_create_block<Argument, Result>(
|
||||
}
|
||||
}
|
||||
|
||||
/// Block-based wrapper `pthread_join`.
|
||||
/// Block-based wrapper for `pthread_join`.
|
||||
public func _stdlib_pthread_join<Result>(
|
||||
thread: pthread_t,
|
||||
resultType: Result.Type
|
||||
@@ -91,24 +92,6 @@ public func _stdlib_pthread_join<Result>(
|
||||
}
|
||||
}
|
||||
|
||||
func _stdlib_sysctlbyname_Int32(name: String) -> Int32 {
|
||||
return name.withCString {
|
||||
(nameUtf8) -> Int32 in
|
||||
var resultSize: size_t = 4
|
||||
var result: Int32 = 0
|
||||
sysctlbyname(nameUtf8, &result, &resultSize, nil, 0)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
func _stdlib_getHardwareConcurrency() -> Int {
|
||||
let result = Int(_stdlib_sysctlbyname_Int32("hw.physicalcpu"))
|
||||
if result < 1 {
|
||||
fatalError("_stdlib_getHardwareConcurrency(): could not query sysctl")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public class _stdlib_Barrier {
|
||||
var _pthreadBarrier: _stdlib_pthread_barrier_t
|
||||
|
||||
@@ -41,6 +41,7 @@ add_swift_library(swiftRuntime IS_STDLIB IS_STDLIB_CORE
|
||||
KnownMetadata.cpp
|
||||
Metadata.cpp
|
||||
Reflection.cpp
|
||||
ShimsChecker.cpp
|
||||
Stubs.cpp
|
||||
SwiftObject.cpp
|
||||
Enum.cpp
|
||||
|
||||
23
stdlib/runtime/ShimsChecker.cpp
Normal file
23
stdlib/runtime/ShimsChecker.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
//===--- ShimsChecker.cpp -------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2015 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file checks the correctness of certain declarations from SwiftShims.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <type_traits>
|
||||
#include <unistd.h>
|
||||
#include "../shims/DarwinShims.h"
|
||||
|
||||
static_assert(std::is_same<ssize_t, __swift_ssize_t>::value,
|
||||
"__swift_ssize_t is wrong");
|
||||
|
||||
@@ -318,3 +318,8 @@ extern "C" const char *_swift_strtold(const char * nptr, void *outResult) {
|
||||
*static_cast<long double*>(outResult) = std::strtold(nptr, &endPtr);
|
||||
return endPtr;
|
||||
}
|
||||
|
||||
extern "C" int _swift_stdlib_putc_stderr(int C) {
|
||||
return putc(C, stderr);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,20 +19,35 @@
|
||||
#ifndef SWIFT_STDLIB_SHIMS_DARWINSHIMS_H
|
||||
#define SWIFT_STDLIB_SHIMS_DARWINSHIMS_H
|
||||
|
||||
#include "SwiftStdint.h"
|
||||
#include "SwiftStddef.h"
|
||||
|
||||
// This declaration is not universally correct. We verify its correctness for
|
||||
// the current platform in the runtime code.
|
||||
typedef long int __swift_ssize_t;
|
||||
|
||||
__swift_size_t swift_malloc_size(const void *ptr);
|
||||
void free(void *);
|
||||
__swift_size_t strlen(const char *s);
|
||||
char *strcpy(char *restrict dst, const char *restrict src);
|
||||
char *strcpy(char *__restrict__ dst, const char *__restrict__ src);
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
int memcmp(const void *s1, const void *s2, __swift_size_t n);
|
||||
int putchar(int c);
|
||||
|
||||
double strtod(const char *restrict nptr, char **restrict endptr);
|
||||
float strtof(const char *restrict nptr, char **restrict endptr);
|
||||
int putchar(int c);
|
||||
__swift_ssize_t read(int fildes, void *buf, __swift_size_t nbyte);
|
||||
__swift_ssize_t write(int fildes, const void *buf, __swift_size_t nbyte);
|
||||
int close(int fildes);
|
||||
|
||||
double strtod(const char *__restrict__ nptr, char **__restrict__ endptr);
|
||||
float strtof(const char *__restrict__ nptr, char **__restrict__ endptr);
|
||||
|
||||
int isspace(int c);
|
||||
|
||||
__swift_uint32_t arc4random(void);
|
||||
__swift_uint32_t arc4random_uniform(__swift_uint32_t upper_bound);
|
||||
|
||||
int sysctlbyname(const char *name, void *oldp, __swift_size_t *oldlenp,
|
||||
void *newp, __swift_size_t newlen);
|
||||
|
||||
#endif // SWIFT_STDLIB_SHIMS_DARWINSHIMS_H
|
||||
|
||||
|
||||
@@ -77,6 +77,8 @@ void *_swift_objCMirrorSummary(const void * nsObject);
|
||||
/// Call strtold, changing arguments so we can operate on Float80
|
||||
const char *_swift_strtold(const char *nptr, void *outResult);
|
||||
|
||||
int _swift_stdlib_putc_stderr(int C);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}} // extern "C", namespace swift
|
||||
#endif
|
||||
|
||||
@@ -3,17 +3,13 @@ add_swift_library(swiftStdlibUnittest SHARED IS_STDLIB
|
||||
# filename.
|
||||
StdlibUnittest.swift.gyb
|
||||
|
||||
DarwinExtras.swift
|
||||
GetOSVersion.mm
|
||||
InterceptTraps.cpp
|
||||
OpaqueIdentityFunctions.cpp
|
||||
OpaqueIdentityFunctions.swift
|
||||
PthreadBarriers.swift
|
||||
PthreadWrappers.swift
|
||||
RaceTest.swift
|
||||
Statistics.swift
|
||||
StdlibCoreExtras.swift
|
||||
SwiftBlockToCFunctionThunks.cpp
|
||||
TestHelpers.swift
|
||||
LifetimeTracked.swift
|
||||
|
||||
@@ -23,7 +19,9 @@ add_swift_library(swiftStdlibUnittest SHARED IS_STDLIB
|
||||
#
|
||||
# SWIFT_COMPILE_FLAGS -Xfrontend -sil-serialize-all
|
||||
|
||||
SWIFT_MODULE_DEPENDS Darwin Foundation
|
||||
SWIFT_MODULE_DEPENDS
|
||||
SwiftUnstable SwiftUnstablePthreadExtras SwiftUnstableDarwinExtras
|
||||
Darwin Foundation
|
||||
FRAMEWORK_DEPENDS Foundation
|
||||
INSTALL_IN_COMPONENT stdlib-experimental)
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import SwiftUnstable
|
||||
import SwiftUnstablePthreadExtras
|
||||
import Darwin
|
||||
|
||||
#if _runtime(_ObjC)
|
||||
@@ -401,8 +403,8 @@ func _masterThreadOneTrial<RT : RaceTestWithPerTrialDataType>(
|
||||
let workerState = _RaceTestWorkerState<RT>()
|
||||
|
||||
// Shuffle the data so that threads process it in different order.
|
||||
let shuffle = _stdlib_randomShuffle(identityShuffle)
|
||||
workerState.raceData = _stdlib_scatter(sharedState.raceData, shuffle)
|
||||
let shuffle = randomShuffle(identityShuffle)
|
||||
workerState.raceData = scatter(sharedState.raceData, shuffle)
|
||||
workerState.raceDataShuffle = shuffle
|
||||
|
||||
workerState.observations = []
|
||||
@@ -420,9 +422,9 @@ func _masterThreadOneTrial<RT : RaceTestWithPerTrialDataType>(
|
||||
for i in 0..<racingThreadCount {
|
||||
let shuffle = sharedState.workerStates[i].raceDataShuffle
|
||||
sharedState.workerStates[i].raceData =
|
||||
_stdlib_gather(sharedState.workerStates[i].raceData, shuffle)
|
||||
gather(sharedState.workerStates[i].raceData, shuffle)
|
||||
sharedState.workerStates[i].observations =
|
||||
_stdlib_gather(sharedState.workerStates[i].observations, shuffle)
|
||||
gather(sharedState.workerStates[i].observations, shuffle)
|
||||
}
|
||||
if true {
|
||||
// FIXME: why doesn't the bracket syntax work?
|
||||
|
||||
@@ -1,35 +1,14 @@
|
||||
|
||||
import Darwin
|
||||
|
||||
public func rand32() -> UInt32 {
|
||||
return arc4random()
|
||||
}
|
||||
|
||||
public func rand32(#exclusiveUpperBound: UInt32) -> UInt32 {
|
||||
return arc4random_uniform(exclusiveUpperBound)
|
||||
}
|
||||
|
||||
public func rand64() -> UInt64 {
|
||||
return (UInt64(arc4random()) << 32) | UInt64(arc4random())
|
||||
}
|
||||
|
||||
public func randInt() -> Int {
|
||||
#if arch(i386) || arch(arm)
|
||||
return Int(Int32(bitPattern: rand32()))
|
||||
#elseif arch(x86_64) || arch(arm64)
|
||||
return Int(Int64(bitPattern: rand64()))
|
||||
#else
|
||||
fatalError("unimplemented")
|
||||
#endif
|
||||
}
|
||||
|
||||
public func randArray64(count: Int) -> _UnitTestArray<UInt64> {
|
||||
var result = _UnitTestArray<UInt64>(count: count, repeatedValue: 0)
|
||||
for i in indices(result) {
|
||||
result[i] = rand64()
|
||||
}
|
||||
return result
|
||||
}
|
||||
//===--- Statistics.swift -------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2015 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// For a given p-value, returns the critical chi-square value for
|
||||
/// a distribution with 1 degree of freedom.
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import SwiftUnstable
|
||||
import Darwin
|
||||
import SwiftUnstableDarwinExtras
|
||||
import Foundation
|
||||
|
||||
//
|
||||
@@ -18,62 +20,6 @@ import Foundation
|
||||
// useful in tests, and stdlib does not have such facilities yet.
|
||||
//
|
||||
|
||||
/// Convert the given numeric value to a hexidecimal string.
|
||||
public func asHex<T : IntegerType>(x: T) -> String {
|
||||
return "0x" + String(x.toIntMax(), radix: 16)
|
||||
}
|
||||
|
||||
/// Convert the given sequence of numeric values to a string representing
|
||||
/// their hexidecimal values.
|
||||
public func asHex<
|
||||
S: SequenceType
|
||||
where
|
||||
S.Generator.Element : IntegerType
|
||||
>(x: S) -> String {
|
||||
return "[ " + ", ".join(lazy(x).map { asHex($0) }) + " ]"
|
||||
}
|
||||
|
||||
/// Compute the prefix sum of `seq`.
|
||||
func scan<
|
||||
S : SequenceType, U
|
||||
>(seq: S, initial: U, combine: (U, S.Generator.Element) -> U) -> _UnitTestArray<U> {
|
||||
var result = _UnitTestArray<U>()
|
||||
result.reserveCapacity(underestimateCount(seq))
|
||||
var runningResult = initial
|
||||
for element in seq {
|
||||
runningResult = combine(runningResult, element)
|
||||
result.append(runningResult)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public func _stdlib_randomShuffle<T>(a: _UnitTestArray<T>) -> _UnitTestArray<T> {
|
||||
var result = a
|
||||
for var i = a.count - 1; i != 0; --i {
|
||||
// FIXME: 32 bits are not enough in general case!
|
||||
let j = Int(rand32(exclusiveUpperBound: UInt32(i + 1)))
|
||||
swap(&result[i], &result[j])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public func _stdlib_gather<T>(a: _UnitTestArray<T>, idx: _UnitTestArray<Int>) -> _UnitTestArray<T> {
|
||||
var result = _UnitTestArray<T>()
|
||||
result.reserveCapacity(a.count)
|
||||
for i in 0..<a.count {
|
||||
result.append(a[idx[i]])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public func _stdlib_scatter<T>(a: _UnitTestArray<T>, idx: _UnitTestArray<Int>) -> _UnitTestArray<T> {
|
||||
var result = a
|
||||
for i in 0..<a.count {
|
||||
result[idx[i]] = a[i]
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func findSubstring(string: String, substring: String) -> String.Index? {
|
||||
if substring.isEmpty {
|
||||
return string.startIndex
|
||||
@@ -81,90 +27,6 @@ func findSubstring(string: String, substring: String) -> String.Index? {
|
||||
return string.rangeOfString(substring)?.startIndex
|
||||
}
|
||||
|
||||
func withArrayOfCStrings<R>(
|
||||
args: _UnitTestArray<String>, body: (Array<UnsafeMutablePointer<CChar>>) -> R
|
||||
) -> R {
|
||||
|
||||
let argsLengths = _UnitTestArray(map(args) { count($0.utf8) + 1 })
|
||||
let argsOffsets = [ 0 ] + scan(argsLengths, 0, +)
|
||||
let argsBufferSize = argsOffsets.last!
|
||||
|
||||
var argsBuffer = _UnitTestArray<UInt8>()
|
||||
argsBuffer.reserveCapacity(argsBufferSize)
|
||||
for arg in args {
|
||||
argsBuffer.extend(arg.utf8)
|
||||
argsBuffer.append(0)
|
||||
}
|
||||
|
||||
return argsBuffer.withUnsafeBufferPointer {
|
||||
(argsBuffer) in
|
||||
let ptr = UnsafeMutablePointer<CChar>(argsBuffer.baseAddress)
|
||||
var cStrings = map(argsOffsets) { ptr + $0 }
|
||||
cStrings[cStrings.count - 1] = nil
|
||||
return body(cStrings)
|
||||
}
|
||||
}
|
||||
|
||||
public struct _Stderr : OutputStreamType {
|
||||
public init() {}
|
||||
|
||||
public mutating func write(string: String) {
|
||||
for c in string.utf8 {
|
||||
putc(Int32(c), stderr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct _FDOutputStream : OutputStreamType {
|
||||
let fd: CInt
|
||||
var isClosed: Bool = false
|
||||
|
||||
init(fd: CInt) {
|
||||
self.fd = fd
|
||||
}
|
||||
|
||||
mutating func write(string: String) {
|
||||
let utf8 = string.nulTerminatedUTF8
|
||||
utf8.withUnsafeBufferPointer {
|
||||
(utf8) -> () in
|
||||
var writtenBytes: size_t = 0
|
||||
let bufferSize = size_t(utf8.count - 1)
|
||||
while writtenBytes != bufferSize {
|
||||
let result = Darwin.write(
|
||||
self.fd, UnsafePointer(utf8.baseAddress + Int(writtenBytes)),
|
||||
bufferSize - writtenBytes)
|
||||
if result < 0 {
|
||||
fatalError("write() returned an error")
|
||||
}
|
||||
writtenBytes += size_t(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mutating func close() {
|
||||
if isClosed {
|
||||
return
|
||||
}
|
||||
let result = Darwin.close(fd)
|
||||
if result < 0 {
|
||||
fatalError("close() returned an error")
|
||||
}
|
||||
isClosed = true
|
||||
}
|
||||
}
|
||||
|
||||
func _stdlib_mkstemps(inout template: String, suffixlen: CInt) -> CInt {
|
||||
var utf8 = template.nulTerminatedUTF8
|
||||
let (fd, fileName) = utf8.withUnsafeMutableBufferPointer {
|
||||
(utf8) -> (CInt, String) in
|
||||
let fd = mkstemps(UnsafeMutablePointer(utf8.baseAddress), suffixlen)
|
||||
let fileName = String.fromCString(UnsafePointer(utf8.baseAddress))!
|
||||
return (fd, fileName)
|
||||
}
|
||||
template = fileName
|
||||
return fd
|
||||
}
|
||||
|
||||
public func createTemporaryFile(
|
||||
fileNamePrefix: String, fileNameSuffix: String, contents: String
|
||||
) -> String {
|
||||
@@ -183,65 +45,3 @@ public func createTemporaryFile(
|
||||
return fileName
|
||||
}
|
||||
|
||||
/// An atomic counter for contended applications.
|
||||
///
|
||||
/// This is a struct to prevent extra retains/releases. You are required to
|
||||
/// call `deinit()` to release the owned memory.
|
||||
public struct _stdlib_ShardedAtomicCounter {
|
||||
// Using an array causes retains/releases, which create contention on the
|
||||
// reference count.
|
||||
// FIXME: guard every element against false sharing.
|
||||
var _shardsPtr: UnsafeMutablePointer<Int>
|
||||
var _shardsCount: Int
|
||||
|
||||
public init() {
|
||||
let hardwareConcurrency = _stdlib_getHardwareConcurrency()
|
||||
let count = max(8, hardwareConcurrency * hardwareConcurrency)
|
||||
let shards = UnsafeMutablePointer<Int>.alloc(count)
|
||||
for var i = 0; i != count; i++ {
|
||||
(shards + i).initialize(0)
|
||||
}
|
||||
self._shardsPtr = shards
|
||||
self._shardsCount = count
|
||||
}
|
||||
|
||||
public func `deinit`() {
|
||||
self._shardsPtr.destroy(self._shardsCount)
|
||||
self._shardsPtr.dealloc(self._shardsCount)
|
||||
}
|
||||
|
||||
public func add(operand: Int, randomInt: Int) {
|
||||
let shardIndex = Int(UInt(bitPattern: randomInt) % UInt(self._shardsCount))
|
||||
_swift_stdlib_atomicFetchAddInt(
|
||||
object: self._shardsPtr + shardIndex, operand: operand)
|
||||
}
|
||||
|
||||
// FIXME: non-atomic as a whole!
|
||||
public func getSum() -> Int {
|
||||
var result = 0
|
||||
let shards = self._shardsPtr
|
||||
let count = self._shardsCount
|
||||
for var i = 0; i != count; i++ {
|
||||
result += _swift_stdlib_atomicLoadInt(object: shards + i)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public struct PRNG {
|
||||
var _state: Int
|
||||
|
||||
public init() {
|
||||
_state = Int(Int32(bitPattern: StdlibUnittest.rand32()))
|
||||
}
|
||||
|
||||
public mutating func randomInt() -> Int {
|
||||
var result = 0
|
||||
for var i = 0; i != Int._sizeInBits; ++i {
|
||||
result = (result << 1) | (_state & 1)
|
||||
_state = (_state >> 1) ^ (-(_state & 1) & Int(bitPattern: 0xD0000001))
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,10 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import SwiftUnstable
|
||||
import SwiftUnstablePthreadExtras
|
||||
import Darwin
|
||||
import SwiftUnstableDarwinExtras
|
||||
import ObjectiveC
|
||||
|
||||
public struct SourceLoc {
|
||||
@@ -393,6 +396,17 @@ public func _setTestSuiteFailedCallback(callback: () -> ()) {
|
||||
_testSuiteFailedCallback = callback
|
||||
}
|
||||
|
||||
extension ProcessTerminationStatus {
|
||||
var isSwiftTrap: Bool {
|
||||
switch self {
|
||||
case .Exit(var status):
|
||||
return false
|
||||
case .Signal(var signal):
|
||||
return CInt(signal) == SIGILL || CInt(signal) == SIGTRAP
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func _stdlib_getline() -> String? {
|
||||
var result = _UnitTestArray<UInt8>()
|
||||
while true {
|
||||
@@ -410,75 +424,6 @@ func _stdlib_getline() -> String? {
|
||||
}
|
||||
}
|
||||
|
||||
struct _FDInputStream {
|
||||
let fd: CInt
|
||||
var isClosed: Bool = false
|
||||
var isEOF: Bool = false
|
||||
var _buffer = _UnitTestArray<UInt8>(count: 256, repeatedValue: 0)
|
||||
var _bufferUsed: Int = 0
|
||||
|
||||
init(fd: CInt) {
|
||||
self.fd = fd
|
||||
}
|
||||
|
||||
mutating func getline() -> String? {
|
||||
if let newlineIndex =
|
||||
find(_buffer[0..<_bufferUsed], UInt8(UnicodeScalar("\n").value)) {
|
||||
var result = String._fromWellFormedCodeUnitSequence(
|
||||
UTF8.self, input: _buffer[0..<newlineIndex])
|
||||
_buffer.removeRange(0...newlineIndex)
|
||||
_bufferUsed -= newlineIndex + 1
|
||||
return result
|
||||
}
|
||||
if isEOF && _bufferUsed > 0 {
|
||||
var result = String._fromWellFormedCodeUnitSequence(
|
||||
UTF8.self, input: _buffer[0..<_bufferUsed])
|
||||
_buffer.removeAll()
|
||||
_bufferUsed = 0
|
||||
return result
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
mutating func read() {
|
||||
let minFree = 128
|
||||
var bufferFree = _buffer.count - _bufferUsed
|
||||
if bufferFree < minFree {
|
||||
_buffer.reserveCapacity(minFree - bufferFree)
|
||||
while bufferFree < minFree {
|
||||
_buffer.append(0)
|
||||
++bufferFree
|
||||
}
|
||||
}
|
||||
let readResult: ssize_t = _buffer.withUnsafeMutableBufferPointer {
|
||||
(_buffer) in
|
||||
let fd = self.fd
|
||||
let addr = _buffer.baseAddress + self._bufferUsed
|
||||
let size = size_t(bufferFree)
|
||||
return Darwin.read(fd, addr, size)
|
||||
}
|
||||
if readResult == 0 {
|
||||
isEOF = true
|
||||
return
|
||||
}
|
||||
if readResult < 0 {
|
||||
fatalError("read() returned error")
|
||||
}
|
||||
_bufferUsed += readResult
|
||||
}
|
||||
|
||||
mutating func close() {
|
||||
if isClosed {
|
||||
return
|
||||
}
|
||||
let result = Darwin.close(fd)
|
||||
if result < 0 {
|
||||
fatalError("close() returned an error")
|
||||
}
|
||||
isClosed = true
|
||||
}
|
||||
}
|
||||
|
||||
func _printDebuggingAdvice(fullTestName: String) {
|
||||
println("To debug, run:")
|
||||
println("$ \(Process.arguments[0]) " +
|
||||
|
||||
11
stdlib/unstable/CMakeLists.txt
Normal file
11
stdlib/unstable/CMakeLists.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
add_swift_library(swiftSwiftUnstable SHARED IS_STDLIB
|
||||
# This file should be listed the first. Module name is inferred from the
|
||||
# filename.
|
||||
SwiftUnstable.swift
|
||||
IO.swift
|
||||
PRNG.swift
|
||||
ShardedAtomicCounter.swift
|
||||
|
||||
SWIFT_COMPILE_FLAGS -Xfrontend -sil-serialize-all
|
||||
INSTALL_IN_COMPONENT stdlib-experimental)
|
||||
|
||||
131
stdlib/unstable/IO.swift
Normal file
131
stdlib/unstable/IO.swift
Normal file
@@ -0,0 +1,131 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2015 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import SwiftShims
|
||||
|
||||
public struct _FDInputStream {
|
||||
public let fd: CInt
|
||||
public var isClosed: Bool = false
|
||||
public var isEOF: Bool = false
|
||||
internal var _buffer = _UnitTestArray<UInt8>(count: 256, repeatedValue: 0)
|
||||
internal var _bufferUsed: Int = 0
|
||||
|
||||
public init(fd: CInt) {
|
||||
self.fd = fd
|
||||
}
|
||||
|
||||
public mutating func getline() -> String? {
|
||||
if let newlineIndex =
|
||||
find(_buffer[0..<_bufferUsed], UInt8(UnicodeScalar("\n").value)) {
|
||||
var result = String._fromWellFormedCodeUnitSequence(
|
||||
UTF8.self, input: _buffer[0..<newlineIndex])
|
||||
_buffer.removeRange(0...newlineIndex)
|
||||
_bufferUsed -= newlineIndex + 1
|
||||
return result
|
||||
}
|
||||
if isEOF && _bufferUsed > 0 {
|
||||
var result = String._fromWellFormedCodeUnitSequence(
|
||||
UTF8.self, input: _buffer[0..<_bufferUsed])
|
||||
_buffer.removeAll()
|
||||
_bufferUsed = 0
|
||||
return result
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
public mutating func read() {
|
||||
let minFree = 128
|
||||
var bufferFree = _buffer.count - _bufferUsed
|
||||
if bufferFree < minFree {
|
||||
_buffer.reserveCapacity(minFree - bufferFree)
|
||||
while bufferFree < minFree {
|
||||
_buffer.append(0)
|
||||
++bufferFree
|
||||
}
|
||||
}
|
||||
let readResult: __swift_ssize_t = _buffer.withUnsafeMutableBufferPointer {
|
||||
(_buffer) in
|
||||
let fd = self.fd
|
||||
let addr = _buffer.baseAddress + self._bufferUsed
|
||||
let size = bufferFree
|
||||
return SwiftShims.read(fd, addr, size)
|
||||
}
|
||||
if readResult == 0 {
|
||||
isEOF = true
|
||||
return
|
||||
}
|
||||
if readResult < 0 {
|
||||
fatalError("read() returned error")
|
||||
}
|
||||
_bufferUsed += readResult
|
||||
}
|
||||
|
||||
public mutating func close() {
|
||||
if isClosed {
|
||||
return
|
||||
}
|
||||
let result = SwiftShims.close(fd)
|
||||
if result < 0 {
|
||||
fatalError("close() returned an error")
|
||||
}
|
||||
isClosed = true
|
||||
}
|
||||
}
|
||||
|
||||
public struct _Stderr : OutputStreamType {
|
||||
public init() {}
|
||||
|
||||
public mutating func write(string: String) {
|
||||
for c in string.utf8 {
|
||||
_swift_stdlib_putc_stderr(CInt(c))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct _FDOutputStream : OutputStreamType {
|
||||
public let fd: CInt
|
||||
public var isClosed: Bool = false
|
||||
|
||||
public init(fd: CInt) {
|
||||
self.fd = fd
|
||||
}
|
||||
|
||||
public mutating func write(string: String) {
|
||||
let utf8 = string.nulTerminatedUTF8
|
||||
utf8.withUnsafeBufferPointer {
|
||||
(utf8) -> () in
|
||||
var writtenBytes = 0
|
||||
let bufferSize = utf8.count - 1
|
||||
while writtenBytes != bufferSize {
|
||||
let result = SwiftShims.write(
|
||||
self.fd, UnsafePointer(utf8.baseAddress + Int(writtenBytes)),
|
||||
bufferSize - writtenBytes)
|
||||
if result < 0 {
|
||||
fatalError("write() returned an error")
|
||||
}
|
||||
writtenBytes += result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public mutating func close() {
|
||||
if isClosed {
|
||||
return
|
||||
}
|
||||
let result = SwiftShims.close(fd)
|
||||
if result < 0 {
|
||||
fatalError("close() returned an error")
|
||||
}
|
||||
isClosed = true
|
||||
}
|
||||
}
|
||||
|
||||
44
stdlib/unstable/PRNG.swift
Normal file
44
stdlib/unstable/PRNG.swift
Normal file
@@ -0,0 +1,44 @@
|
||||
//===--- PRNG.swift -------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2015 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import SwiftShims
|
||||
|
||||
public func rand32() -> UInt32 {
|
||||
return arc4random()
|
||||
}
|
||||
|
||||
public func rand32(#exclusiveUpperBound: UInt32) -> UInt32 {
|
||||
return arc4random_uniform(exclusiveUpperBound)
|
||||
}
|
||||
|
||||
public func rand64() -> UInt64 {
|
||||
return (UInt64(arc4random()) << 32) | UInt64(arc4random())
|
||||
}
|
||||
|
||||
public func randInt() -> Int {
|
||||
#if arch(i386) || arch(arm)
|
||||
return Int(Int32(bitPattern: rand32()))
|
||||
#elseif arch(x86_64) || arch(arm64)
|
||||
return Int(Int64(bitPattern: rand64()))
|
||||
#else
|
||||
fatalError("unimplemented")
|
||||
#endif
|
||||
}
|
||||
|
||||
public func randArray64(count: Int) -> _UnitTestArray<UInt64> {
|
||||
var result = _UnitTestArray<UInt64>(count: count, repeatedValue: 0)
|
||||
for i in indices(result) {
|
||||
result[i] = rand64()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
94
stdlib/unstable/ShardedAtomicCounter.swift
Normal file
94
stdlib/unstable/ShardedAtomicCounter.swift
Normal file
@@ -0,0 +1,94 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2015 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import SwiftShims
|
||||
|
||||
func _stdlib_sysctlbyname_Int32(name: String) -> Int32 {
|
||||
return name.withCString {
|
||||
(nameUtf8) -> Int32 in
|
||||
var resultSize = 4
|
||||
var result: Int32 = 0
|
||||
sysctlbyname(nameUtf8, &result, &resultSize, nil, 0)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
public func _stdlib_getHardwareConcurrency() -> Int {
|
||||
let result = Int(_stdlib_sysctlbyname_Int32("hw.physicalcpu"))
|
||||
if result < 1 {
|
||||
fatalError("_stdlib_getHardwareConcurrency(): could not query sysctl")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/// An atomic counter for contended applications.
|
||||
///
|
||||
/// This is a struct to prevent extra retains/releases. You are required to
|
||||
/// call `deinit()` to release the owned memory.
|
||||
public struct _stdlib_ShardedAtomicCounter {
|
||||
// Using an array causes retains/releases, which create contention on the
|
||||
// reference count.
|
||||
// FIXME: guard every element against false sharing.
|
||||
var _shardsPtr: UnsafeMutablePointer<Int>
|
||||
var _shardsCount: Int
|
||||
|
||||
public init() {
|
||||
let hardwareConcurrency = _stdlib_getHardwareConcurrency()
|
||||
let count = max(8, hardwareConcurrency * hardwareConcurrency)
|
||||
let shards = UnsafeMutablePointer<Int>.alloc(count)
|
||||
for var i = 0; i != count; i++ {
|
||||
(shards + i).initialize(0)
|
||||
}
|
||||
self._shardsPtr = shards
|
||||
self._shardsCount = count
|
||||
}
|
||||
|
||||
public func `deinit`() {
|
||||
self._shardsPtr.destroy(self._shardsCount)
|
||||
self._shardsPtr.dealloc(self._shardsCount)
|
||||
}
|
||||
|
||||
public func add(operand: Int, randomInt: Int) {
|
||||
let shardIndex = Int(UInt(bitPattern: randomInt) % UInt(self._shardsCount))
|
||||
_swift_stdlib_atomicFetchAddInt(
|
||||
object: self._shardsPtr + shardIndex, operand: operand)
|
||||
}
|
||||
|
||||
// FIXME: non-atomic as a whole!
|
||||
public func getSum() -> Int {
|
||||
var result = 0
|
||||
let shards = self._shardsPtr
|
||||
let count = self._shardsCount
|
||||
for var i = 0; i != count; i++ {
|
||||
result += _swift_stdlib_atomicLoadInt(object: shards + i)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public struct PRNG {
|
||||
var _state: Int
|
||||
|
||||
public init() {
|
||||
_state = Int(Int32(bitPattern: rand32()))
|
||||
}
|
||||
|
||||
public mutating func randomInt() -> Int {
|
||||
var result = 0
|
||||
for var i = 0; i != Int._sizeInBits; ++i {
|
||||
result = (result << 1) | (_state & 1)
|
||||
_state = (_state >> 1) ^ (-(_state & 1) & Int(bitPattern: 0xD0000001))
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
94
stdlib/unstable/SwiftUnstable.swift
Normal file
94
stdlib/unstable/SwiftUnstable.swift
Normal file
@@ -0,0 +1,94 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2015 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import SwiftShims
|
||||
|
||||
/// Convert the given numeric value to a hexidecimal string.
|
||||
public func asHex<T : IntegerType>(x: T) -> String {
|
||||
return "0x" + String(x.toIntMax(), radix: 16)
|
||||
}
|
||||
|
||||
/// Convert the given sequence of numeric values to a string representing
|
||||
/// their hexidecimal values.
|
||||
public func asHex<
|
||||
S: SequenceType
|
||||
where
|
||||
S.Generator.Element : IntegerType
|
||||
>(x: S) -> String {
|
||||
return "[ " + ", ".join(lazy(x).map { asHex($0) }) + " ]"
|
||||
}
|
||||
|
||||
/// Compute the prefix sum of `seq`.
|
||||
public func scan<
|
||||
S : SequenceType, U
|
||||
>(seq: S, initial: U, combine: (U, S.Generator.Element) -> U) -> _UnitTestArray<U> {
|
||||
var result = _UnitTestArray<U>()
|
||||
result.reserveCapacity(underestimateCount(seq))
|
||||
var runningResult = initial
|
||||
for element in seq {
|
||||
runningResult = combine(runningResult, element)
|
||||
result.append(runningResult)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public func randomShuffle<T>(a: _UnitTestArray<T>) -> _UnitTestArray<T> {
|
||||
var result = a
|
||||
for var i = a.count - 1; i != 0; --i {
|
||||
// FIXME: 32 bits are not enough in general case!
|
||||
let j = Int(rand32(exclusiveUpperBound: UInt32(i + 1)))
|
||||
swap(&result[i], &result[j])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public func gather<T>(a: _UnitTestArray<T>, idx: _UnitTestArray<Int>) -> _UnitTestArray<T> {
|
||||
var result = _UnitTestArray<T>()
|
||||
result.reserveCapacity(a.count)
|
||||
for i in 0..<a.count {
|
||||
result.append(a[idx[i]])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public func scatter<T>(a: _UnitTestArray<T>, idx: _UnitTestArray<Int>) -> _UnitTestArray<T> {
|
||||
var result = a
|
||||
for i in 0..<a.count {
|
||||
result[idx[i]] = a[i]
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public func withArrayOfCStrings<R>(
|
||||
args: _UnitTestArray<String>, body: (Array<UnsafeMutablePointer<CChar>>) -> R
|
||||
) -> R {
|
||||
|
||||
let argsLengths = _UnitTestArray(map(args) { count($0.utf8) + 1 })
|
||||
let argsOffsets = [ 0 ] + scan(argsLengths, 0, +)
|
||||
let argsBufferSize = argsOffsets.last!
|
||||
|
||||
var argsBuffer = _UnitTestArray<UInt8>()
|
||||
argsBuffer.reserveCapacity(argsBufferSize)
|
||||
for arg in args {
|
||||
argsBuffer.extend(arg.utf8)
|
||||
argsBuffer.append(0)
|
||||
}
|
||||
|
||||
return argsBuffer.withUnsafeBufferPointer {
|
||||
(argsBuffer) in
|
||||
let ptr = UnsafeMutablePointer<CChar>(argsBuffer.baseAddress)
|
||||
var cStrings = map(argsOffsets) { ptr + $0 }
|
||||
cStrings[cStrings.count - 1] = nil
|
||||
return body(cStrings)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
// XFAIL: linux
|
||||
|
||||
import Swift
|
||||
import SwiftUnstable
|
||||
import StdlibUnittest
|
||||
|
||||
final class HeapBool {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// XFAIL: linux
|
||||
|
||||
import Swift
|
||||
import SwiftUnstable
|
||||
import StdlibUnittest
|
||||
|
||||
var HashingTestSuite = TestSuite("Hashing")
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
// XFAIL: linux
|
||||
|
||||
import SwiftUnstable
|
||||
import StdlibUnittest
|
||||
|
||||
var HashingTestSuite = TestSuite("Hashing")
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
// XFAIL: linux
|
||||
|
||||
import SwiftUnstable
|
||||
import StdlibUnittest
|
||||
|
||||
_setOverrideOSVersion(.OSX(major: 10, minor: 9, bugFix: 3))
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
import Swift
|
||||
import StdlibUnittest
|
||||
import SwiftUnstablePthreadExtras
|
||||
import Dispatch
|
||||
|
||||
var StringTestSuite = TestSuite("String")
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// FIXME: rdar://problem/19648117 Needs splitting objc parts out
|
||||
// XFAIL: linux
|
||||
|
||||
import SwiftUnstable
|
||||
import StdlibUnittest
|
||||
import Foundation
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ grapheme_cluster_break_property_table = \
|
||||
|
||||
}%
|
||||
|
||||
import SwiftUnstable
|
||||
import StdlibUnittest
|
||||
import Darwin
|
||||
import Foundation
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// FIXME: rdar://problem/19648117 Needs splitting objc parts out
|
||||
// XFAIL: linux
|
||||
|
||||
import SwiftUnstable
|
||||
import StdlibUnittest
|
||||
import Foundation
|
||||
|
||||
|
||||
Reference in New Issue
Block a user