Commit 998e25a01e

Andrew Kelley <superjoe30@gmail.com>
2018-04-29 05:47:39
pthread support working
1 parent a344cb0
src/all_types.hpp
@@ -1486,6 +1486,7 @@ struct CodeGen {
 
     ZigList<LinkLib *> link_libs_list;
     LinkLib *libc_link_lib;
+    LinkLib *pthread_link_lib;
 
     // add -framework [name] args to linker
     ZigList<Buf *> darwin_frameworks;
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;
 }
 
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");
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));
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);