-
Notifications
You must be signed in to change notification settings - Fork 1.2k
build: Repair the build on WASI platform (take 3) #5057
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
build: Repair the build on WASI platform (take 3) #5057
Conversation
@swift-ci test |
I merged that one, but that introduced conflicts unfortunately 😢 |
…bxml2 `find_package(LibXml2 REQUIRED)` sets `LIBXML2_INCLUDE_DIR` to the correct include directory for the libxml2 headers. Use this variable instead of hardcoding `/usr/include/libxml2`. This allows the build to work with custom libxml2 builds on WASI.
This commit disables libdispatch and threads on WASI, and enables wasi-libc emulation features.
Because networking is not a part of WASI Preview 1. We can add it back when it is available.
Treat WASI as an usual Unix-like system
We had been using the vendored BlocksRuntime on WASI, but the build configuration was removed during the recore. This change restores the vendored BlocksRuntime build configuration on WASI.
Mark them available on WASI. Otherwise, the `static inline` implementations are activated and the build fails with multiple definitions.
916e4bc
to
29c01d4
Compare
@@ -600,7 +600,7 @@ CFBundleRef CFBundleGetBundleWithIdentifier(CFStringRef bundleID) { | |||
#if TARGET_OS_WASI | |||
hint = NULL; | |||
#else | |||
hint = __builtin_frame_address(0); | |||
hint = __builtin_return_address(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was accidentally changed in #5052 We should continue using __builtin_return_address
on non-WASI platforms.
@swift-ci test |
@@ -471,7 +471,7 @@ open class XMLParser : NSObject { | |||
open var allowedExternalEntityURLs: Set<URL>? | |||
|
|||
#if os(WASI) | |||
private static var _currentParser: XMLParser? | |||
private nonisolated(unsafe) static var _currentParser: XMLParser? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems unsafe at first look, since any thread can call setCurrentParser
and effectively traffic XMLParser
between actors. Can you elaborate a bit more on why this is necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WASI preview1 ABI is always single-threaded, so memory access to the same storage should not happen simultaneously. So any data storage should be safe to access from any isolation context on WASI, but 6 lang mode requires explicit marking here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps the better question is what does actor isolation mean on WASI where everything is single threaded? This will allow this mutable state to pass between actor isolations on WASI, is that ok because we know it's single threaded? Or should this instead be some form of task-local storage to prevent it from traveling across actors?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need task local storage at all here because there is no suspension point during XMLParser.parse
call. No suspension point means no Task switching, thus it's guaranteed that XMLParser.setCurrentParser(self)
is not called twice before resetting the storage by XMLParser.setCurrentParser(nil)
.
The only exception is the case where user provided XMLParserDelegate
methods call XMLParser.parse()
, but the reentrancy issue is not specific to os(WASI)
branch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation. The reentrancy possibility isn't unique to WASI, but its ability to manipulate the underlying nonisolated(unsafe)
variable across actor isolations is unique to WASI with this change (on other platforms, that variable is thread-specific - which should probably be marked as unavailable from async for this reason).
The example I'm thinking of is: someone calls XMLParser.parse()
, in a delegate callout they create a new detached task on a different actor calling XMLParser.parse()
again. At this point, we have two actors manipulating the same underlying nonisolated(unsafe)
variable. Typically, that'd be a concurrency violation because two actors are mutating the same shared state. Since WASI is single-threaded, we know that this can't data race in practice, but it's still a violation in the Swift 6 concurrency design and I'm not sure how to rationalize that with the thread model of WASI at the moment (cc @hborla in case you have any insight here)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example I'm thinking of is: someone calls XMLParser.parse(), in a delegate callout they create a new detached task on a different actor calling XMLParser.parse() again.
Having a closer look, I noticed the problem exists even in non-WASI code path since jobs associated with two different Tasks can be scheduled on the same thread, and in that case two different tasks can manipulate the same thread local variable.
So we had two issues in the existing code, 1. reentrancy issue, 2. sharing mutable storage across Tasks. I'll send a fix for them in another PR and exclude the commit from this PR. Does it make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jmschonfeld Opened another PR to fix the issues #5061
@swift-ci test |
@swift-ci test windows |
@@ -471,7 +471,7 @@ open class XMLParser : NSObject { | |||
open var allowedExternalEntityURLs: Set<URL>? | |||
|
|||
#if os(WASI) | |||
private static var _currentParser: XMLParser? | |||
private nonisolated(unsafe) static var _currentParser: XMLParser? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation. The reentrancy possibility isn't unique to WASI, but its ability to manipulate the underlying nonisolated(unsafe)
variable across actor isolations is unique to WASI with this change (on other platforms, that variable is thread-specific - which should probably be marked as unavailable from async for this reason).
The example I'm thinking of is: someone calls XMLParser.parse()
, in a delegate callout they create a new detached task on a different actor calling XMLParser.parse()
again. At this point, we have two actors manipulating the same underlying nonisolated(unsafe)
variable. Typically, that'd be a concurrency violation because two actors are mutating the same shared state. Since WASI is single-threaded, we know that this can't data race in practice, but it's still a violation in the Swift 6 concurrency design and I'm not sure how to rationalize that with the thread model of WASI at the moment (cc @hborla in case you have any insight here)
We accidentally changed it to `__builtin_frame_address` in 7f38264 but we should keep it as `__builtin_return_address` as it was before.
To avoid shippig BlocksRuntime as a separate library, build it as an object library and include it in CoreFoundation static archive.
We ported BlocksRuntime CMakeLists.txt from the state of 02b7d8f but we don't find any reason to set POSITION_INDEPENDENT_CODE=FALSE for BlocksRuntime.
c5f47e7
to
3b8485a
Compare
@swift-ci please test |
@swift-ci test Windows |
I forgot to tell @MaxDesiatov we need several additional changes other than #5052