authorgravatar for kbutcher6200@gmail.comkprotty <kbutcher6200@gmail.com> 2021-07-01 17:34:23-05:00
committergravatar for kbutcher6200@gmail.comkprotty <kbutcher6200@gmail.com> 2021-07-01 17:34:23-05:00
log483eb8e05788f2ee258bc1719f210c51a2057dd6
tree627c8b54c4c134018662cbf9dd27c32ff2a04c81
parent98106b09d5bf1bcc1be4fe09a7fa645b3b343732

std.Thread: move linux detach code to inline asm


1 files changed, 96 insertions(+), 106 deletions(-)

lib/std/Thread.zig+96-106
......@@ -500,6 +500,101 @@ const LinuxThreadImpl = struct {
500500 child_tid: Atomic(i32) = Atomic(i32).init(1),
501501 parent_tid: i32 = undefined,
502502 mapped: []align(std.mem.page_size) u8,
503
504 /// Calls `munmap(mapped.ptr, mapped.len)` then `exit(1)` without touching the stack (which lives in `mapped.ptr`).
505 /// Ported over from musl libc's pthread detached implementation:
506 /// https://github.com/ifduyue/musl/search?q=__unmapself
507 fn freeAndExit(self: *ThreadCompletion) noreturn {
508 const unmap_and_exit: []const u8 = switch (target.cpu.arch) {
509 .i386 => (
510 \\ movl $91, %%eax
511 \\ movl %[ptr], %%ebx
512 \\ movl %[len], %%ecx
513 \\ int $128
514 \\ movl $1, %%eax
515 \\ movl $0, %%ebx
516 \\ int $128
517 ),
518 .x86_64 => (
519 \\ movq $11, %%rax
520 \\ movq %[ptr], %%rbx
521 \\ movq %[len], %%rcx
522 \\ syscall
523 \\ movq $60, %%rax
524 \\ movq $1, %%rdi
525 \\ syscall
526 ),
527 .arm, .armeb, .thumb, .thumbeb => (
528 \\ mov r7, #91
529 \\ mov r0, %[ptr]
530 \\ mov r1, %[len]
531 \\ svc 0
532 \\ mov r7, #1
533 \\ mov r0, #0
534 \\ svc 0
535 ),
536 .aarch64, .aarch64_be, .aarch64_32 => (
537 \\ mov x8, #215
538 \\ mov x0, %[ptr]
539 \\ mov x1, %[len]
540 \\ svc 0
541 \\ mov x8, #93
542 \\ mov x0, #0
543 \\ svc 0
544 ),
545 .mips, .mipsel => (
546 \\ move $sp, $25
547 \\ li $2, 4091
548 \\ move $4, %[ptr]
549 \\ move $5, %[len]
550 \\ syscall
551 \\ li $2, 4001
552 \\ li $4, 0
553 \\ syscall
554 ),
555 .mips64, .mips64el => (
556 \\ li $2, 4091
557 \\ move $4, %[ptr]
558 \\ move $5, %[len]
559 \\ syscall
560 \\ li $2, 4001
561 \\ li $4, 0
562 \\ syscall
563 ),
564 .powerpc, .powerpcle, .powerpc64, .powerpc64le => (
565 \\ li 0, 91
566 \\ mr %[ptr], 3
567 \\ mr %[len], 4
568 \\ sc
569 \\ li 0, 1
570 \\ li 3, 0
571 \\ sc
572 \\ blr
573 ),
574 .riscv64 => (
575 \\ li a7, 215
576 \\ mv a0, %[ptr]
577 \\ mv a1, %[len]
578 \\ ecall
579 \\ li a7, 93
580 \\ mv a0, zero
581 \\ ecall
582 ),
583 else => |cpu_arch| {
584 @compileLog("Unsupported linux arch ", cpu_arch);
585 },
586 };
587
588 asm volatile (
589 unmap_and_exit
590 :
591 : [ptr] "r" (@ptrToInt(self.mapped.ptr)),
592 [len] "r" (self.mapped.len)
593 : "memory"
594 );
595
596 unreachable;
597 }
503598 };
504599
505600 fn spawn(config: SpawnConfig, comptime f: anytype, args: anytype) !Impl {
......@@ -513,10 +608,7 @@ const LinuxThreadImpl = struct {
513608 defer switch (self.thread.completion.swap(.completed, .SeqCst)) {
514609 .running => {},
515610 .completed => unreachable,
516 .detached => {
517 const memory = self.thread.mapped;
518 __unmap_and_exit(@ptrToInt(memory.ptr), memory.len);
519 },
611 .detached => self.thread.freeAndExit(),
520612 };
521613 return callFn(f, self.fn_args);
522614 }
......@@ -664,108 +756,6 @@ const LinuxThreadImpl = struct {
664756 }
665757 }
666758 }
667
668 // Calls `munmap(ptr, len)` then `exit(1)` without touching the stack (which lives in `ptr`).
669 // Ported over from musl libc's pthread detached implementation (`__unmapself`).
670 extern fn __unmap_and_exit(ptr: usize, len: usize) callconv(.C) noreturn;
671 comptime {
672 if (target.os.tag == .linux) {
673 asm (switch (target.cpu.arch) {
674 .i386 => (
675 \\.text
676 \\.global __unmap_and_exit
677 \\.type __unmap_and_exit, @function
678 \\__unmap_and_exit:
679 \\ movl $91, %eax
680 \\ movl 4(%esp), %ebx
681 \\ movl 8(%esp), %ecx
682 \\ int $128
683 \\ xorl %ebx, %ebx
684 \\ movl $1, %eax
685 \\ int $128
686 ),
687 .x86_64 => (
688 \\.text
689 \\.global __unmap_and_exit
690 \\.type __unmap_and_exit, @function
691 \\__unmap_and_exit:
692 \\ movl $11, %eax
693 \\ syscall
694 \\ xor %rdi, %rdi
695 \\ movl $60, %eax
696 \\ syscall
697 ),
698 .arm, .armeb, .thumb, .thumbeb => (
699 \\.syntax unified
700 \\.text
701 \\.global __unmap_and_exit
702 \\.type __unmap_and_exit, %function
703 \\__unmap_and_exit:
704 \\ mov r7, #91
705 \\ svc 0
706 \\ mov r7, #1
707 \\ svc 0
708 ),
709 .aarch64, .aarch64_be, .aarch64_32 => (
710 \\.global __unmap_and_exit
711 \\.type __unmap_and_exit, %function
712 \\__unmap_and_exit:
713 \\ mov x8, #215
714 \\ svc 0
715 \\ mov x8, #93
716 \\ svc 0
717 ),
718 .mips,
719 .mipsel,
720 => (
721 \\.set noreorder
722 \\.global __unmap_and_exit
723 \\.type __unmap_and_exit,@function
724 \\__unmap_and_exit:
725 \\ move $sp, $25
726 \\ li $2, 4091
727 \\ syscall
728 \\ li $4, 0
729 \\ li $2, 4001
730 \\ syscall
731 ),
732 .mips64, .mips64el => (
733 \\.set noreorder
734 \\.global __unmap_and_exit
735 \\.type __unmap_and_exit, @function
736 \\__unmap_and_exit:
737 \\ li $2, 4091
738 \\ syscall
739 \\ li $4, 0
740 \\ li $2, 4001
741 \\ syscall
742 ),
743 .powerpc, .powerpc64, .powerpc64le => (
744 \\.text
745 \\.global __unmap_and_exit
746 \\.type __unmap_and_exit, %function
747 \\__unmap_and_exit:
748 \\ li 0, 91
749 \\ sc
750 \\ li 0, 1
751 \\ sc
752 \\ blr
753 ),
754 .riscv64 => (
755 \\.global __unmap_and_exit
756 \\.type __unmap_and_exit, %function
757 \\__unmap_and_exit:
758 \\ li a7, 215
759 \\ ecall
760 \\ li a7, 93
761 \\ ecall
762 ),
763 else => |cpu_arch| {
764 @compileLog("linux arch", cpu_arch, "is not supported");
765 },
766 });
767 }
768 }
769759};
770760
771761test "std.Thread" {