Files
swift-mirror/stdlib/unittest/PthreadWrappers.swift
Dave Abrahams 1fb0f889d7 [stdlib] Make UnsafePointer conversions explicit
Previously, it was possible to write Unsafe[Mutable]Pointer(x) and have
Swift deduce the pointee type based on context.  Since reinterpreting
memory is a fundamentally type-unsafe operation, it's better to be
explicit about conversions from Unsafe[Mutable]Pointer<T> to
Unsafe[Mutable]Pointer<U>.  This change is consistent with the move from
reinterpretCast(x) to unsafeBitCast(x, T.self).

Also, we've encoded the operations of explicitly adding or removing
mutability as properties, so that adding mutability can be separated
from wild reinterpretCast'ing, a much more severe form of unsafety.

Swift SVN r21324
2014-08-20 23:15:56 +00:00

162 lines
4.6 KiB
Swift

//===--- PthreadWrappers.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 Darwin
//
// This file contains wrappers for functions in Darwin module.
//
@asmname("swift_stdlib_getExecuteBlockFunctionPtr_VoidPtr_VoidPtr")
func _stdlib_getExecuteBlockFunctionPtr_VoidPtr_VoidPtr()
-> CFunctionPointer<((UnsafeMutablePointer<()>) -> UnsafeMutablePointer<()>)>
@asmname("swift_stdlib_getTypeMetadata")
func _stdlib_getTypeMetadata<T>(_: T.Type) -> UnsafePointer<Void>
struct ExecuteSwiftClosureContext<Argument, Result> {
let argumentTypeMetadata: UnsafePointer<Void>
let resultTypeMetadata: UnsafePointer<Void>
let closure: ((Argument) -> Result)
let arg: Argument
}
/// Execute a Swift closure with a given argument.
///
/// :param: closureAndArg closure and its argument. The function takes
/// ownership of this pointer.
@asmname("swift_stdlib_executeSwiftClosure")
func _stdlib_executeSwiftClosure<Param, Result>(
context: UnsafeMutablePointer<ExecuteSwiftClosureContext<Param, Result>>
) -> UnsafeMutablePointer<Result> {
let closure = context.memory.closure
let arg = context.memory.arg
context.destroy()
context.dealloc(1)
var result = UnsafeMutablePointer<Result>.alloc(1)
result.initialize(closure(arg))
return result
}
extension pthread_attr_t {
public init() {
#if arch(i386) || arch(arm)
self = pthread_attr_t(
__sig: 0,
__opaque: (
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0))
#elseif arch(x86_64) || arch(arm64)
self = pthread_attr_t(
__sig: 0,
__opaque: (
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0))
#endif
}
}
extension pthread_mutex_t {
public init() {
#if arch(i386) || arch(arm)
self = pthread_mutex_t(
__sig: 0,
__opaque: (
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
#elseif arch(x86_64) || arch(arm64)
self = pthread_mutex_t(
__sig: 0,
__opaque: (
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0))
#endif
}
}
extension pthread_cond_t {
public init() {
#if arch(i386) || arch(arm)
self = pthread_cond_t(
__sig: 0,
__opaque: (
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0))
#elseif arch(x86_64) || arch(arm64)
self = pthread_cond_t(
__sig: 0,
__opaque: (
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
#endif
}
}
/// Block-based wrapper `pthread_create`.
public func _stdlib_pthread_create_block<Argument, Result>(
attr: UnsafePointer<pthread_attr_t>,
start_routine: (Argument) -> Result,
arg: Argument
) -> (CInt, pthread_t?) {
let thunk = _stdlib_getExecuteBlockFunctionPtr_VoidPtr_VoidPtr()
var thunkArg =
UnsafeMutablePointer<ExecuteSwiftClosureContext<Argument, Result>>.alloc(1)
thunkArg.initialize(ExecuteSwiftClosureContext(
argumentTypeMetadata: _stdlib_getTypeMetadata(Argument.self),
resultTypeMetadata: _stdlib_getTypeMetadata(Result.self),
closure: start_routine,
arg: arg))
var threadID = pthread_t()
let result = pthread_create(&threadID, attr, thunk, thunkArg)
if result == 0 {
return (result, threadID)
} else {
return (result, nil)
}
}
/// Block-based wrapper `pthread_join`.
public func _stdlib_pthread_join<Result>(
thread: pthread_t,
resultType: Result.Type
) -> (CInt, Result?) {
var threadResultPtr = UnsafeMutablePointer<Void>()
let result = pthread_join(thread, &threadResultPtr)
if result == 0 {
let threadResult = threadResultPtr.asPointerTo(Result.self).memory
threadResultPtr.destroy()
threadResultPtr.dealloc(1)
return (result, threadResult)
} else {
return (result, nil)
}
}