| ... | ... | @@ -762,13 +762,13 @@ const WasiThreadImpl = struct { |
| 762 | 762 | /// A meta-data structure used to bootstrap a thread |
| 763 | 763 | const Instance = struct { |
| 764 | 764 | thread: WasiThread, |
| 765 | | /// Address of this `Instance` |
| 766 | | base: usize, |
| 767 | | /// Contains the pointer of the new __tls_base. |
| 768 | | tls_base: usize, |
| 769 | | /// Contains the pointer to the stack for the newly spawned thread. |
| 770 | | stack_pointer: usize, |
| 771 | | /// Contains the pointer to the wrapper which holds all arguments |
| 765 | /// Contains the offset to the new __tls_base. |
| 766 | /// The offset starting from the memory's base. |
| 767 | tls_offset: usize, |
| 768 | /// Contains the offset to the stack for the newly spawned thread. |
| 769 | /// The offset is calculated starting from the memory's base. |
| 770 | stack_offset: usize, |
| 771 | /// Contains the raw pointer value to the wrapper which holds all arguments |
| 772 | 772 | /// for the callback. |
| 773 | 773 | raw_ptr: usize, |
| 774 | 774 | /// Function pointer to a wrapping function which will call the user's |
| ... | ... | @@ -790,9 +790,12 @@ const WasiThreadImpl = struct { |
| 790 | 790 | } |
| 791 | 791 | |
| 792 | 792 | fn join(self: Impl) void { |
| 793 | | // TODO cleanup memory |
| 794 | | // The memory also contains the thread's stack, which is problematic while freeing the memory |
| 795 | | // defer self.thread.allocator.free(self.thread.memory); |
| 793 | defer { |
| 794 | // Create a copy of the allocator so we do not free the reference to the |
| 795 | // original allocator while freeing the memory. |
| 796 | var allocator = self.thread.allocator; |
| 797 | allocator.free(self.thread.memory); |
| 798 | } |
| 796 | 799 | |
| 797 | 800 | var spin: u8 = 10; |
| 798 | 801 | while (true) { |
| ... | ... | @@ -808,11 +811,11 @@ const WasiThreadImpl = struct { |
| 808 | 811 | } |
| 809 | 812 | |
| 810 | 813 | const result = asm ( |
| 811 | | \\local.get %[ptr] |
| 812 | | \\local.get %[expected] |
| 813 | | \\i64.const -1 # infinite |
| 814 | | \\memory.atomic.wait32 0 |
| 815 | | \\local.set %[ret] |
| 814 | \\ local.get %[ptr] |
| 815 | \\ local.get %[expected] |
| 816 | \\ i64.const -1 # infinite |
| 817 | \\ memory.atomic.wait32 0 |
| 818 | \\ local.set %[ret] |
| 816 | 819 | : [ret] "=r" (-> u32), |
| 817 | 820 | : [ptr] "r" (&self.thread.tid.value), |
| 818 | 821 | [expected] "r" (tid), |
| ... | ... | @@ -883,9 +886,8 @@ const WasiThreadImpl = struct { |
| 883 | 886 | const instance = @ptrCast(*Instance, @alignCast(@alignOf(Instance), &allocated_memory[instance_offset])); |
| 884 | 887 | instance.* = .{ |
| 885 | 888 | .thread = .{ .memory = allocated_memory, .allocator = config.allocator.? }, |
| 886 | | .base = @ptrToInt(allocated_memory.ptr), |
| 887 | | .tls_base = tls_offset, |
| 888 | | .stack_pointer = stack_offset, |
| 889 | .tls_offset = tls_offset, |
| 890 | .stack_offset = stack_offset, |
| 889 | 891 | .raw_ptr = @ptrToInt(wrapper), |
| 890 | 892 | .call_back = &Wrapper.entry, |
| 891 | 893 | }; |
| ... | ... | @@ -903,8 +905,8 @@ const WasiThreadImpl = struct { |
| 903 | 905 | |
| 904 | 906 | /// Bootstrap procedure, called by the HOST environment after thread creation. |
| 905 | 907 | export fn wasi_thread_start(tid: i32, arg: *Instance) void { |
| 906 | | __set_stack_pointer(arg.thread.memory.ptr + arg.stack_pointer); |
| 907 | | __wasm_init_tls(arg.thread.memory.ptr + arg.tls_base); |
| 908 | __set_stack_pointer(arg.thread.memory.ptr + arg.stack_offset); |
| 909 | __wasm_init_tls(arg.thread.memory.ptr + arg.tls_offset); |
| 908 | 910 | WasiThreadImpl.tls_thread_id = @intCast(u32, tid); |
| 909 | 911 | |
| 910 | 912 | // Finished bootstrapping, call user's procedure. |