| ... | @@ -798,6 +798,7 @@ fn checkCancel(t: *Threaded) error{Canceled}!void { | ... | @@ -798,6 +798,7 @@ fn checkCancel(t: *Threaded) error{Canceled}!void { |
| 798 | | 798 | |
| 799 | fn mutexLock(userdata: ?*anyopaque, prev_state: Io.Mutex.State, mutex: *Io.Mutex) Io.Cancelable!void { | 799 | fn mutexLock(userdata: ?*anyopaque, prev_state: Io.Mutex.State, mutex: *Io.Mutex) Io.Cancelable!void { |
| 800 | if (builtin.single_threaded) unreachable; // Interface should have prevented this. | 800 | if (builtin.single_threaded) unreachable; // Interface should have prevented this. |
| | 801 | if (native_os == .netbsd) @panic("TODO"); |
| 801 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 802 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 802 | if (prev_state == .contended) { | 803 | if (prev_state == .contended) { |
| 803 | try futexWait(t, @ptrCast(&mutex.state), @intFromEnum(Io.Mutex.State.contended)); | 804 | try futexWait(t, @ptrCast(&mutex.state), @intFromEnum(Io.Mutex.State.contended)); |
| ... | @@ -809,6 +810,7 @@ fn mutexLock(userdata: ?*anyopaque, prev_state: Io.Mutex.State, mutex: *Io.Mutex | ... | @@ -809,6 +810,7 @@ fn mutexLock(userdata: ?*anyopaque, prev_state: Io.Mutex.State, mutex: *Io.Mutex |
| 809 | | 810 | |
| 810 | fn mutexLockUncancelable(userdata: ?*anyopaque, prev_state: Io.Mutex.State, mutex: *Io.Mutex) void { | 811 | fn mutexLockUncancelable(userdata: ?*anyopaque, prev_state: Io.Mutex.State, mutex: *Io.Mutex) void { |
| 811 | if (builtin.single_threaded) unreachable; // Interface should have prevented this. | 812 | if (builtin.single_threaded) unreachable; // Interface should have prevented this. |
| | 813 | if (native_os == .netbsd) @panic("TODO"); |
| 812 | _ = userdata; | 814 | _ = userdata; |
| 813 | if (prev_state == .contended) { | 815 | if (prev_state == .contended) { |
| 814 | futexWaitUncancelable(@ptrCast(&mutex.state), @intFromEnum(Io.Mutex.State.contended)); | 816 | futexWaitUncancelable(@ptrCast(&mutex.state), @intFromEnum(Io.Mutex.State.contended)); |
| ... | @@ -820,6 +822,7 @@ fn mutexLockUncancelable(userdata: ?*anyopaque, prev_state: Io.Mutex.State, mute | ... | @@ -820,6 +822,7 @@ fn mutexLockUncancelable(userdata: ?*anyopaque, prev_state: Io.Mutex.State, mute |
| 820 | | 822 | |
| 821 | fn mutexUnlock(userdata: ?*anyopaque, prev_state: Io.Mutex.State, mutex: *Io.Mutex) void { | 823 | fn mutexUnlock(userdata: ?*anyopaque, prev_state: Io.Mutex.State, mutex: *Io.Mutex) void { |
| 822 | if (builtin.single_threaded) unreachable; // Interface should have prevented this. | 824 | if (builtin.single_threaded) unreachable; // Interface should have prevented this. |
| | 825 | if (native_os == .netbsd) @panic("TODO"); |
| 823 | _ = userdata; | 826 | _ = userdata; |
| 824 | _ = prev_state; | 827 | _ = prev_state; |
| 825 | if (@atomicRmw(Io.Mutex.State, &mutex.state, .Xchg, .unlocked, .release) == .contended) { | 828 | if (@atomicRmw(Io.Mutex.State, &mutex.state, .Xchg, .unlocked, .release) == .contended) { |
| ... | @@ -829,6 +832,7 @@ fn mutexUnlock(userdata: ?*anyopaque, prev_state: Io.Mutex.State, mutex: *Io.Mut | ... | @@ -829,6 +832,7 @@ fn mutexUnlock(userdata: ?*anyopaque, prev_state: Io.Mutex.State, mutex: *Io.Mut |
| 829 | | 832 | |
| 830 | fn conditionWaitUncancelable(userdata: ?*anyopaque, cond: *Io.Condition, mutex: *Io.Mutex) void { | 833 | fn conditionWaitUncancelable(userdata: ?*anyopaque, cond: *Io.Condition, mutex: *Io.Mutex) void { |
| 831 | if (builtin.single_threaded) unreachable; // Deadlock. | 834 | if (builtin.single_threaded) unreachable; // Deadlock. |
| | 835 | if (native_os == .netbsd) @panic("TODO"); |
| 832 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 836 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 833 | const t_io = ioBasic(t); | 837 | const t_io = ioBasic(t); |
| 834 | comptime assert(@TypeOf(cond.state) == u64); | 838 | comptime assert(@TypeOf(cond.state) == u64); |
| ... | @@ -860,6 +864,7 @@ fn conditionWaitUncancelable(userdata: ?*anyopaque, cond: *Io.Condition, mutex: | ... | @@ -860,6 +864,7 @@ fn conditionWaitUncancelable(userdata: ?*anyopaque, cond: *Io.Condition, mutex: |
| 860 | | 864 | |
| 861 | fn conditionWait(userdata: ?*anyopaque, cond: *Io.Condition, mutex: *Io.Mutex) Io.Cancelable!void { | 865 | fn conditionWait(userdata: ?*anyopaque, cond: *Io.Condition, mutex: *Io.Mutex) Io.Cancelable!void { |
| 862 | if (builtin.single_threaded) unreachable; // Deadlock. | 866 | if (builtin.single_threaded) unreachable; // Deadlock. |
| | 867 | if (native_os == .netbsd) @panic("TODO"); |
| 863 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 868 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 864 | const t_io = ioBasic(t); | 869 | const t_io = ioBasic(t); |
| 865 | comptime assert(@TypeOf(cond.state) == u64); | 870 | comptime assert(@TypeOf(cond.state) == u64); |
| ... | @@ -960,6 +965,7 @@ fn conditionWake(userdata: ?*anyopaque, cond: *Io.Condition, wake: Io.Condition. | ... | @@ -960,6 +965,7 @@ fn conditionWake(userdata: ?*anyopaque, cond: *Io.Condition, wake: Io.Condition. |
| 960 | // - T2: UPDATE(&state, signal) + FUTEX_WAKE(&epoch) | 965 | // - T2: UPDATE(&state, signal) + FUTEX_WAKE(&epoch) |
| 961 | // - T1: s & signals == 0 -> FUTEX_WAIT(&epoch, e) (missed both epoch change and state change) | 966 | // - T1: s & signals == 0 -> FUTEX_WAIT(&epoch, e) (missed both epoch change and state change) |
| 962 | _ = cond_epoch.fetchAdd(1, .release); | 967 | _ = cond_epoch.fetchAdd(1, .release); |
| | 968 | if (native_os == .netbsd) @panic("TODO"); |
| 963 | futexWake(cond_epoch, to_wake); | 969 | futexWake(cond_epoch, to_wake); |
| 964 | return; | 970 | return; |
| 965 | }; | 971 | }; |