| author | |
| committer | |
| log | 61cd38e8ace66de64b2d3e53b2ebc327a979c4ef |
| tree | cc271bb44627f163be2778fb16bf43ed744c6c98 |
| parent | 9b177a7d21250b82cd18677c5c71ab04e431120d |
| signature |
* and remove their mingw, musl and wasi implementations17 files changed, 98 insertions(+), 151 deletions(-)
lib/c.zig+1| ... | @@ -68,6 +68,7 @@ comptime { | ... | @@ -68,6 +68,7 @@ comptime { |
| 68 | _ = @import("c/malloc.zig"); | 68 | _ = @import("c/malloc.zig"); |
| 69 | } | 69 | } |
| 70 | _ = @import("c/math.zig"); | 70 | _ = @import("c/math.zig"); |
| 71 | _ = @import("c/pthread.zig"); | ||
| 71 | _ = @import("c/search.zig"); | 72 | _ = @import("c/search.zig"); |
| 72 | _ = @import("c/stdlib.zig"); | 73 | _ = @import("c/stdlib.zig"); |
| 73 | _ = @import("c/string.zig"); | 74 | _ = @import("c/string.zig"); |
lib/c/pthread.zig created+57| ... | @@ -0,0 +1,57 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | const c = std.c; | ||
| 5 | |||
| 6 | const symbol = @import("../c.zig").symbol; | ||
| 7 | |||
| 8 | comptime { | ||
| 9 | if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC() or builtin.target.isMinGW()) { | ||
| 10 | symbol(&pthread_spin_init, "pthread_spin_init"); | ||
| 11 | symbol(&pthread_spin_destroy, "pthread_spin_destroy"); | ||
| 12 | symbol(&pthread_spin_trylock, "pthread_spin_trylock"); | ||
| 13 | symbol(&pthread_spin_lock, "pthread_spin_lock"); | ||
| 14 | symbol(&pthread_spin_unlock, "pthread_spin_unlock"); | ||
| 15 | } | ||
| 16 | } | ||
| 17 | |||
| 18 | const SpinLock = enum(c.pthread_spinlock_t) { | ||
| 19 | unlocked = if (builtin.target.isMinGW()) -1 else 0, | ||
| 20 | locked = if (builtin.target.isMinGW()) 0 else @intFromEnum(c.E.BUSY), | ||
| 21 | }; | ||
| 22 | |||
| 23 | fn pthread_spin_init(s: *c.pthread_spinlock_t, pshared: c_int) callconv(.c) c_int { | ||
| 24 | _ = pshared; | ||
| 25 | const spin: *SpinLock = @ptrCast(s); | ||
| 26 | spin.* = .unlocked; | ||
| 27 | return 0; | ||
| 28 | } | ||
| 29 | |||
| 30 | fn pthread_spin_destroy(s: *c.pthread_spinlock_t) callconv(.c) c_int { | ||
| 31 | const spin: *SpinLock = @ptrCast(s); | ||
| 32 | spin.* = undefined; | ||
| 33 | return 0; | ||
| 34 | } | ||
| 35 | |||
| 36 | fn pthread_spin_trylock(s: *c.pthread_spinlock_t) callconv(.c) c_int { | ||
| 37 | const spin: *SpinLock = @ptrCast(s); | ||
| 38 | return if (@cmpxchgStrong(SpinLock, spin, .unlocked, .locked, .acquire, .monotonic)) |_| @intFromEnum(c.E.BUSY) else 0; | ||
| 39 | } | ||
| 40 | |||
| 41 | fn pthread_spin_lock(s: *c.pthread_spinlock_t) callconv(.c) c_int { | ||
| 42 | const spin: *SpinLock = @ptrCast(s); | ||
| 43 | if (builtin.single_threaded and @atomicLoad(SpinLock, spin, .monotonic) == .locked) return @intFromEnum(c.E.DEADLK); | ||
| 44 | |||
| 45 | while (@cmpxchgWeak(SpinLock, spin, .unlocked, .locked, .acquire, .monotonic)) |_| { | ||
| 46 | std.atomic.spinLoopHint(); | ||
| 47 | } | ||
| 48 | return 0; | ||
| 49 | } | ||
| 50 | |||
| 51 | fn pthread_spin_unlock(s: *c.pthread_spinlock_t) callconv(.c) c_int { | ||
| 52 | const spin: *SpinLock = @ptrCast(s); | ||
| 53 | |||
| 54 | // "The results are undefined if the lock is not held by the calling thread" | ||
| 55 | std.debug.assert(@atomicRmw(SpinLock, spin, .Xchg, .unlocked, .release) == .locked); | ||
| 56 | return 0; | ||
| 57 | } | ||
lib/libc/mingw/winpthreads/spinlock.c deleted-82| ... | @@ -1,82 +0,0 @@ | ||
| 1 | /* | ||
| 2 | Copyright (c) 2013 mingw-w64 project | ||
| 3 | Copyright (c) 2015 Intel Corporation | ||
| 4 | |||
| 5 | Permission is hereby granted, free of charge, to any person obtaining a | ||
| 6 | copy of this software and associated documentation files (the "Software"), | ||
| 7 | to deal in the Software without restriction, including without limitation | ||
| 8 | the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 9 | and/or sell copies of the Software, and to permit persons to whom the | ||
| 10 | Software is furnished to do so, subject to the following conditions: | ||
| 11 | |||
| 12 | The above copyright notice and this permission notice shall be included in | ||
| 13 | all copies or substantial portions of the Software. | ||
| 14 | |||
| 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
| 21 | DEALINGS IN THE SOFTWARE. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #ifdef HAVE_CONFIG_H | ||
| 25 | #include "config.h" | ||
| 26 | #endif | ||
| 27 | |||
| 28 | #define WIN32_LEAN_AND_MEAN | ||
| 29 | #include <windows.h> | ||
| 30 | |||
| 31 | /* public header files */ | ||
| 32 | #include "pthread.h" | ||
| 33 | /* internal header files */ | ||
| 34 | #include "misc.h" | ||
| 35 | |||
| 36 | /* We use the pthread_spinlock_t itself as a lock: | ||
| 37 | -1 is free, 0 is locked. | ||
| 38 | (This is dictated by PTHREAD_SPINLOCK_INITIALIZER, which we can't change | ||
| 39 | without breaking binary compatibility.) */ | ||
| 40 | typedef intptr_t spinlock_word_t; | ||
| 41 | |||
| 42 | int | ||
| 43 | pthread_spin_init (pthread_spinlock_t *lock, int pshared) | ||
| 44 | { | ||
| 45 | spinlock_word_t *lk = (spinlock_word_t *)lock; | ||
| 46 | *lk = -1; | ||
| 47 | return 0; | ||
| 48 | } | ||
| 49 | |||
| 50 | |||
| 51 | int | ||
| 52 | pthread_spin_destroy (pthread_spinlock_t *lock) | ||
| 53 | { | ||
| 54 | return 0; | ||
| 55 | } | ||
| 56 | |||
| 57 | int | ||
| 58 | pthread_spin_lock (pthread_spinlock_t *lock) | ||
| 59 | { | ||
| 60 | volatile spinlock_word_t *lk = (volatile spinlock_word_t *)lock; | ||
| 61 | while (unlikely(InterlockedExchangePointer((PVOID volatile *)lk, 0) == 0)) | ||
| 62 | do { | ||
| 63 | YieldProcessor(); | ||
| 64 | } while (*lk == 0); | ||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | |||
| 68 | int | ||
| 69 | pthread_spin_trylock (pthread_spinlock_t *lock) | ||
| 70 | { | ||
| 71 | spinlock_word_t *lk = (spinlock_word_t *)lock; | ||
| 72 | return InterlockedExchangePointer((PVOID volatile *)lk, 0) == 0 ? EBUSY : 0; | ||
| 73 | } | ||
| 74 | |||
| 75 | |||
| 76 | int | ||
| 77 | pthread_spin_unlock (pthread_spinlock_t *lock) | ||
| 78 | { | ||
| 79 | volatile spinlock_word_t *lk = (volatile spinlock_word_t *)lock; | ||
| 80 | *lk = -1; | ||
| 81 | return 0; | ||
| 82 | } | ||
lib/libc/musl/src/thread/pthread_spin_destroy.c deleted-6| ... | @@ -1,6 +0,0 @@ | ||
| 1 | #include "pthread_impl.h" | ||
| 2 | |||
| 3 | int pthread_spin_destroy(pthread_spinlock_t *s) | ||
| 4 | { | ||
| 5 | 	return 0; | ||
| 6 | } | ||
lib/libc/musl/src/thread/pthread_spin_init.c deleted-6| ... | @@ -1,6 +0,0 @@ | ||
| 1 | #include "pthread_impl.h" | ||
| 2 | |||
| 3 | int pthread_spin_init(pthread_spinlock_t *s, int shared) | ||
| 4 | { | ||
| 5 | 	return *s = 0; | ||
| 6 | } | ||
lib/libc/musl/src/thread/pthread_spin_lock.c deleted-8| ... | @@ -1,8 +0,0 @@ | ||
| 1 | #include "pthread_impl.h" | ||
| 2 | #include <errno.h> | ||
| 3 | |||
| 4 | int pthread_spin_lock(pthread_spinlock_t *s) | ||
| 5 | { | ||
| 6 | 	while (*(volatile int *)s || a_cas(s, 0, EBUSY)) a_spin(); | ||
| 7 | 	return 0; | ||
| 8 | } | ||
lib/libc/musl/src/thread/pthread_spin_trylock.c deleted-7| ... | @@ -1,7 +0,0 @@ | ||
| 1 | #include "pthread_impl.h" | ||
| 2 | #include <errno.h> | ||
| 3 | |||
| 4 | int pthread_spin_trylock(pthread_spinlock_t *s) | ||
| 5 | { | ||
| 6 | 	return a_cas(s, 0, EBUSY); | ||
| 7 | } | ||
lib/libc/musl/src/thread/pthread_spin_unlock.c deleted-7| ... | @@ -1,7 +0,0 @@ | ||
| 1 | #include "pthread_impl.h" | ||
| 2 | |||
| 3 | int pthread_spin_unlock(pthread_spinlock_t *s) | ||
| 4 | { | ||
| 5 | 	a_store(s, 0); | ||
| 6 | 	return 0; | ||
| 7 | } | ||
lib/libc/wasi/thread-stub/pthread_spin_lock.c deleted-8| ... | @@ -1,8 +0,0 @@ | ||
| 1 | #include "pthread_impl.h" | ||
| 2 | |||
| 3 | int pthread_spin_lock(pthread_spinlock_t *s) | ||
| 4 | { | ||
| 5 | 	if (*s) return EDEADLK; | ||
| 6 | 	*s = 1; | ||
| 7 | 	return 0; | ||
| 8 | } | ||
lib/libc/wasi/thread-stub/pthread_spin_trylock.c deleted-8| ... | @@ -1,8 +0,0 @@ | ||
| 1 | #include "pthread_impl.h" | ||
| 2 | |||
| 3 | int pthread_spin_trylock(pthread_spinlock_t *s) | ||
| 4 | { | ||
| 5 | 	if (*s) return EBUSY; | ||
| 6 | 	*s = 1; | ||
| 7 | 	return 0; | ||
| 8 | } | ||
lib/libc/wasi/thread-stub/pthread_spin_unlock.c deleted-7| ... | @@ -1,7 +0,0 @@ | ||
| 1 | #include "pthread_impl.h" | ||
| 2 | |||
| 3 | int pthread_spin_unlock(pthread_spinlock_t *s) | ||
| 4 | { | ||
| 5 | 	*s = 0; | ||
| 6 | 	return 0; | ||
| 7 | } | ||
lib/std/c.zig+19-1| ... | @@ -7898,6 +7898,12 @@ pub const Stat = switch (native_os) { | ... | @@ -7898,6 +7898,12 @@ pub const Stat = switch (native_os) { |
| 7898 | else => void, | 7898 | else => void, |
| 7899 | }; | 7899 | }; |
| 7900 | 7900 | ||
| 7901 | pub const pthread_spinlock_t = switch (native_os) { | ||
| 7902 | .openbsd => openbsd.pthread_spinlock_t, | ||
| 7903 | .windows => isize, | ||
| 7904 | else => c_int, | ||
| 7905 | }; | ||
| 7906 | |||
| 7901 | pub const pthread_mutex_t = switch (native_os) { | 7907 | pub const pthread_mutex_t = switch (native_os) { |
| 7902 | .linux => extern struct { | 7908 | .linux => extern struct { |
| 7903 | data: [data_len]u8 align(@alignOf(usize)) = [_]u8{0} ** data_len, | 7909 | data: [data_len]u8 align(@alignOf(usize)) = [_]u8{0} ** data_len, |
| ... | @@ -10956,6 +10962,19 @@ pub extern "c" fn dn_expand( | ... | @@ -10956,6 +10962,19 @@ pub extern "c" fn dn_expand( |
| 10956 | length: c_int, | 10962 | length: c_int, |
| 10957 | ) c_int; | 10963 | ) c_int; |
| 10958 | 10964 | ||
| 10965 | pub const PTHREAD_PROCESS_PRIVATE: c_int = if (native_os.isDarwin()) | ||
| 10966 | 2 | ||
| 10967 | else | ||
| 10968 | 0; | ||
| 10969 | |||
| 10970 | pub const PTHREAD_PROCESS_SHARED: c_int = 1; | ||
| 10971 | |||
| 10972 | pub extern "c" fn pthread_spin_init(spin: *pthread_spinlock_t, pshared: c_int) E; | ||
| 10973 | pub extern "c" fn pthread_spin_lock(spin: *pthread_spinlock_t) E; | ||
| 10974 | pub extern "c" fn pthread_spin_unlock(spin: *pthread_spinlock_t) E; | ||
| 10975 | pub extern "c" fn pthread_spin_trylock(spin: *pthread_spinlock_t) E; | ||
| 10976 | pub extern "c" fn pthread_spin_destroy(spin: *pthread_spinlock_t) E; | ||
| 10977 | |||
| 10959 | pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = .{}; | 10978 | pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = .{}; |
| 10960 | pub extern "c" fn pthread_mutex_lock(mutex: *pthread_mutex_t) E; | 10979 | pub extern "c" fn pthread_mutex_lock(mutex: *pthread_mutex_t) E; |
| 10961 | pub extern "c" fn pthread_mutex_unlock(mutex: *pthread_mutex_t) E; | 10980 | pub extern "c" fn pthread_mutex_unlock(mutex: *pthread_mutex_t) E; |
| ... | @@ -11268,7 +11287,6 @@ pub const login_getcaptime = openbsd.login_getcaptime; | ... | @@ -11268,7 +11287,6 @@ pub const login_getcaptime = openbsd.login_getcaptime; |
| 11268 | pub const login_getclass = openbsd.login_getclass; | 11287 | pub const login_getclass = openbsd.login_getclass; |
| 11269 | pub const login_getstyle = openbsd.login_getstyle; | 11288 | pub const login_getstyle = openbsd.login_getstyle; |
| 11270 | pub const pledge = openbsd.pledge; | 11289 | pub const pledge = openbsd.pledge; |
| 11271 | pub const pthread_spinlock_t = openbsd.pthread_spinlock_t; | ||
| 11272 | pub const pw_dup = openbsd.pw_dup; | 11290 | pub const pw_dup = openbsd.pw_dup; |
| 11273 | pub const setclasscontext = openbsd.setclasscontext; | 11291 | pub const setclasscontext = openbsd.setclasscontext; |
| 11274 | pub const setpassent = openbsd.setpassent; | 11292 | pub const setpassent = openbsd.setpassent; |
src/libs/mingw.zig-1| ... | @@ -913,7 +913,6 @@ const mingw32_winpthreads_src = [_][]const u8{ | ... | @@ -913,7 +913,6 @@ const mingw32_winpthreads_src = [_][]const u8{ |
| 913 | "winpthreads" ++ path.sep_str ++ "rwlock.c", | 913 | "winpthreads" ++ path.sep_str ++ "rwlock.c", |
| 914 | "winpthreads" ++ path.sep_str ++ "sched.c", | 914 | "winpthreads" ++ path.sep_str ++ "sched.c", |
| 915 | "winpthreads" ++ path.sep_str ++ "sem.c", | 915 | "winpthreads" ++ path.sep_str ++ "sem.c", |
| 916 | "winpthreads" ++ path.sep_str ++ "spinlock.c", | ||
| 917 | "winpthreads" ++ path.sep_str ++ "thread.c", | 916 | "winpthreads" ++ path.sep_str ++ "thread.c", |
| 918 | }; | 917 | }; |
| 919 | 918 |
src/libs/musl.zig-5| ... | @@ -1663,11 +1663,6 @@ const src_files = [_][]const u8{ | ... | @@ -1663,11 +1663,6 @@ const src_files = [_][]const u8{ |
| 1663 | "musl/src/thread/pthread_setschedprio.c", | 1663 | "musl/src/thread/pthread_setschedprio.c", |
| 1664 | "musl/src/thread/pthread_setspecific.c", | 1664 | "musl/src/thread/pthread_setspecific.c", |
| 1665 | "musl/src/thread/pthread_sigmask.c", | 1665 | "musl/src/thread/pthread_sigmask.c", |
| 1666 | "musl/src/thread/pthread_spin_destroy.c", | ||
| 1667 | "musl/src/thread/pthread_spin_init.c", | ||
| 1668 | "musl/src/thread/pthread_spin_lock.c", | ||
| 1669 | "musl/src/thread/pthread_spin_trylock.c", | ||
| 1670 | "musl/src/thread/pthread_spin_unlock.c", | ||
| 1671 | "musl/src/thread/pthread_testcancel.c", | 1666 | "musl/src/thread/pthread_testcancel.c", |
| 1672 | "musl/src/thread/riscv32/clone.s", | 1667 | "musl/src/thread/riscv32/clone.s", |
| 1673 | "musl/src/thread/riscv32/__set_thread_area.s", | 1668 | "musl/src/thread/riscv32/__set_thread_area.s", |
src/libs/wasi_libc.zig-5| ... | @@ -939,8 +939,6 @@ const libc_top_half_src_files = [_][]const u8{ | ... | @@ -939,8 +939,6 @@ const libc_top_half_src_files = [_][]const u8{ |
| 939 | "musl/src/thread/pthread_setcancelstate.c", | 939 | "musl/src/thread/pthread_setcancelstate.c", |
| 940 | "musl/src/thread/pthread_setcanceltype.c", | 940 | "musl/src/thread/pthread_setcanceltype.c", |
| 941 | "musl/src/thread/pthread_setspecific.c", | 941 | "musl/src/thread/pthread_setspecific.c", |
| 942 | "musl/src/thread/pthread_spin_destroy.c", | ||
| 943 | "musl/src/thread/pthread_spin_init.c", | ||
| 944 | "musl/src/thread/pthread_testcancel.c", | 942 | "musl/src/thread/pthread_testcancel.c", |
| 945 | "musl/src/thread/thrd_sleep.c", | 943 | "musl/src/thread/thrd_sleep.c", |
| 946 | "musl/src/time/asctime.c", | 944 | "musl/src/time/asctime.c", |
| ... | @@ -1086,9 +1084,6 @@ const libc_top_half_src_files = [_][]const u8{ | ... | @@ -1086,9 +1084,6 @@ const libc_top_half_src_files = [_][]const u8{ |
| 1086 | "wasi/thread-stub/pthread_rwlock_trywrlock.c", | 1084 | "wasi/thread-stub/pthread_rwlock_trywrlock.c", |
| 1087 | "wasi/thread-stub/pthread_rwlock_unlock.c", | 1085 | "wasi/thread-stub/pthread_rwlock_unlock.c", |
| 1088 | "wasi/thread-stub/pthread_rwlock_wrlock.c", | 1086 | "wasi/thread-stub/pthread_rwlock_wrlock.c", |
| 1089 | "wasi/thread-stub/pthread_spin_lock.c", | ||
| 1090 | "wasi/thread-stub/pthread_spin_trylock.c", | ||
| 1091 | "wasi/thread-stub/pthread_spin_unlock.c", | ||
| 1092 | }; | 1087 | }; |
| 1093 | 1088 | ||
| 1094 | const crt1_command_src_file = "wasi/libc-bottom-half/crt/crt1-command.c"; | 1089 | const crt1_command_src_file = "wasi/libc-bottom-half/crt/crt1-command.c"; |
test/c.zig+1| ... | @@ -4,6 +4,7 @@ const std = @import("std"); | ... | @@ -4,6 +4,7 @@ const std = @import("std"); |
| 4 | test { | 4 | test { |
| 5 | _ = @import("c/inttypes.zig"); | 5 | _ = @import("c/inttypes.zig"); |
| 6 | _ = @import("c/math.zig"); | 6 | _ = @import("c/math.zig"); |
| 7 | _ = @import("c/pthread.zig"); | ||
| 7 | _ = @import("c/search.zig"); | 8 | _ = @import("c/search.zig"); |
| 8 | _ = @import("c/stdlib.zig"); | 9 | _ = @import("c/stdlib.zig"); |
| 9 | _ = @import("c/string.zig"); | 10 | _ = @import("c/string.zig"); |
test/c/pthread.zig created+20| ... | @@ -0,0 +1,20 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const std = @import("std"); | ||
| 3 | |||
| 4 | const c = std.c; | ||
| 5 | const math = std.math; | ||
| 6 | const testing = std.testing; | ||
| 7 | |||
| 8 | test "pthread_spinlock_t" { | ||
| 9 | if (builtin.target.os.tag.isDarwin()) return; // Darwin doesn't have `pthread_spin_*` | ||
| 10 | |||
| 11 | var spin: c.pthread_spinlock_t = undefined; | ||
| 12 | _ = c.pthread_spin_init(&spin, c.PTHREAD_PROCESS_PRIVATE); | ||
| 13 | defer _ = c.pthread_spin_destroy(&spin); | ||
| 14 | |||
| 15 | try std.testing.expectEqual(.SUCCESS, c.pthread_spin_trylock(&spin)); | ||
| 16 | try std.testing.expectEqual(.SUCCESS, c.pthread_spin_unlock(&spin)); | ||
| 17 | |||
| 18 | try std.testing.expectEqual(.SUCCESS, c.pthread_spin_lock(&spin)); | ||
| 19 | try std.testing.expectEqual(.SUCCESS, c.pthread_spin_unlock(&spin)); | ||
| 20 | } | ||