make pthreads threads work on darwin

darwin pthreads adds a restriction that the stack start and end
must be page aligned
This commit is contained in:
Andrew Kelley 2018-04-29 00:07:32 -04:00
parent 998e25a01e
commit a425420993
2 changed files with 9 additions and 5 deletions

View File

@ -2421,7 +2421,7 @@ pub fn spawnThreadAllocator(allocator: &mem.Allocator, context: var, comptime st
// TODO compile-time call graph analysis to determine stack upper bound
// https://github.com/zig-lang/zig/issues/157
const default_stack_size = 8 * 1024 * 1024;
const stack_bytes = try allocator.alloc(u8, default_stack_size);
const stack_bytes = try allocator.alignedAlloc(u8, os.page_size, default_stack_size);
const thread = try spawnThread(stack_bytes, context, startFn);
thread.allocator = allocator;
return thread;
@ -2431,7 +2431,7 @@ pub fn spawnThreadAllocator(allocator: &mem.Allocator, context: var, comptime st
/// fn startFn(@typeOf(context)) T
/// where T is u8, noreturn, void, or !void
/// caller must call wait on the returned thread
pub fn spawnThread(stack: []u8, context: var, comptime startFn: var) SpawnThreadError!&Thread {
pub fn spawnThread(stack: []align(os.page_size) u8, context: var, comptime startFn: var) SpawnThreadError!&Thread {
const Context = @typeOf(context);
comptime assert(@ArgType(@typeOf(startFn), 0) == Context);
@ -2481,8 +2481,12 @@ pub fn spawnThread(stack: []u8, context: var, comptime startFn: var) SpawnThread
if (c.pthread_attr_init(&attr) != 0) return SpawnThreadError.SystemResources;
defer assert(c.pthread_attr_destroy(&attr) == 0);
// align to page
stack_end -= stack_end % os.page_size;
const stack_size = stack_end - @ptrToInt(stack.ptr);
if (c.pthread_attr_setstack(&attr, @ptrCast(&c_void, stack.ptr), stack_size) != 0) {
const setstack_err = c.pthread_attr_setstack(&attr, @ptrCast(&c_void, stack.ptr), stack_size);
if (setstack_err != 0) {
return SpawnThreadError.StackTooSmall; // pthreads requires at least 16384 bytes
}

View File

@ -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: [20 * 1024]u8 = undefined;
var stack2: [20 * 1024]u8 = undefined;
var stack1: [20 * 1024]u8 align(os.page_size) = undefined;
var stack2: [20 * 1024]u8 align(os.page_size) = undefined;
const thread2 = try std.os.spawnThread(stack1[0..], &shared_ctx, start2);
const thread3 = try std.os.spawnThread(stack2[0..], &shared_ctx, start2);