| ... | ... | @@ -192,14 +192,22 @@ pub fn init(el: *EventLoop, gpa: Allocator) !void { |
| 192 | 192 | }; |
| 193 | 193 | const main_thread = &el.threads.allocated[0]; |
| 194 | 194 | Thread.self = main_thread; |
| 195 | | const idle_stack_end: [*]usize = @alignCast(@ptrCast(allocated_slice[idle_stack_end_offset..].ptr)); |
| 195 | const idle_stack_end: [*]align(16) usize = @alignCast(@ptrCast(allocated_slice[idle_stack_end_offset..].ptr)); |
| 196 | 196 | (idle_stack_end - 1)[0..1].* = .{@intFromPtr(el)}; |
| 197 | 197 | main_thread.* = .{ |
| 198 | 198 | .thread = undefined, |
| 199 | | .idle_context = .{ |
| 200 | | .rsp = @intFromPtr(idle_stack_end - 1), |
| 201 | | .rbp = 0, |
| 202 | | .rip = @intFromPtr(&mainIdleEntry), |
| 199 | .idle_context = switch (builtin.cpu.arch) { |
| 200 | .aarch64 => .{ |
| 201 | .sp = @intFromPtr(idle_stack_end), |
| 202 | .fp = 0, |
| 203 | .pc = @intFromPtr(&mainIdleEntry), |
| 204 | }, |
| 205 | .x86_64 => .{ |
| 206 | .rsp = @intFromPtr(idle_stack_end - 1), |
| 207 | .rbp = 0, |
| 208 | .rip = @intFromPtr(&mainIdleEntry), |
| 209 | }, |
| 210 | else => @compileError("unimplemented architecture"), |
| 203 | 211 | }, |
| 204 | 212 | .current_context = &main_fiber.context, |
| 205 | 213 | .ready_queue = null, |
| ... | ... | @@ -606,6 +614,11 @@ const SwitchMessage = struct { |
| 606 | 614 | }; |
| 607 | 615 | |
| 608 | 616 | const Context = switch (builtin.cpu.arch) { |
| 617 | .aarch64 => extern struct { |
| 618 | sp: u64, |
| 619 | fp: u64, |
| 620 | pc: u64, |
| 621 | }, |
| 609 | 622 | .x86_64 => extern struct { |
| 610 | 623 | rsp: u64, |
| 611 | 624 | rbp: u64, |
| ... | ... | @@ -616,6 +629,102 @@ const Context = switch (builtin.cpu.arch) { |
| 616 | 629 | |
| 617 | 630 | inline fn contextSwitch(message: *const SwitchMessage) *const SwitchMessage { |
| 618 | 631 | return @fieldParentPtr("contexts", switch (builtin.cpu.arch) { |
| 632 | .aarch64 => asm volatile ( |
| 633 | \\ ldp x0, x2, [x1] |
| 634 | \\ ldr x3, [x2, #16] |
| 635 | \\ mov x4, sp |
| 636 | \\ stp x4, fp, [x0] |
| 637 | \\ adr x5, 0f |
| 638 | \\ ldp x4, fp, [x2] |
| 639 | \\ str x5, [x0, #16] |
| 640 | \\ mov sp, x4 |
| 641 | \\ br x3 |
| 642 | \\0: |
| 643 | : [received_message] "={x1}" (-> *const @FieldType(SwitchMessage, "contexts")), |
| 644 | : [message_to_send] "{x1}" (&message.contexts), |
| 645 | : .{ |
| 646 | .x1 = true, |
| 647 | .x2 = true, |
| 648 | .x3 = true, |
| 649 | .x4 = true, |
| 650 | .x5 = true, |
| 651 | .x6 = true, |
| 652 | .x7 = true, |
| 653 | .x8 = true, |
| 654 | .x9 = true, |
| 655 | .x10 = true, |
| 656 | .x11 = true, |
| 657 | .x12 = true, |
| 658 | .x13 = true, |
| 659 | .x14 = true, |
| 660 | .x15 = true, |
| 661 | .x16 = true, |
| 662 | .x17 = true, |
| 663 | .x18 = true, |
| 664 | .x19 = true, |
| 665 | .x20 = true, |
| 666 | .x21 = true, |
| 667 | .x22 = true, |
| 668 | .x23 = true, |
| 669 | .x24 = true, |
| 670 | .x25 = true, |
| 671 | .x26 = true, |
| 672 | .x27 = true, |
| 673 | .x28 = true, |
| 674 | .x30 = true, |
| 675 | .z0 = true, |
| 676 | .z1 = true, |
| 677 | .z2 = true, |
| 678 | .z3 = true, |
| 679 | .z4 = true, |
| 680 | .z5 = true, |
| 681 | .z6 = true, |
| 682 | .z7 = true, |
| 683 | .z8 = true, |
| 684 | .z9 = true, |
| 685 | .z10 = true, |
| 686 | .z11 = true, |
| 687 | .z12 = true, |
| 688 | .z13 = true, |
| 689 | .z14 = true, |
| 690 | .z15 = true, |
| 691 | .z16 = true, |
| 692 | .z17 = true, |
| 693 | .z18 = true, |
| 694 | .z19 = true, |
| 695 | .z20 = true, |
| 696 | .z21 = true, |
| 697 | .z22 = true, |
| 698 | .z23 = true, |
| 699 | .z24 = true, |
| 700 | .z25 = true, |
| 701 | .z26 = true, |
| 702 | .z27 = true, |
| 703 | .z28 = true, |
| 704 | .z29 = true, |
| 705 | .z30 = true, |
| 706 | .z31 = true, |
| 707 | .p0 = true, |
| 708 | .p1 = true, |
| 709 | .p2 = true, |
| 710 | .p3 = true, |
| 711 | .p4 = true, |
| 712 | .p5 = true, |
| 713 | .p6 = true, |
| 714 | .p7 = true, |
| 715 | .p8 = true, |
| 716 | .p9 = true, |
| 717 | .p10 = true, |
| 718 | .p11 = true, |
| 719 | .p12 = true, |
| 720 | .p13 = true, |
| 721 | .p14 = true, |
| 722 | .p15 = true, |
| 723 | .fpcr = true, |
| 724 | .fpsr = true, |
| 725 | .ffr = true, |
| 726 | .memory = true, |
| 727 | }), |
| 619 | 728 | .x86_64 => asm volatile ( |
| 620 | 729 | \\ movq 0(%%rsi), %%rax |
| 621 | 730 | \\ movq 8(%%rsi), %%rcx |
| ... | ... | @@ -629,15 +738,67 @@ inline fn contextSwitch(message: *const SwitchMessage) *const SwitchMessage { |
| 629 | 738 | \\0: |
| 630 | 739 | : [received_message] "={rsi}" (-> *const @FieldType(SwitchMessage, "contexts")), |
| 631 | 740 | : [message_to_send] "{rsi}" (&message.contexts), |
| 632 | | : "rax", "rcx", "rdx", "rbx", "rdi", // |
| 633 | | "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", // |
| 634 | | "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", // |
| 635 | | "zmm0", "zmm1", "zmm2", "zmm3", "zmm4", "zmm5", "zmm6", "zmm7", // |
| 636 | | "zmm8", "zmm9", "zmm10", "zmm11", "zmm12", "zmm13", "zmm14", "zmm15", // |
| 637 | | "zmm16", "zmm17", "zmm18", "zmm19", "zmm20", "zmm21", "zmm22", "zmm23", // |
| 638 | | "zmm24", "zmm25", "zmm26", "zmm27", "zmm28", "zmm29", "zmm30", "zmm31", // |
| 639 | | "fpsr", "fpcr", "mxcsr", "rflags", "dirflag", "memory" |
| 640 | | ), |
| 741 | : .{ |
| 742 | .rax = true, |
| 743 | .rcx = true, |
| 744 | .rdx = true, |
| 745 | .rbx = true, |
| 746 | .rsi = true, |
| 747 | .r8 = true, |
| 748 | .r9 = true, |
| 749 | .r10 = true, |
| 750 | .r11 = true, |
| 751 | .r12 = true, |
| 752 | .r13 = true, |
| 753 | .r14 = true, |
| 754 | .r15 = true, |
| 755 | .mm0 = true, |
| 756 | .mm1 = true, |
| 757 | .mm2 = true, |
| 758 | .mm3 = true, |
| 759 | .mm4 = true, |
| 760 | .mm5 = true, |
| 761 | .mm6 = true, |
| 762 | .mm7 = true, |
| 763 | .zmm0 = true, |
| 764 | .zmm1 = true, |
| 765 | .zmm2 = true, |
| 766 | .zmm3 = true, |
| 767 | .zmm4 = true, |
| 768 | .zmm5 = true, |
| 769 | .zmm6 = true, |
| 770 | .zmm7 = true, |
| 771 | .zmm8 = true, |
| 772 | .zmm9 = true, |
| 773 | .zmm10 = true, |
| 774 | .zmm11 = true, |
| 775 | .zmm12 = true, |
| 776 | .zmm13 = true, |
| 777 | .zmm14 = true, |
| 778 | .zmm15 = true, |
| 779 | .zmm16 = true, |
| 780 | .zmm17 = true, |
| 781 | .zmm18 = true, |
| 782 | .zmm19 = true, |
| 783 | .zmm20 = true, |
| 784 | .zmm21 = true, |
| 785 | .zmm22 = true, |
| 786 | .zmm23 = true, |
| 787 | .zmm24 = true, |
| 788 | .zmm25 = true, |
| 789 | .zmm26 = true, |
| 790 | .zmm27 = true, |
| 791 | .zmm28 = true, |
| 792 | .zmm29 = true, |
| 793 | .zmm30 = true, |
| 794 | .zmm31 = true, |
| 795 | .fpsr = true, |
| 796 | .fpcr = true, |
| 797 | .mxcsr = true, |
| 798 | .rflags = true, |
| 799 | .dirflag = true, |
| 800 | .memory = true, |
| 801 | }), |
| 641 | 802 | else => |arch| @compileError("unimplemented architecture: " ++ @tagName(arch)), |
| 642 | 803 | }); |
| 643 | 804 | } |
| ... | ... | @@ -650,6 +811,12 @@ fn mainIdleEntry() callconv(.naked) void { |
| 650 | 811 | : |
| 651 | 812 | : [mainIdle] "X" (&mainIdle), |
| 652 | 813 | ), |
| 814 | .aarch64 => asm volatile ( |
| 815 | \\ ldr x0, [sp, #-8] |
| 816 | \\ b %[mainIdle] |
| 817 | : |
| 818 | : [mainIdle] "X" (&mainIdle), |
| 819 | ), |
| 653 | 820 | else => |arch| @compileError("unimplemented architecture: " ++ @tagName(arch)), |
| 654 | 821 | } |
| 655 | 822 | } |
| ... | ... | @@ -660,6 +827,11 @@ fn fiberEntry() callconv(.naked) void { |
| 660 | 827 | \\ leaq 8(%%rsp), %%rdi |
| 661 | 828 | \\ jmpq *(%%rsp) |
| 662 | 829 | ), |
| 830 | .aarch64 => asm volatile ( |
| 831 | \\ mov x0, sp |
| 832 | \\ ldr x2, [sp, #-8] |
| 833 | \\ br x2 |
| 834 | ), |
| 663 | 835 | else => |arch| @compileError("unimplemented architecture: " ++ @tagName(arch)), |
| 664 | 836 | } |
| 665 | 837 | } |
| ... | ... | @@ -718,7 +890,7 @@ fn async( |
| 718 | 890 | std.log.debug("allocated {*}", .{fiber}); |
| 719 | 891 | |
| 720 | 892 | const closure: *AsyncClosure = .fromFiber(fiber); |
| 721 | | const stack_end: [*]usize = @alignCast(@ptrCast(closure)); |
| 893 | const stack_end: [*]align(16) usize = @alignCast(@ptrCast(closure)); |
| 722 | 894 | (stack_end - 1)[0..1].* = .{@intFromPtr(&AsyncClosure.call)}; |
| 723 | 895 | fiber.* = .{ |
| 724 | 896 | .required_align = {}, |
| ... | ... | @@ -728,6 +900,11 @@ fn async( |
| 728 | 900 | .rbp = 0, |
| 729 | 901 | .rip = @intFromPtr(&fiberEntry), |
| 730 | 902 | }, |
| 903 | .aarch64 => .{ |
| 904 | .sp = @intFromPtr(stack_end), |
| 905 | .fp = 0, |
| 906 | .pc = @intFromPtr(&fiberEntry), |
| 907 | }, |
| 731 | 908 | else => |arch| @compileError("unimplemented architecture: " ++ @tagName(arch)), |
| 732 | 909 | }, |
| 733 | 910 | .awaiter = null, |
| ... | ... | @@ -796,7 +973,7 @@ fn asyncDetached( |
| 796 | 973 | const closure: *DetachedClosure = @ptrFromInt(Fiber.max_context_align.max(.of(DetachedClosure)).backward( |
| 797 | 974 | @intFromPtr(fiber.allocatedEnd()) - Fiber.max_context_size, |
| 798 | 975 | ) - @sizeOf(DetachedClosure)); |
| 799 | | const stack_end: [*]usize = @alignCast(@ptrCast(closure)); |
| 976 | const stack_end: [*]align(16) usize = @alignCast(@ptrCast(closure)); |
| 800 | 977 | (stack_end - 1)[0..1].* = .{@intFromPtr(&DetachedClosure.call)}; |
| 801 | 978 | fiber.* = .{ |
| 802 | 979 | .required_align = {}, |
| ... | ... | @@ -806,6 +983,11 @@ fn asyncDetached( |
| 806 | 983 | .rbp = 0, |
| 807 | 984 | .rip = @intFromPtr(&fiberEntry), |
| 808 | 985 | }, |
| 986 | .aarch64 => .{ |
| 987 | .sp = @intFromPtr(stack_end), |
| 988 | .fp = 0, |
| 989 | .pc = @intFromPtr(&fiberEntry), |
| 990 | }, |
| 809 | 991 | else => |arch| @compileError("unimplemented architecture: " ++ @tagName(arch)), |
| 810 | 992 | }, |
| 811 | 993 | .awaiter = null, |