authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-29 00:07:32-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-29 00:07:32-04:00
loga42542099392cf189b96bdd77ecd88feadfb6382
tree723f625b401ca2bfbe1c343d2f19e472a514ba65
parent998e25a01e8b3ada235aee4a9f785a7454de4b3f

make pthreads threads work on darwin

darwin pthreads adds a restriction that the stack start and end must be page aligned

2 files changed, 9 insertions(+), 5 deletions(-)

std/os/index.zig+7-3
......@@ -2421,7 +2421,7 @@ pub fn spawnThreadAllocator(allocator: &mem.Allocator, context: var, comptime st
24212421 // TODO compile-time call graph analysis to determine stack upper bound
24222422 // https://github.com/zig-lang/zig/issues/157
24232423 const default_stack_size = 8 * 1024 * 1024;
2424 const stack_bytes = try allocator.alloc(u8, default_stack_size);
2424 const stack_bytes = try allocator.alignedAlloc(u8, os.page_size, default_stack_size);
24252425 const thread = try spawnThread(stack_bytes, context, startFn);
24262426 thread.allocator = allocator;
24272427 return thread;
......@@ -2431,7 +2431,7 @@ pub fn spawnThreadAllocator(allocator: &mem.Allocator, context: var, comptime st
24312431/// fn startFn(@typeOf(context)) T
24322432/// where T is u8, noreturn, void, or !void
24332433/// caller must call wait on the returned thread
2434pub fn spawnThread(stack: []u8, context: var, comptime startFn: var) SpawnThreadError!&Thread {
2434pub fn spawnThread(stack: []align(os.page_size) u8, context: var, comptime startFn: var) SpawnThreadError!&Thread {
24352435 const Context = @typeOf(context);
24362436 comptime assert(@ArgType(@typeOf(startFn), 0) == Context);
24372437
......@@ -2481,8 +2481,12 @@ pub fn spawnThread(stack: []u8, context: var, comptime startFn: var) SpawnThread
24812481 if (c.pthread_attr_init(&attr) != 0) return SpawnThreadError.SystemResources;
24822482 defer assert(c.pthread_attr_destroy(&attr) == 0);
24832483
2484 // align to page
2485 stack_end -= stack_end % os.page_size;
2486
24842487 const stack_size = stack_end - @ptrToInt(stack.ptr);
2485 if (c.pthread_attr_setstack(&attr, @ptrCast(&c_void, stack.ptr), stack_size) != 0) {
2488 const setstack_err = c.pthread_attr_setstack(&attr, @ptrCast(&c_void, stack.ptr), stack_size);
2489 if (setstack_err != 0) {
24862490 return SpawnThreadError.StackTooSmall; // pthreads requires at least 16384 bytes
24872491 }
24882492
std/os/test.zig+2-2
......@@ -57,8 +57,8 @@ test "spawn threads" {
5757 const thread1 = try std.os.spawnThreadAllocator(&direct_allocator.allocator, {}, start1);
5858 const thread4 = try std.os.spawnThreadAllocator(&direct_allocator.allocator, &shared_ctx, start2);
5959
60 var stack1: [20 * 1024]u8 = undefined;
61 var stack2: [20 * 1024]u8 = undefined;
60 var stack1: [20 * 1024]u8 align(os.page_size) = undefined;
61 var stack2: [20 * 1024]u8 align(os.page_size) = undefined;
6262
6363 const thread2 = try std.os.spawnThread(stack1[0..], &shared_ctx, start2);
6464 const thread3 = try std.os.spawnThread(stack2[0..], &shared_ctx, start2);