Skip to content

Commit 902c8a5

Browse files
committed
Async VFS file writing
1 parent 645c421 commit 902c8a5

File tree

14 files changed

+134
-128
lines changed

14 files changed

+134
-128
lines changed

Wazzy/Interop/Buffer.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,39 @@ public Span<T> GetSpan(Caller caller)
5353
{
5454
return GetSpan(caller.GetMemory("memory")!);
5555
}
56+
}
57+
58+
internal static class BufferExtensions
59+
{
60+
public static uint TotalLength<T>(this Buffer<Buffer<T>> buffers, Caller caller)
61+
where T : unmanaged
62+
{
63+
var length = 0u;
64+
foreach (var inner in buffers.GetSpan(caller))
65+
length += inner.Length;
66+
return length;
67+
}
68+
69+
public static uint TotalLength<T>(this ReadonlyBuffer<ReadonlyBuffer<T>> buffers, Caller caller)
70+
where T : unmanaged
71+
{
72+
var length = 0u;
73+
foreach (var inner in buffers.GetSpan(caller))
74+
length += inner.Length;
75+
return length;
76+
}
77+
78+
public static Memory<T> Flatten<T>(this ReadonlyBuffer<ReadonlyBuffer<T>> buffers, Caller caller, T[] dest)
79+
where T : unmanaged
80+
{
81+
var ptr = 0;
82+
foreach (var buffer in buffers.GetSpan(caller))
83+
{
84+
var inner = buffer.GetSpan(caller);
85+
inner.CopyTo(dest.AsSpan(ptr));
86+
ptr += inner.Length;
87+
}
88+
89+
return dest.AsMemory(0, ptr);
90+
}
5691
}

Wazzy/WasiSnapshotPreview1/FileSystem/IWasiFileSystem.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System.Text;
2-
using Wasmtime;
1+
using Wasmtime;
32
using Wazzy.Interop;
43

54
namespace Wazzy.WasiSnapshotPreview1.FileSystem;
@@ -83,9 +82,9 @@ public interface IWasiFileSystem
8382
/// <param name="caller">Context for this call</param>
8483
/// <param name="fd">File descriptor to write to</param>
8584
/// <param name="iovs">set of buffers to write</param>
86-
/// <param name="nwritten">total number of bytes written</param>
85+
/// <param name="nwrittenPtr">total number of bytes written</param>
8786
/// <returns></returns>
88-
public WasiError Write(Caller caller, FileDescriptor fd, ReadonlyBuffer<ReadonlyBuffer<byte>> iovs, out uint nwritten);
87+
public WasiError Write(Caller caller, FileDescriptor fd, ReadonlyBuffer<ReadonlyBuffer<byte>> iovs, Pointer<uint> nwrittenPtr);
8988

9089
/// <summary>
9190
/// Write to a given file descriptor without updating the offset
@@ -96,7 +95,7 @@ public interface IWasiFileSystem
9695
/// <param name="offset"></param>
9796
/// <param name="nwrittenOutput"></param>
9897
/// <returns></returns>
99-
public WasiError PWrite(Caller caller, FileDescriptor fd, ReadonlyBuffer<ReadonlyBuffer<byte>> iovs, long offset, out uint nwrittenOutput);
98+
public WasiError PWrite(Caller caller, FileDescriptor fd, ReadonlyBuffer<ReadonlyBuffer<byte>> iovs, long offset, Pointer<uint> nwrittenPtr);
10099

101100
/// <summary>
102101
/// Get a "FileStat" object for the given file descriptor
@@ -487,7 +486,7 @@ void IWasiFeature.DefineOn(Linker linker)
487486
c,
488487
new FileDescriptor(fd),
489488
new ReadonlyBuffer<ReadonlyBuffer<byte>>(iovsAddr, (uint)iovsCount),
490-
out new Pointer<uint>(nwrittenAddr).Deref(c)
489+
new Pointer<uint>(nwrittenAddr)
491490
)
492491
);
493492

@@ -497,7 +496,7 @@ void IWasiFeature.DefineOn(Linker linker)
497496
new FileDescriptor(fd),
498497
new ReadonlyBuffer<ReadonlyBuffer<byte>>(iovsAddr, (uint)iovsCount),
499498
offset,
500-
out new Pointer<uint>(nwrittenAddr).Deref(c)
499+
new Pointer<uint>(nwrittenAddr)
501500
)
502501
);
503502

Wazzy/WasiSnapshotPreview1/FileSystem/Implementations/NullFilesystem.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ namespace Wazzy.WasiSnapshotPreview1.FileSystem.Implementations;
99
public class NullFilesystem
1010
: IWasiFileSystem
1111
{
12-
public WasiError Write(Caller caller, FileDescriptor fd, ReadonlyBuffer<ReadonlyBuffer<byte>> iovs, out uint nwritten)
12+
public WasiError Write(Caller caller, FileDescriptor fd, ReadonlyBuffer<ReadonlyBuffer<byte>> iovs, Pointer<uint> nwritten)
1313
{
14-
nwritten = 0;
14+
nwritten.Deref(caller) = 0;
1515

1616
// Check if it's stdout or stderr
1717
if (fd.Handle != 1 && fd.Handle != 2)
@@ -22,7 +22,7 @@ public WasiError Write(Caller caller, FileDescriptor fd, ReadonlyBuffer<Readonly
2222
for (var i = 0; i < iovecs.Length; i++)
2323
{
2424
var span = iovecs[i].GetSpan(caller);
25-
nwritten += (uint)span.Length;
25+
nwritten.Deref(caller) += (uint)span.Length;
2626
}
2727

2828
// Done
@@ -62,9 +62,9 @@ public WasiError PathCreateDirectory(Caller caller, FileDescriptor fd, ReadOnlyS
6262
return WasiError.EBADF;
6363
}
6464

65-
public WasiError PWrite(Caller caller, FileDescriptor fd, ReadonlyBuffer<ReadonlyBuffer<byte>> iovs, long offset, out uint nread)
65+
public WasiError PWrite(Caller caller, FileDescriptor fd, ReadonlyBuffer<ReadonlyBuffer<byte>> iovs, long offset, Pointer<uint> nwritten)
6666
{
67-
nread = 0;
67+
nwritten.Deref(caller) = 0;
6868
return WasiError.EBADF;
6969
}
7070

Wazzy/WasiSnapshotPreview1/FileSystem/Implementations/VirtualFileSystem/Builder/VirtualFileSystemBuilder.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class VirtualFileSystemBuilder
1818
private bool _readonly;
1919
private bool _blocking;
2020
private readonly List<string> _preopens = [];
21+
private int _seed = 17;
2122

2223
private void ThrowClosed([CallerMemberName] string name = "")
2324
{
@@ -41,7 +42,8 @@ public VirtualFileSystem Build()
4142
_stdout ?? new ZeroFile(),
4243
_stderr ?? new ZeroFile(),
4344
root,
44-
_preopens
45+
_preopens,
46+
_seed
4547
);
4648
}
4749

@@ -118,4 +120,10 @@ internal VirtualFileSystemBuilder WithPreopen(string path)
118120
_preopens.Add(path);
119121
return this;
120122
}
123+
124+
public VirtualFileSystemBuilder Seed(int seed)
125+
{
126+
_seed = seed;
127+
return this;
128+
}
121129
}

Wazzy/WasiSnapshotPreview1/FileSystem/Implementations/VirtualFileSystem/Files/ConsoleLog.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ public override void Truncate(ulong timestamp, long size)
4242
throw new NotSupportedException("Cannot truncate ConsoleLog");
4343
}
4444

45-
public override uint Write(ReadOnlySpan<byte> bytes, ulong timestamp)
45+
public override Task<uint> Write(ReadOnlyMemory<byte> bytes, ulong timestamp)
4646
{
4747
File.AccessTime = timestamp;
4848
File.ModificationTime = timestamp;
4949
File.ChangeTime = timestamp;
5050

51-
_builder.AddRange(bytes);
51+
_builder.AddRange(bytes.Span);
5252

5353
if (_builder.Count >= File._maxBufferSize)
5454
{
@@ -67,7 +67,7 @@ public override uint Write(ReadOnlySpan<byte> bytes, ulong timestamp)
6767
}
6868
}
6969

70-
return (uint)bytes.Length;
70+
return Task.FromResult((uint)bytes.Length);
7171
}
7272

7373
private void WriteToLog(int count)

Wazzy/WasiSnapshotPreview1/FileSystem/Implementations/VirtualFileSystem/Files/IFileHandle.cs

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
using Wasmtime;
2-
using Wazzy.Interop;
3-
4-
namespace Wazzy.WasiSnapshotPreview1.FileSystem.Implementations.VirtualFileSystem.Files;
1+
namespace Wazzy.WasiSnapshotPreview1.FileSystem.Implementations.VirtualFileSystem.Files;
52

63
/// <summary>
74
/// Base interface for a handle to an open file
@@ -35,7 +32,7 @@ public interface IFileHandle
3532
/// <param name="bytes">Bytes to write</param>
3633
/// <param name="timestamp">Timestamp of "now", used to update file metadata</param>
3734
/// <returns>Count of written bytes</returns>
38-
uint Write(ReadOnlySpan<byte> bytes, ulong timestamp);
35+
Task<uint> Write(ReadOnlyMemory<byte> bytes, ulong timestamp);
3936

4037
/// <summary>
4138
/// Read bytes from the file into the buffer
@@ -114,31 +111,6 @@ SeekResult Seek(long offset, Whence whence, out ulong finalOffset)
114111
ulong PollReadableBytes();
115112

116113
ulong PollWritableBytes();
117-
118-
/// <summary>
119-
/// Write all of the iovs one by one
120-
/// </summary>
121-
/// <param name="caller"></param>
122-
/// <param name="iovs"></param>
123-
/// <param name="timestamp"></param>
124-
/// <returns>bytes written</returns>
125-
uint Write(Caller caller, ReadonlyBuffer<ReadonlyBuffer<byte>> iovs, ulong timestamp)
126-
{
127-
var nwrittenOutput = 0u;
128-
129-
var iovecs = iovs.GetSpan(caller);
130-
for (var i = 0; i < iovecs.Length; i++)
131-
{
132-
var span = iovecs[i].GetSpan(caller);
133-
var written = Write(span, timestamp);
134-
nwrittenOutput += written;
135-
136-
if (written != span.Length)
137-
break;
138-
}
139-
140-
return nwrittenOutput;
141-
}
142114
}
143115

144116
public abstract class BaseFileHandle<T>
@@ -192,7 +164,7 @@ public WasiError SetFlags(FdFlags flags)
192164

193165
public abstract void Truncate(ulong timestamp, long size);
194166

195-
public abstract uint Write(ReadOnlySpan<byte> bytes, ulong timestamp);
167+
public abstract Task<uint> Write(ReadOnlyMemory<byte> bytes, ulong timestamp);
196168

197169
public abstract void Dispose();
198170

Wazzy/WasiSnapshotPreview1/FileSystem/Implementations/VirtualFileSystem/Files/InMemoryFile.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,20 @@ public override Task<uint> Read(Memory<byte> memory, ulong timestamp)
4949
return Task.FromResult((uint)read);
5050
}
5151

52-
public override uint Write(ReadOnlySpan<byte> bytes, ulong timestamp)
52+
public override Task<uint> Write(ReadOnlyMemory<byte> bytes, ulong timestamp)
5353
{
5454
TryWrite(timestamp);
5555

5656
if ((Flags & FdFlags.Append) != 0)
5757
_position = File._memory.Length;
5858

5959
File._memory.Seek(_position, SeekOrigin.Begin);
60-
File._memory.Write(bytes);
60+
File._memory.Write(bytes.Span);
6161

6262
var written = bytes.Length;
6363
_position += written;
6464

65-
return (uint)written;
65+
return Task.FromResult((uint)written);
6666
}
6767

6868
private void TryRead(ulong timestamp)

Wazzy/WasiSnapshotPreview1/FileSystem/Implementations/VirtualFileSystem/Files/MappedFile.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,13 @@ public override void Truncate(ulong timestamp, long size)
6262
}
6363
}
6464

65-
public override uint Write(ReadOnlySpan<byte> bytes, ulong timestamp)
65+
public override async Task<uint> Write(ReadOnlyMemory<byte> bytes, ulong timestamp)
6666
{
67-
_stream.Write(bytes);
67+
await _stream.WriteAsync(bytes);
68+
6869
if (_flushWrites)
69-
_stream.Flush();
70+
await _stream.FlushAsync();
71+
7072
return (uint)bytes.Length;
7173
}
7274

Wazzy/WasiSnapshotPreview1/FileSystem/Implementations/VirtualFileSystem/Files/MappedZipEntryFile.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public override ulong Position
3737

3838
public override ulong Size => _file.Size;
3939

40-
public override uint Write(ReadOnlySpan<byte> bytes, ulong timestamp)
40+
public override Task<uint> Write(ReadOnlyMemory<byte> bytes, ulong timestamp)
4141
{
4242
throw new NotSupportedException();
4343
}

Wazzy/WasiSnapshotPreview1/FileSystem/Implementations/VirtualFileSystem/Files/StringBuilderLog.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public override void Truncate(ulong timestamp, long size)
3939
throw new NotSupportedException("Cannot truncate StringBuilderLog");
4040
}
4141

42-
public override uint Write(ReadOnlySpan<byte> bytes, ulong timestamp)
42+
public override Task<uint> Write(ReadOnlyMemory<byte> bytes, ulong timestamp)
4343
{
4444
File.AccessTime = timestamp;
4545
File.ModificationTime = timestamp;
@@ -52,17 +52,17 @@ public override uint Write(ReadOnlySpan<byte> bytes, ulong timestamp)
5252
const int CHUNK_SIZE = 128;
5353
if (bytes.Length < CHUNK_SIZE)
5454
{
55-
bytesWritten += WriteBytes(bytes);
55+
bytesWritten += WriteBytes(bytes.Span);
5656
break;
5757
}
5858

59-
var chunk = bytes[..CHUNK_SIZE];
59+
var chunk = bytes[..CHUNK_SIZE].Span;
6060
bytesWritten += WriteBytes(chunk);
6161

6262
bytes = bytes[CHUNK_SIZE..];
6363
}
6464

65-
return bytesWritten;
65+
return Task.FromResult(bytesWritten);
6666
}
6767

6868
private uint WriteBytes(ReadOnlySpan<byte> bytes)

0 commit comments

Comments
 (0)