| ... | ... | @@ -500,6 +500,101 @@ const LinuxThreadImpl = struct { |
| 500 | 500 | child_tid: Atomic(i32) = Atomic(i32).init(1), |
| 501 | 501 | parent_tid: i32 = undefined, |
| 502 | 502 | 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 | } |
| 503 | 598 | }; |
| 504 | 599 | |
| 505 | 600 | fn spawn(config: SpawnConfig, comptime f: anytype, args: anytype) !Impl { |
| ... | ... | @@ -513,10 +608,7 @@ const LinuxThreadImpl = struct { |
| 513 | 608 | defer switch (self.thread.completion.swap(.completed, .SeqCst)) { |
| 514 | 609 | .running => {}, |
| 515 | 610 | .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(), |
| 520 | 612 | }; |
| 521 | 613 | return callFn(f, self.fn_args); |
| 522 | 614 | } |
| ... | ... | @@ -664,108 +756,6 @@ const LinuxThreadImpl = struct { |
| 664 | 756 | } |
| 665 | 757 | } |
| 666 | 758 | } |
| 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 | | } |
| 769 | 759 | }; |
| 770 | 760 | |
| 771 | 761 | test "std.Thread" { |