-
Notifications
You must be signed in to change notification settings - Fork 5.2k
[WASI] timers based on wasi:clocks #105879
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
Changes from all commits
d19d317
4217313
1872580
d3586a5
b9f4243
3129ac4
31006e4
3ca5606
b14f61a
0ad3fe5
00eab2f
186d55d
7b2d74e
e95a702
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<linker> | ||
<assembly fullname="System.Private.CoreLib"> | ||
<!-- these methods are temporarily accessed via UnsafeAccessor from generated code until we have it in public API, probably in WASI preview3 and promises --> | ||
<type fullname="System.Threading.Thread"> | ||
<method name="RegisterWasiPollableHandle" /> | ||
<method name="PollWasiEventLoopUntilResolved" /> | ||
</type> | ||
</assembly> | ||
</linker> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,22 +5,34 @@ | |
using System.Runtime; | ||
using System.Runtime.InteropServices; | ||
using Microsoft.Win32.SafeHandles; | ||
using System.Threading.Tasks; | ||
|
||
namespace System.Threading | ||
{ | ||
public sealed partial class Thread | ||
{ | ||
// these methods are temporarily accessed via UnsafeAccessor from generated code until we have it in public API, probably in WASI preview3 and promises | ||
#if TARGET_WASI | ||
internal static System.Threading.Tasks.Task RegisterWasiPollable(int handle) | ||
internal static System.Threading.Tasks.Task RegisterWasiPollableHandle(int handle) | ||
{ | ||
return WasiEventLoop.RegisterWasiPollable(handle); | ||
return WasiEventLoop.RegisterWasiPollableHandle(handle); | ||
} | ||
|
||
internal static void DispatchWasiEventLoop() | ||
internal static int PollWasiEventLoopUntilResolved(Task<int> mainTask) | ||
{ | ||
WasiEventLoop.DispatchWasiEventLoop(); | ||
while (!mainTask.IsCompleted) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is probably too naive solution. Such code/tasks/continuations could have (expected) externally observable side effects (after we exit the entry point). But I don't know how to do that at this point. So I guess it will be some next PR. cc @dicej There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the browser we schedule browser callback any time the new job triggers Maybe we need to run cc @SingleAccretion , any thoughts ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree that full event loop emulation requires what is effectively: bool workItemsLeft;
do
{
workItemsLeft = ThreadPoolWorkQueue.Dispatch();
}
while (workItemsLeft) I think it's ok to wait for the top-level task only here. It matches "normal" platform's behavior: ThreadPool.QueueUserWorkItem(x => { Thread.Sleep(100); Console.WriteLine(); });
> dotnet run
; Nothing printed because thread pool threads are background threads. So it seems unlikely our tests would depend on it. It does not match Browser's behavior, of course. It is a point to debate whether we'd want the eventual async main experience to match browser or not-browser. |
||
{ | ||
WasiEventLoop.DispatchWasiEventLoop(); | ||
} | ||
var exception = mainTask.Exception; | ||
if (exception is not null) | ||
{ | ||
throw exception; | ||
} | ||
|
||
return mainTask.Result; | ||
} | ||
|
||
#endif | ||
|
||
// the closest analog to Sleep(0) on Unix is sched_yield | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// Generated by `wit-bindgen` 0.29.0. DO NOT EDIT! | ||
// <auto-generated /> | ||
#nullable enable | ||
|
||
using System; | ||
using System.Runtime.CompilerServices; | ||
using System.Collections; | ||
using System.Runtime.InteropServices; | ||
using System.Text; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Diagnostics.CodeAnalysis; | ||
|
||
namespace WasiPollWorld.wit.imports.wasi.clocks.v0_2_1 | ||
{ | ||
internal static class MonotonicClockInterop { | ||
|
||
internal static class NowWasmInterop | ||
{ | ||
[DllImport("wasi:clocks/[email protected]", EntryPoint = "now"), WasmImportLinkage] | ||
internal static extern long wasmImportNow(); | ||
|
||
} | ||
|
||
internal static unsafe ulong Now() | ||
{ | ||
var result = NowWasmInterop.wasmImportNow(); | ||
return unchecked((ulong)(result)); | ||
|
||
//TODO: free alloc handle (interopString) if exists | ||
} | ||
|
||
internal static class ResolutionWasmInterop | ||
{ | ||
[DllImport("wasi:clocks/[email protected]", EntryPoint = "resolution"), WasmImportLinkage] | ||
internal static extern long wasmImportResolution(); | ||
|
||
} | ||
|
||
internal static unsafe ulong Resolution() | ||
{ | ||
var result = ResolutionWasmInterop.wasmImportResolution(); | ||
return unchecked((ulong)(result)); | ||
|
||
//TODO: free alloc handle (interopString) if exists | ||
} | ||
|
||
internal static class SubscribeInstantWasmInterop | ||
{ | ||
[DllImport("wasi:clocks/[email protected]", EntryPoint = "subscribe-instant"), WasmImportLinkage] | ||
internal static extern int wasmImportSubscribeInstant(long p0); | ||
|
||
} | ||
|
||
internal static unsafe global::WasiPollWorld.wit.imports.wasi.io.v0_2_1.IPoll.Pollable SubscribeInstant(ulong when) | ||
{ | ||
var result = SubscribeInstantWasmInterop.wasmImportSubscribeInstant(unchecked((long)(when))); | ||
var resource = new global::WasiPollWorld.wit.imports.wasi.io.v0_2_1.IPoll.Pollable(new global::WasiPollWorld.wit.imports.wasi.io.v0_2_1.IPoll.Pollable.THandle(result)); | ||
return resource; | ||
|
||
//TODO: free alloc handle (interopString) if exists | ||
} | ||
|
||
internal static class SubscribeDurationWasmInterop | ||
{ | ||
[DllImport("wasi:clocks/[email protected]", EntryPoint = "subscribe-duration"), WasmImportLinkage] | ||
internal static extern int wasmImportSubscribeDuration(long p0); | ||
|
||
} | ||
|
||
internal static unsafe global::WasiPollWorld.wit.imports.wasi.io.v0_2_1.IPoll.Pollable SubscribeDuration(ulong when) | ||
{ | ||
var result = SubscribeDurationWasmInterop.wasmImportSubscribeDuration(unchecked((long)(when))); | ||
var resource = new global::WasiPollWorld.wit.imports.wasi.io.v0_2_1.IPoll.Pollable(new global::WasiPollWorld.wit.imports.wasi.io.v0_2_1.IPoll.Pollable.THandle(result)); | ||
return resource; | ||
|
||
//TODO: free alloc handle (interopString) if exists | ||
} | ||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ tar xzf v0.2.1.tar.gz | |
cat >wasi-http-0.2.1/wit/world.wit <<EOF | ||
world wasi-poll { | ||
import wasi:io/[email protected]; | ||
import wasi:clocks/[email protected]; | ||
} | ||
EOF | ||
wit-bindgen c-sharp -w wasi-poll -r native-aot --internal --skip-support-files wasi-http-0.2.1/wit | ||
|
Uh oh!
There was an error while loading. Please reload this page.