authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-20 15:37:58-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-20 15:37:58-07:00
log1d94a6893689ad1fb8e06308ae51603a6c8708a8
tree4adb4cbf5e6764df65747fb3bae2c1640060eb89
parent10d30838d1887a8585e79ad7a680d3067674c9d9

add an option to compile zig in single-threaded mode

And enable it for Drone CI. I hate to do this, but I need to make progress on other fronts.

5 files changed, 29 insertions(+), 6 deletions(-)

CMakeLists.txt+10
...@@ -75,6 +75,7 @@ set(ZIG_TARGET_TRIPLE "native" CACHE STRING "arch-os-abi to output binaries for"...@@ -75,6 +75,7 @@ set(ZIG_TARGET_TRIPLE "native" CACHE STRING "arch-os-abi to output binaries for"
75set(ZIG_TARGET_MCPU "baseline" CACHE STRING "-mcpu parameter to output binaries for")75set(ZIG_TARGET_MCPU "baseline" CACHE STRING "-mcpu parameter to output binaries for")
76set(ZIG_EXECUTABLE "" CACHE STRING "(when cross compiling) path to already-built zig binary")76set(ZIG_EXECUTABLE "" CACHE STRING "(when cross compiling) path to already-built zig binary")
77set(ZIG_PREFER_LLVM_CONFIG off CACHE BOOL "(when cross compiling) use llvm-config to find target llvm dependencies if needed")77set(ZIG_PREFER_LLVM_CONFIG off CACHE BOOL "(when cross compiling) use llvm-config to find target llvm dependencies if needed")
78set(ZIG_SINGLE_THREADED off CACHE BOOL "limit the zig compiler to use only 1 thread")
7879
79find_package(llvm)80find_package(llvm)
80find_package(clang)81find_package(clang)
...@@ -510,10 +511,13 @@ set(ZIG_STAGE2_SOURCES...@@ -510,10 +511,13 @@ set(ZIG_STAGE2_SOURCES
510 "${CMAKE_SOURCE_DIR}/src/Cache.zig"511 "${CMAKE_SOURCE_DIR}/src/Cache.zig"
511 "${CMAKE_SOURCE_DIR}/src/Compilation.zig"512 "${CMAKE_SOURCE_DIR}/src/Compilation.zig"
512 "${CMAKE_SOURCE_DIR}/src/DepTokenizer.zig"513 "${CMAKE_SOURCE_DIR}/src/DepTokenizer.zig"
514 "${CMAKE_SOURCE_DIR}/src/Event.zig"
513 "${CMAKE_SOURCE_DIR}/src/Module.zig"515 "${CMAKE_SOURCE_DIR}/src/Module.zig"
514 "${CMAKE_SOURCE_DIR}/src/Package.zig"516 "${CMAKE_SOURCE_DIR}/src/Package.zig"
515 "${CMAKE_SOURCE_DIR}/src/RangeSet.zig"517 "${CMAKE_SOURCE_DIR}/src/RangeSet.zig"
518 "${CMAKE_SOURCE_DIR}/src/ThreadPool.zig"
516 "${CMAKE_SOURCE_DIR}/src/TypedValue.zig"519 "${CMAKE_SOURCE_DIR}/src/TypedValue.zig"
520 "${CMAKE_SOURCE_DIR}/src/WaitGroup.zig"
517 "${CMAKE_SOURCE_DIR}/src/astgen.zig"521 "${CMAKE_SOURCE_DIR}/src/astgen.zig"
518 "${CMAKE_SOURCE_DIR}/src/clang.zig"522 "${CMAKE_SOURCE_DIR}/src/clang.zig"
519 "${CMAKE_SOURCE_DIR}/src/clang_options.zig"523 "${CMAKE_SOURCE_DIR}/src/clang_options.zig"
...@@ -713,6 +717,11 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")...@@ -713,6 +717,11 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
713else()717else()
714 set(ZIG1_RELEASE_ARG -OReleaseFast --strip)718 set(ZIG1_RELEASE_ARG -OReleaseFast --strip)
715endif()719endif()
720if(ZIG_SINGLE_THREADED)
721 set(ZIG1_SINGLE_THREADED_ARG "--single-threaded")
722else()
723 set(ZIG1_SINGLE_THREADED_ARG "")
724endif()
716725
717set(BUILD_ZIG1_ARGS726set(BUILD_ZIG1_ARGS
718 "src/stage1.zig"727 "src/stage1.zig"
...@@ -722,6 +731,7 @@ set(BUILD_ZIG1_ARGS...@@ -722,6 +731,7 @@ set(BUILD_ZIG1_ARGS
722 --override-lib-dir "${CMAKE_SOURCE_DIR}/lib"731 --override-lib-dir "${CMAKE_SOURCE_DIR}/lib"
723 "-femit-bin=${ZIG1_OBJECT}"732 "-femit-bin=${ZIG1_OBJECT}"
724 "${ZIG1_RELEASE_ARG}"733 "${ZIG1_RELEASE_ARG}"
734 "${ZIG1_SINGLE_THREADED_ARG}"
725 -lc735 -lc
726 --pkg-begin build_options "${ZIG_CONFIG_ZIG_OUT}"736 --pkg-begin build_options "${ZIG_CONFIG_ZIG_OUT}"
727 --pkg-end737 --pkg-end
ci/drone/linux_script+2-1
...@@ -17,7 +17,8 @@ git config core.abbrev 9...@@ -17,7 +17,8 @@ git config core.abbrev 9
1717
18mkdir build18mkdir build
19cd build19cd build
20cmake .. -DCMAKE_BUILD_TYPE=Release "-DCMAKE_INSTALL_PREFIX=$DISTDIR" -DZIG_STATIC=ON -DCMAKE_PREFIX_PATH=/deps/local -GNinja20# TODO figure out why Drone CI is deadlocking and stop passing -DZIG_SINGLE_THREADED=ON
21cmake .. -DCMAKE_BUILD_TYPE=Release "-DCMAKE_INSTALL_PREFIX=$DISTDIR" -DZIG_STATIC=ON -DCMAKE_PREFIX_PATH=/deps/local -GNinja -DZIG_SINGLE_THREADED=ON
2122
22samu install23samu install
23./zig build test -Dskip-release -Dskip-non-native24./zig build test -Dskip-release -Dskip-non-native
src/Compilation.zig+7-5
...@@ -1728,7 +1728,7 @@ fn workerUpdateCObject(...@@ -1728,7 +1728,7 @@ fn workerUpdateCObject(
1728 error.AnalysisFail => return,1728 error.AnalysisFail => return,
1729 else => {1729 else => {
1730 {1730 {
1731 var lock = comp.mutex.acquire();1731 const lock = comp.mutex.acquire();
1732 defer lock.release();1732 defer lock.release();
1733 comp.failed_c_objects.ensureCapacity(comp.gpa, comp.failed_c_objects.items().len + 1) catch {1733 comp.failed_c_objects.ensureCapacity(comp.gpa, comp.failed_c_objects.items().len + 1) catch {
1734 fatal("TODO handle this by setting c_object.status = oom failure", .{});1734 fatal("TODO handle this by setting c_object.status = oom failure", .{});
...@@ -1759,7 +1759,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_comp_progress_node: *...@@ -1759,7 +1759,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_comp_progress_node: *
17591759
1760 if (c_object.clearStatus(comp.gpa)) {1760 if (c_object.clearStatus(comp.gpa)) {
1761 // There was previous failure.1761 // There was previous failure.
1762 var lock = comp.mutex.acquire();1762 const lock = comp.mutex.acquire();
1763 defer lock.release();1763 defer lock.release();
1764 comp.failed_c_objects.removeAssertDiscard(c_object);1764 comp.failed_c_objects.removeAssertDiscard(c_object);
1765 }1765 }
...@@ -1789,10 +1789,12 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_comp_progress_node: *...@@ -1789,10 +1789,12 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_comp_progress_node: *
17891789
1790 {1790 {
1791 const is_collision = blk: {1791 const is_collision = blk: {
1792 var lock = comp.mutex.acquire();1792 const bin_digest = man.hash.peekBin();
1793
1794 const lock = comp.mutex.acquire();
1793 defer lock.release();1795 defer lock.release();
17941796
1795 const gop = try comp.c_object_cache_digest_set.getOrPut(comp.gpa, man.hash.peekBin());1797 const gop = try comp.c_object_cache_digest_set.getOrPut(comp.gpa, bin_digest);
1796 break :blk gop.found_existing;1798 break :blk gop.found_existing;
1797 };1799 };
1798 if (is_collision) {1800 if (is_collision) {
...@@ -2211,7 +2213,7 @@ fn failCObj(comp: *Compilation, c_object: *CObject, comptime format: []const u8,...@@ -2211,7 +2213,7 @@ fn failCObj(comp: *Compilation, c_object: *CObject, comptime format: []const u8,
22112213
2212fn failCObjWithOwnedErrorMsg(comp: *Compilation, c_object: *CObject, err_msg: *ErrorMsg) InnerError {2214fn failCObjWithOwnedErrorMsg(comp: *Compilation, c_object: *CObject, err_msg: *ErrorMsg) InnerError {
2213 {2215 {
2214 var lock = comp.mutex.acquire();2216 const lock = comp.mutex.acquire();
2215 defer lock.release();2217 defer lock.release();
2216 {2218 {
2217 errdefer err_msg.destroy(comp.gpa);2219 errdefer err_msg.destroy(comp.gpa);
src/ThreadPool.zig+6
...@@ -25,6 +25,8 @@ pub fn init(self: *ThreadPool, allocator: *std.mem.Allocator) !void {...@@ -25,6 +25,8 @@ pub fn init(self: *ThreadPool, allocator: *std.mem.Allocator) !void {
25 .allocator = allocator,25 .allocator = allocator,
26 .threads = &[_]*std.Thread{},26 .threads = &[_]*std.Thread{},
27 };27 };
28 if (std.builtin.single_threaded)
29 return;
2830
29 errdefer self.deinit();31 errdefer self.deinit();
3032
...@@ -67,6 +69,10 @@ pub fn shutdown(self: *ThreadPool) void {...@@ -67,6 +69,10 @@ pub fn shutdown(self: *ThreadPool) void {
67}69}
6870
69pub fn spawn(self: *ThreadPool, comptime func: anytype, args: anytype) !void {71pub fn spawn(self: *ThreadPool, comptime func: anytype, args: anytype) !void {
72 if (std.builtin.single_threaded) {
73 @call(.{}, func, args);
74 return;
75 }
70 const Args = @TypeOf(args);76 const Args = @TypeOf(args);
71 const Closure = struct {77 const Closure = struct {
72 arguments: Args,78 arguments: Args,
src/stage1/zig0.cpp+4
...@@ -266,6 +266,7 @@ int main(int argc, char **argv) {...@@ -266,6 +266,7 @@ int main(int argc, char **argv) {
266 TargetSubsystem subsystem = TargetSubsystemAuto;266 TargetSubsystem subsystem = TargetSubsystemAuto;
267 const char *override_lib_dir = nullptr;267 const char *override_lib_dir = nullptr;
268 const char *mcpu = nullptr;268 const char *mcpu = nullptr;
269 bool single_threaded = false;
269270
270 for (int i = 1; i < argc; i += 1) {271 for (int i = 1; i < argc; i += 1) {
271 char *arg = argv[i];272 char *arg = argv[i];
...@@ -281,6 +282,8 @@ int main(int argc, char **argv) {...@@ -281,6 +282,8 @@ int main(int argc, char **argv) {
281 optimize_mode = BuildModeSafeRelease;282 optimize_mode = BuildModeSafeRelease;
282 } else if (strcmp(arg, "-OReleaseSmall") == 0) {283 } else if (strcmp(arg, "-OReleaseSmall") == 0) {
283 optimize_mode = BuildModeSmallRelease;284 optimize_mode = BuildModeSmallRelease;
285 } else if (strcmp(arg, "--single-threaded") == 0) {
286 single_threaded = true;
284 } else if (strcmp(arg, "--help") == 0) {287 } else if (strcmp(arg, "--help") == 0) {
285 return print_full_usage(arg0, stdout, EXIT_SUCCESS);288 return print_full_usage(arg0, stdout, EXIT_SUCCESS);
286 } else if (strcmp(arg, "--strip") == 0) {289 } else if (strcmp(arg, "--strip") == 0) {
...@@ -469,6 +472,7 @@ int main(int argc, char **argv) {...@@ -469,6 +472,7 @@ int main(int argc, char **argv) {
469 stage1->link_libcpp = link_libcpp;472 stage1->link_libcpp = link_libcpp;
470 stage1->subsystem = subsystem;473 stage1->subsystem = subsystem;
471 stage1->pic = true;474 stage1->pic = true;
475 stage1->is_single_threaded = single_threaded;
472476
473 zig_stage1_build_object(stage1);477 zig_stage1_build_object(stage1);
474478