From 998e25a01e8b3ada235aee4a9f785a7454de4b3f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 28 Apr 2018 23:47:39 -0400 Subject: [PATCH] pthread support working --- src/all_types.hpp | 1 + src/analyze.cpp | 8 ++++++++ src/codegen.cpp | 2 ++ std/os/index.zig | 14 ++++++++------ std/os/test.zig | 4 ++-- 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/all_types.hpp b/src/all_types.hpp index d1b2ad61d..f08b870b3 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1486,6 +1486,7 @@ struct CodeGen { ZigList link_libs_list; LinkLib *libc_link_lib; + LinkLib *pthread_link_lib; // add -framework [name] args to linker ZigList darwin_frameworks; diff --git a/src/analyze.cpp b/src/analyze.cpp index 1ecfe32f4..8a9d23679 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -6049,10 +6049,15 @@ LinkLib *create_link_lib(Buf *name) { LinkLib *add_link_lib(CodeGen *g, Buf *name) { bool is_libc = buf_eql_str(name, "c"); + bool is_pthread = buf_eql_str(name, "pthread"); if (is_libc && g->libc_link_lib != nullptr) return g->libc_link_lib; + if (is_pthread && g->pthread_link_lib != nullptr) { + return g->pthread_link_lib; + } + for (size_t i = 0; i < g->link_libs_list.length; i += 1) { LinkLib *existing_lib = g->link_libs_list.at(i); if (buf_eql_buf(existing_lib->name, name)) { @@ -6066,6 +6071,9 @@ LinkLib *add_link_lib(CodeGen *g, Buf *name) { if (is_libc) g->libc_link_lib = link_lib; + if (is_pthread) + g->pthread_link_lib = link_lib; + return link_lib; } diff --git a/src/codegen.cpp b/src/codegen.cpp index 2d8c385f4..9f064d5f1 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -145,6 +145,7 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out { g->libc_link_lib = create_link_lib(buf_create_from_str("c")); g->link_libs_list.append(g->libc_link_lib); + g->pthread_link_lib = create_link_lib(buf_create_from_str("pthread")); } return g; @@ -6373,6 +6374,7 @@ static void define_builtin_compile_vars(CodeGen *g) { buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt); buf_appendf(contents, "pub const mode = %s;\n", build_mode_to_str(g->build_mode)); buf_appendf(contents, "pub const link_libc = %s;\n", bool_to_str(g->libc_link_lib != nullptr)); + buf_appendf(contents, "pub const link_pthread = %s;\n", bool_to_str(g->pthread_link_lib != nullptr)); buf_appendf(contents, "pub const have_error_return_tracing = %s;\n", bool_to_str(g->have_err_ret_tracing)); buf_appendf(contents, "pub const __zig_test_fn_slice = {}; // overwritten later\n"); diff --git a/std/os/index.zig b/std/os/index.zig index 3669dca19..fa1cc418a 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -2352,12 +2352,11 @@ pub const Thread = struct { stack: []u8, pthread_handle: pthread_t, - pub const use_pthreads = is_posix and builtin.link_libc; - const pthread_t = if (use_pthreads) c.pthread_t else void; - const pid_t = if (!use_pthreads) i32 else void; + const pthread_t = if (builtin.link_pthread) c.pthread_t else void; + const pid_t = if (!builtin.link_pthread) i32 else void; pub fn wait(self: &const Thread) void { - if (use_pthreads) { + if (builtin.link_pthread) { const err = c.pthread_join(self.pthread_handle, null); switch (err) { 0 => {}, @@ -2407,6 +2406,9 @@ pub const SpawnThreadError = error { /// be copied. SystemResources, + /// pthreads requires at least 16384 bytes of stack space + StackTooSmall, + Unexpected, }; @@ -2473,7 +2475,7 @@ pub fn spawnThread(stack: []u8, context: var, comptime startFn: var) SpawnThread if (builtin.os == builtin.Os.windows) { // use windows API directly @compileError("TODO support spawnThread for Windows"); - } else if (Thread.use_pthreads) { + } else if (builtin.link_pthread) { // use pthreads var attr: c.pthread_attr_t = undefined; if (c.pthread_attr_init(&attr) != 0) return SpawnThreadError.SystemResources; @@ -2481,7 +2483,7 @@ pub fn spawnThread(stack: []u8, context: var, comptime startFn: var) SpawnThread const stack_size = stack_end - @ptrToInt(stack.ptr); if (c.pthread_attr_setstack(&attr, @ptrCast(&c_void, stack.ptr), stack_size) != 0) { - return SpawnThreadError.SystemResources; + return SpawnThreadError.StackTooSmall; // pthreads requires at least 16384 bytes } const err = c.pthread_create(&thread_ptr.pthread_handle, &attr, MainFuncs.posixThreadMain, @intToPtr(&c_void, arg)); diff --git a/std/os/test.zig b/std/os/test.zig index 9a155c027..87486bde4 100644 --- a/std/os/test.zig +++ b/std/os/test.zig @@ -57,8 +57,8 @@ test "spawn threads" { const thread1 = try std.os.spawnThreadAllocator(&direct_allocator.allocator, {}, start1); const thread4 = try std.os.spawnThreadAllocator(&direct_allocator.allocator, &shared_ctx, start2); - var stack1: [1024]u8 = undefined; - var stack2: [1024]u8 = undefined; + var stack1: [20 * 1024]u8 = undefined; + var stack2: [20 * 1024]u8 = undefined; const thread2 = try std.os.spawnThread(stack1[0..], &shared_ctx, start2); const thread3 = try std.os.spawnThread(stack2[0..], &shared_ctx, start2);