mirror of
https://github.com/ziglang/zig.git
synced 2026-01-21 06:45:24 +00:00
store allocator & remove global assembly
We now store the original allocator that was used to allocate the memory required for the thread. This allocator can then be used in any cleanup functionality to ensure the memory is freed correctly. Secondly, we now use a function to set the stack pointer instead of generating a function using global assembly. This is a lot cleaner and more readable.
This commit is contained in:
parent
a97dbdfa0b
commit
10bf58b2db
@ -739,32 +739,24 @@ const PosixThreadImpl = struct {
|
||||
};
|
||||
|
||||
const WasiThreadImpl = struct {
|
||||
comptime {
|
||||
// Sets the stack pointer, which is needed after creating a new thread
|
||||
// to ensure the stack of the main thread isn't being poluted.
|
||||
asm (
|
||||
\\ .text
|
||||
\\ .export_name __set_stack_pointer, __set_stack_pointer
|
||||
\\ .globaltype __stack_pointer, i32
|
||||
\\ .hidden wasi_thread_start
|
||||
\\ .globl wasi_thread_start
|
||||
\\ .type __set_stack_pointer, @function
|
||||
\\
|
||||
\\ __set_stack_pointer:
|
||||
\\ .functype __set_stack_pointer (i32) -> ()
|
||||
\\ local.get 0 # The raw pointer which replaces the stack pointer
|
||||
\\ global.set __stack_pointer
|
||||
\\ end_function
|
||||
);
|
||||
}
|
||||
thread: *WasiThread,
|
||||
|
||||
pub const ThreadHandle = i32;
|
||||
threadlocal var tls_thread_id: Id = 0;
|
||||
|
||||
const WasiThread = struct {
|
||||
/// Thread ID
|
||||
tid: Atomic(i32) = Atomic(i32).init(0),
|
||||
/// Contains all memory which was allocated to bootstrap this thread, including:
|
||||
/// - Guard page
|
||||
/// - Stack
|
||||
/// - TLS segment
|
||||
/// - `Instance`
|
||||
/// All memory is freed upon call to `join`
|
||||
memory: []u8,
|
||||
/// The allocator used to allocate the thread's memory,
|
||||
/// which is also used during `join` to ensure clean-up.
|
||||
allocator: std.mem.Allocator,
|
||||
};
|
||||
|
||||
/// A meta-data structure used to bootstrap a thread
|
||||
@ -790,7 +782,7 @@ const WasiThreadImpl = struct {
|
||||
}
|
||||
|
||||
fn getHandle(self: Impl) ThreadHandle {
|
||||
return self.thread.tid;
|
||||
return self.thread.tid.load(.SeqCst);
|
||||
}
|
||||
|
||||
fn detach(self: Impl) void {
|
||||
@ -813,7 +805,6 @@ const WasiThreadImpl = struct {
|
||||
}
|
||||
};
|
||||
|
||||
var guard_offset: usize = undefined;
|
||||
var stack_offset: usize = undefined;
|
||||
var tls_offset: usize = undefined;
|
||||
var wrapper_offset: usize = undefined;
|
||||
@ -824,8 +815,11 @@ const WasiThreadImpl = struct {
|
||||
// - The TLS segment
|
||||
// - `Instance` - containing information about how to call the user's function.
|
||||
const map_bytes = blk: {
|
||||
// start with atleast a single page, which is used as a guard to prevent
|
||||
// other threads clobbering our new thread.
|
||||
// Unfortunately, WebAssembly has no notion of read-only segments, so this
|
||||
// is only a temporary measure until the entire page is "run over".
|
||||
var bytes: usize = std.wasm.page_size;
|
||||
guard_offset = bytes;
|
||||
|
||||
bytes = std.mem.alignForward(usize, bytes, 16); // align stack to 16 bytes
|
||||
stack_offset = bytes;
|
||||
@ -855,7 +849,7 @@ const WasiThreadImpl = struct {
|
||||
|
||||
const instance = @ptrCast(*Instance, @alignCast(@alignOf(Instance), &allocated_memory[instance_offset]));
|
||||
instance.* = .{
|
||||
.thread = .{ .memory = allocated_memory },
|
||||
.thread = .{ .memory = allocated_memory, .allocator = config.allocator.? },
|
||||
.base = @ptrToInt(allocated_memory.ptr),
|
||||
.tls_base = tls_offset,
|
||||
.stack_pointer = stack_offset,
|
||||
@ -923,6 +917,16 @@ const WasiThreadImpl = struct {
|
||||
: [ret] "=r" (-> u32),
|
||||
);
|
||||
}
|
||||
|
||||
/// Allows for setting the stack pointer in the WebAssembly module.
|
||||
inline fn __set_stack_pointer(addr: [*]u8) void {
|
||||
asm volatile (
|
||||
\\ local.get %[ptr]
|
||||
\\ global.set __stack_pointer
|
||||
:
|
||||
: [ptr] "r" (addr),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const LinuxThreadImpl = struct {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user