parent
86d1cc8e2f
commit
a25824e033
@ -2518,22 +2518,28 @@ pub const Thread = struct {
|
|||||||
pub const use_pthreads = is_posix and builtin.link_libc;
|
pub const use_pthreads = is_posix and builtin.link_libc;
|
||||||
|
|
||||||
/// An opaque type representing a kernel thread ID.
|
/// An opaque type representing a kernel thread ID.
|
||||||
pub const Id = *@OpaqueType();
|
pub const Id = if (use_pthreads)
|
||||||
|
c.pthread_t
|
||||||
|
else switch (builtin.os) {
|
||||||
|
builtin.Os.linux => i32,
|
||||||
|
builtin.Os.windows => windows.HANDLE,
|
||||||
|
else => @compileError("Unsupported OS"),
|
||||||
|
};
|
||||||
|
|
||||||
pub const Data = if (use_pthreads)
|
pub const Data = if (use_pthreads)
|
||||||
struct {
|
struct {
|
||||||
handle: c.pthread_t,
|
handle: Thread.Id,
|
||||||
stack_addr: usize,
|
stack_addr: usize,
|
||||||
stack_len: usize,
|
stack_len: usize,
|
||||||
}
|
}
|
||||||
else switch (builtin.os) {
|
else switch (builtin.os) {
|
||||||
builtin.Os.linux => struct {
|
builtin.Os.linux => struct {
|
||||||
pid: i32,
|
handle: Thread.Id,
|
||||||
stack_addr: usize,
|
stack_addr: usize,
|
||||||
stack_len: usize,
|
stack_len: usize,
|
||||||
},
|
},
|
||||||
builtin.Os.windows => struct {
|
builtin.Os.windows => struct {
|
||||||
handle: windows.HANDLE,
|
handle: Thread.Id,
|
||||||
alloc_start: *c_void,
|
alloc_start: *c_void,
|
||||||
heap_handle: windows.HANDLE,
|
heap_handle: windows.HANDLE,
|
||||||
},
|
},
|
||||||
@ -2547,26 +2553,17 @@ pub const Thread = struct {
|
|||||||
// storage (https://github.com/ziglang/zig/issues/924), we could
|
// storage (https://github.com/ziglang/zig/issues/924), we could
|
||||||
// memoize it.
|
// memoize it.
|
||||||
if (use_pthreads) {
|
if (use_pthreads) {
|
||||||
return @ptrCast(Thread.Id, c.pthread_self());
|
return c.pthread_self();
|
||||||
} else return switch (builtin.os) {
|
} else return switch (builtin.os) {
|
||||||
builtin.Os.linux =>
|
builtin.Os.linux => linux.getpid(),
|
||||||
@intToPtr(Thread.Id, @bitCast(u32, linux.getpid())),
|
builtin.Os.windows => windows.GetCurrentThread(),
|
||||||
builtin.Os.windows =>
|
|
||||||
@ptrCast(Thread.Id, windows.GetCurrentThread()),
|
|
||||||
else => @compileError("Unsupported OS"),
|
else => @compileError("Unsupported OS"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the ID of this thread object.
|
/// Returns the ID of this thread.
|
||||||
pub fn id(self: *const Thread) Thread.Id {
|
pub fn id(self: *const Thread) Thread.Id {
|
||||||
if (use_pthreads) {
|
return self.data.handle;
|
||||||
return @ptrCast(Thread.Id, self.data.handle);
|
|
||||||
} else return switch (builtin.os) {
|
|
||||||
builtin.Os.linux =>
|
|
||||||
@intToPtr(Thread.Id, @bitCast(u32, self.data.pid)),
|
|
||||||
builtin.Os.windows => @ptrCast(Thread.Id, self.data.handle),
|
|
||||||
else => @compileError("Unsupported OS"),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wait(self: *const Thread) void {
|
pub fn wait(self: *const Thread) void {
|
||||||
@ -2583,9 +2580,9 @@ pub const Thread = struct {
|
|||||||
} else switch (builtin.os) {
|
} else switch (builtin.os) {
|
||||||
builtin.Os.linux => {
|
builtin.Os.linux => {
|
||||||
while (true) {
|
while (true) {
|
||||||
const pid_value = @atomicLoad(i32, &self.data.pid, builtin.AtomicOrder.SeqCst);
|
const pid_value = @atomicLoad(i32, &self.data.handle, builtin.AtomicOrder.SeqCst);
|
||||||
if (pid_value == 0) break;
|
if (pid_value == 0) break;
|
||||||
const rc = linux.futex_wait(@ptrToInt(&self.data.pid), linux.FUTEX_WAIT, pid_value, null);
|
const rc = linux.futex_wait(@ptrToInt(&self.data.handle), linux.FUTEX_WAIT, pid_value, null);
|
||||||
switch (linux.getErrno(rc)) {
|
switch (linux.getErrno(rc)) {
|
||||||
0 => continue,
|
0 => continue,
|
||||||
posix.EINTR => continue,
|
posix.EINTR => continue,
|
||||||
@ -2767,7 +2764,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
|
|||||||
// use linux API directly. TODO use posix.CLONE_SETTLS and initialize thread local storage correctly
|
// use linux API directly. TODO use posix.CLONE_SETTLS and initialize thread local storage correctly
|
||||||
const flags = posix.CLONE_VM | posix.CLONE_FS | posix.CLONE_FILES | posix.CLONE_SIGHAND | posix.CLONE_THREAD | posix.CLONE_SYSVSEM | posix.CLONE_PARENT_SETTID | posix.CLONE_CHILD_CLEARTID | posix.CLONE_DETACHED;
|
const flags = posix.CLONE_VM | posix.CLONE_FS | posix.CLONE_FILES | posix.CLONE_SIGHAND | posix.CLONE_THREAD | posix.CLONE_SYSVSEM | posix.CLONE_PARENT_SETTID | posix.CLONE_CHILD_CLEARTID | posix.CLONE_DETACHED;
|
||||||
const newtls: usize = 0;
|
const newtls: usize = 0;
|
||||||
const rc = posix.clone(MainFuncs.linuxThreadMain, stack_end, flags, arg, &thread_ptr.data.pid, newtls, &thread_ptr.data.pid);
|
const rc = posix.clone(MainFuncs.linuxThreadMain, stack_end, flags, arg, &thread_ptr.data.handle, newtls, &thread_ptr.data.handle);
|
||||||
const err = posix.getErrno(rc);
|
const err = posix.getErrno(rc);
|
||||||
switch (err) {
|
switch (err) {
|
||||||
0 => return thread_ptr,
|
0 => return thread_ptr,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user