aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorkprotty <kbutcher6200@gmail.com>2021-07-01 17:34:23 -0500
committerkprotty <kbutcher6200@gmail.com>2021-07-01 17:34:23 -0500
commit483eb8e05788f2ee258bc1719f210c51a2057dd6 (patch)
tree627c8b54c4c134018662cbf9dd27c32ff2a04c81 /lib/std
parent98106b09d5bf1bcc1be4fe09a7fa645b3b343732 (diff)
downloadzig-483eb8e05788f2ee258bc1719f210c51a2057dd6.tar.gz
zig-483eb8e05788f2ee258bc1719f210c51a2057dd6.zip
std.Thread: move linux detach code to inline asm
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/Thread.zig202
1 files changed, 96 insertions, 106 deletions
diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig
index 8f245c257c..37b0a8751f 100644
--- a/lib/std/Thread.zig
+++ b/lib/std/Thread.zig
@@ -500,6 +500,101 @@ const LinuxThreadImpl = struct {
child_tid: Atomic(i32) = Atomic(i32).init(1),
parent_tid: i32 = undefined,
mapped: []align(std.mem.page_size) u8,
+
+ /// Calls `munmap(mapped.ptr, mapped.len)` then `exit(1)` without touching the stack (which lives in `mapped.ptr`).
+ /// Ported over from musl libc's pthread detached implementation:
+ /// https://github.com/ifduyue/musl/search?q=__unmapself
+ fn freeAndExit(self: *ThreadCompletion) noreturn {
+ const unmap_and_exit: []const u8 = switch (target.cpu.arch) {
+ .i386 => (
+ \\ movl $91, %%eax
+ \\ movl %[ptr], %%ebx
+ \\ movl %[len], %%ecx
+ \\ int $128
+ \\ movl $1, %%eax
+ \\ movl $0, %%ebx
+ \\ int $128
+ ),
+ .x86_64 => (
+ \\ movq $11, %%rax
+ \\ movq %[ptr], %%rbx
+ \\ movq %[len], %%rcx
+ \\ syscall
+ \\ movq $60, %%rax
+ \\ movq $1, %%rdi
+ \\ syscall
+ ),
+ .arm, .armeb, .thumb, .thumbeb => (
+ \\ mov r7, #91
+ \\ mov r0, %[ptr]
+ \\ mov r1, %[len]
+ \\ svc 0
+ \\ mov r7, #1
+ \\ mov r0, #0
+ \\ svc 0
+ ),
+ .aarch64, .aarch64_be, .aarch64_32 => (
+ \\ mov x8, #215
+ \\ mov x0, %[ptr]
+ \\ mov x1, %[len]
+ \\ svc 0
+ \\ mov x8, #93
+ \\ mov x0, #0
+ \\ svc 0
+ ),
+ .mips, .mipsel => (
+ \\ move $sp, $25
+ \\ li $2, 4091
+ \\ move $4, %[ptr]
+ \\ move $5, %[len]
+ \\ syscall
+ \\ li $2, 4001
+ \\ li $4, 0
+ \\ syscall
+ ),
+ .mips64, .mips64el => (
+ \\ li $2, 4091
+ \\ move $4, %[ptr]
+ \\ move $5, %[len]
+ \\ syscall
+ \\ li $2, 4001
+ \\ li $4, 0
+ \\ syscall
+ ),
+ .powerpc, .powerpcle, .powerpc64, .powerpc64le => (
+ \\ li 0, 91
+ \\ mr %[ptr], 3
+ \\ mr %[len], 4
+ \\ sc
+ \\ li 0, 1
+ \\ li 3, 0
+ \\ sc
+ \\ blr
+ ),
+ .riscv64 => (
+ \\ li a7, 215
+ \\ mv a0, %[ptr]
+ \\ mv a1, %[len]
+ \\ ecall
+ \\ li a7, 93
+ \\ mv a0, zero
+ \\ ecall
+ ),
+ else => |cpu_arch| {
+ @compileLog("Unsupported linux arch ", cpu_arch);
+ },
+ };
+
+ asm volatile (
+ unmap_and_exit
+ :
+ : [ptr] "r" (@ptrToInt(self.mapped.ptr)),
+ [len] "r" (self.mapped.len)
+ : "memory"
+ );
+
+ unreachable;
+ }
};
fn spawn(config: SpawnConfig, comptime f: anytype, args: anytype) !Impl {
@@ -513,10 +608,7 @@ const LinuxThreadImpl = struct {
defer switch (self.thread.completion.swap(.completed, .SeqCst)) {
.running => {},
.completed => unreachable,
- .detached => {
- const memory = self.thread.mapped;
- __unmap_and_exit(@ptrToInt(memory.ptr), memory.len);
- },
+ .detached => self.thread.freeAndExit(),
};
return callFn(f, self.fn_args);
}
@@ -664,108 +756,6 @@ const LinuxThreadImpl = struct {
}
}
}
-
- // Calls `munmap(ptr, len)` then `exit(1)` without touching the stack (which lives in `ptr`).
- // Ported over from musl libc's pthread detached implementation (`__unmapself`).
- extern fn __unmap_and_exit(ptr: usize, len: usize) callconv(.C) noreturn;
- comptime {
- if (target.os.tag == .linux) {
- asm (switch (target.cpu.arch) {
- .i386 => (
- \\.text
- \\.global __unmap_and_exit
- \\.type __unmap_and_exit, @function
- \\__unmap_and_exit:
- \\ movl $91, %eax
- \\ movl 4(%esp), %ebx
- \\ movl 8(%esp), %ecx
- \\ int $128
- \\ xorl %ebx, %ebx
- \\ movl $1, %eax
- \\ int $128
- ),
- .x86_64 => (
- \\.text
- \\.global __unmap_and_exit
- \\.type __unmap_and_exit, @function
- \\__unmap_and_exit:
- \\ movl $11, %eax
- \\ syscall
- \\ xor %rdi, %rdi
- \\ movl $60, %eax
- \\ syscall
- ),
- .arm, .armeb, .thumb, .thumbeb => (
- \\.syntax unified
- \\.text
- \\.global __unmap_and_exit
- \\.type __unmap_and_exit, %function
- \\__unmap_and_exit:
- \\ mov r7, #91
- \\ svc 0
- \\ mov r7, #1
- \\ svc 0
- ),
- .aarch64, .aarch64_be, .aarch64_32 => (
- \\.global __unmap_and_exit
- \\.type __unmap_and_exit, %function
- \\__unmap_and_exit:
- \\ mov x8, #215
- \\ svc 0
- \\ mov x8, #93
- \\ svc 0
- ),
- .mips,
- .mipsel,
- => (
- \\.set noreorder
- \\.global __unmap_and_exit
- \\.type __unmap_and_exit,@function
- \\__unmap_and_exit:
- \\ move $sp, $25
- \\ li $2, 4091
- \\ syscall
- \\ li $4, 0
- \\ li $2, 4001
- \\ syscall
- ),
- .mips64, .mips64el => (
- \\.set noreorder
- \\.global __unmap_and_exit
- \\.type __unmap_and_exit, @function
- \\__unmap_and_exit:
- \\ li $2, 4091
- \\ syscall
- \\ li $4, 0
- \\ li $2, 4001
- \\ syscall
- ),
- .powerpc, .powerpc64, .powerpc64le => (
- \\.text
- \\.global __unmap_and_exit
- \\.type __unmap_and_exit, %function
- \\__unmap_and_exit:
- \\ li 0, 91
- \\ sc
- \\ li 0, 1
- \\ sc
- \\ blr
- ),
- .riscv64 => (
- \\.global __unmap_and_exit
- \\.type __unmap_and_exit, %function
- \\__unmap_and_exit:
- \\ li a7, 215
- \\ ecall
- \\ li a7, 93
- \\ ecall
- ),
- else => |cpu_arch| {
- @compileLog("linux arch", cpu_arch, "is not supported");
- },
- });
- }
- }
};
test "std.Thread" {