Compare commits

...

15 commits

Author SHA1 Message Date
Yureka 42a160bce2 flake.lock: Update
Flake lock file updates:

• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/9227223f6d922fee3c7b190b2cc238a99527bbb7' (2024-07-03)
  → 'github:hercules-ci/flake-parts/8471fe90ad337a8074e957b69ca4d0089218391d' (2024-08-01)
• Updated input 'lix':
    'ef0de7c79f.tar.gz?narHash=sha256-GUH5%2BB1JztzDNSN1D7KbndrYSq0LWvVIJnuWKHlpN3Q%3D' (2024-07-16)
  → 'b016eb0895.tar.gz?narHash=sha256-kOpGI9WPmte1L4QWHviuXsr8jxmGn27zwi82jtzYObM%3D&rev=b016eb0895bb6714a4f6530d9a2bb6577ac6c3cf' (2024-08-13)
• Updated input 'lix/nix2container':
    'github:nlewo/nix2container/20aad300c925639d5d6cbe30013c8357ce9f2a2e' (2024-04-13)
  → 'github:nlewo/nix2container/3853e5caf9ad24103b13aa6e0e8bcebb47649fe4' (2024-07-10)
• Updated input 'lix/pre-commit-hooks':
    'github:cachix/git-hooks.nix/e35aed5fda3cc79f88ed7f1795021e559582093a' (2024-04-02)
  → 'github:cachix/git-hooks.nix/f451c19376071a90d8c58ab1a953c6e9840527fd' (2024-07-15)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/732b4f3a3afdfe6a6c4fcb2511e529588d4e5ccd' (2024-07-15)
  → 'github:NixOS/nixpkgs/fb81cec9eda2a6b5365ad723995f0329d9e356fd' (2024-08-13)
• Updated input 'treefmt-nix':
    'github:numtide/treefmt-nix/0fb28f237f83295b4dd05e342f333b447c097398' (2024-07-15)
  → 'github:numtide/treefmt-nix/349de7bc435bdff37785c2466f054ed1766173be' (2024-08-12)
2024-08-13 22:00:51 +02:00
Pierre Bourdon c057494450
flake.lock: Update
Flake lock file updates:

• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/2a55567fcf15b1b1c7ed712a2c6fadaec7412ea8' (2024-06-01)
  → 'github:hercules-ci/flake-parts/9227223f6d922fee3c7b190b2cc238a99527bbb7' (2024-07-03)
• Updated input 'lix':
    'f170870ae7.tar.gz?narHash=sha256-GK6PusfbMgkg%2BqdgChmrw78KTNQkm7SDoJ6%2BlJKY6vg%3D' (2024-06-25)
  → 'ef0de7c79f.tar.gz?narHash=sha256-GUH5%2BB1JztzDNSN1D7KbndrYSq0LWvVIJnuWKHlpN3Q%3D' (2024-07-16)
• Updated input 'nix-github-actions':
    'github:nix-community/nix-github-actions/5163432afc817cf8bd1f031418d1869e4c9d5547' (2023-12-29)
  → 'github:nix-community/nix-github-actions/622f829f5fe69310a866c8a6cd07e747c44ef820' (2024-07-04)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/d9e18354acbf59c625505b7315c85508e9831bf4' (2024-06-18)
  → 'github:NixOS/nixpkgs/732b4f3a3afdfe6a6c4fcb2511e529588d4e5ccd' (2024-07-15)
• Updated input 'treefmt-nix':
    'github:numtide/treefmt-nix/1cb529bffa880746a1d0ec4e0f5076876af931f1' (2024-06-11)
  → 'github:numtide/treefmt-nix/0fb28f237f83295b4dd05e342f333b447c097398' (2024-07-15)
2024-07-17 07:57:52 +02:00
Pierre Bourdon d9a46559a4
drv: backport CA derivations support changes from hydra-eval-jobs
It is not possible to query output paths for CA derivations since
they're not static / known at eval time. Instead, return JSON nulls for
outputs paths.

This is a partial port of the following Hydra commits:

- 9ba4417940ffdd0fadea43f68c61ef948a4b8d39
- 069b7775c565f5999fe33e8c3f28c7b9306039ca
- fcde5908d8e51f975b883329b34d24a9f30ea4b3

By the following authors:

Co-Authored-By: John Ericson <John.Ericson@Obsidian.Systems>
Co-Authored-By: Théophane Hufschmitt <theophane.hufschmitt@tweag.io>
Co-Authored-By: Alexander Sosedkin <monk@unboiled.info>
Co-Authored-By: Andrea Ciceri <andrea.ciceri@autistici.org>
Co-Authored-By: Charlotte 🦝 Delenk Mlotte@chir.rs>
Co-Authored-By: Sandro Jäckel <sandro.jaeckel@gmail.com>
2024-07-16 09:15:21 +02:00
eldritch horrors f8869bdcca update for lix 2.91-dev
the api of nix::Pid changed, causing a build failure.
2024-06-25 23:57:51 +02:00
jade fd86a1a068 Fix on latest lix
Fixes: #9
2024-06-18 23:08:04 -07:00
jade 9c23772cf2 Tidy and make it work on release-2.90 2024-06-18 22:31:42 -07:00
puck 11d467fecd Use our own Thread struct instead of std::thread
We'd highly prefer using std::thread here; but this won't let us configure the stack
size. macOS uses 512KiB size stacks for non-main threads, and musl defaults to 128k.
While Nix configures a 64MiB size for the main thread, this doesn't propagate to the
threads we launch here. It turns out, running the evaluator under an anemic stack of
0.5MiB has it overflow way too quickly. Hence, we have our own custom Thread struct.
2024-06-12 22:39:53 +00:00
puck 040db2fe26 flake.nix: nixpkgs-unstable -> nixos-23.11-unstable; flake update
This makes nix-eval-jobs build again.
2024-06-12 22:39:29 +00:00
jade ee79f8a236 Merge pull request 'Fixup readme and version to say what this is' (#6) from jade/fixup-readme-and-version into main
Reviewed-on: #6
2024-06-12 21:06:56 +00:00
jade ed7a959ae1 update lix pin to actually work 2024-05-30 12:50:13 -07:00
jade d05f8e86a9 Merge pull request 'lix: deal with util.hh removal' (#7) from jade/util-hh-removal into main
Reviewed-on: #7
2024-05-30 02:33:13 +00:00
jade b67c46d320 lix: deal with util.hh removal 2024-05-29 19:17:54 -07:00
jade 30cf61fd26 fix: don't crash on startup on macOS
This is caused, through several layers of absurdity, by runtime type
information of Nix things being invisible due to -fvisibility=hidden
inside n-e-j.

We don't have any idea why n-e-j has -fvisibility=hidden, since blame
says it's from the initial commit. It is plausible that it was some
ill-advised optimization but it's not sound.

The crash is caused by dynamic_cast<RootArgs *>(MyArgs *) failing, which
is in turn caused by the RTTI being invisible.

See: https://www.qt.io/blog/quality-assurance/one-way-dynamic_cast-across-library-boundaries-can-fail-and-how-to-fix-it
Fixes: #2
2024-05-27 18:23:13 -06:00
jade 7e22a3daab Fixup readme and version to say what this is 2024-05-27 12:54:51 -06:00
jade 13524829d1 Merge pull request 'nixexpr -> lixexpr' (#5) from jade/lixexpr into main
Reviewed-on: #5
2024-05-23 23:24:26 +00:00
13 changed files with 145 additions and 58 deletions

View file

@ -1 +0,0 @@
unstable

View file

@ -1,5 +1,8 @@
# nix-eval-jobs # nix-eval-jobs
> [!NOTE]
> This is a fork of nix-eval-jobs that works with Lix.
This project evaluates nix attribute sets in parallel with streamable json This project evaluates nix attribute sets in parallel with streamable json
output. This is useful for time and memory intensive evaluations such as NixOS output. This is useful for time and memory intensive evaluations such as NixOS
machines, i.e. in a CI context. The evaluation is done with a controllable machines, i.e. in a CI context. The evaluation is done with a controllable
@ -89,11 +92,12 @@ we collect example ci configuration for various CIs.
## Organisation of this repository ## Organisation of this repository
On the `main` branch we target nixUnstable. When a release of nix happens, we `main` follows Lix HEAD, and is updated alongside the Lix NixOS module. When we
fork for a release branch i.e. `release-2.8` and change the nix version in release we will make a `release-2.90` etc branch, which receives backports.
`.nix-version`. Changes and improvements made in `main` also may be backported
to these release branches. At the time of writing we only intent to support the The version of nix-eval-jobs follows the major version of Lix and minor
latest release branch. versions of nix-eval-jobs are released as necessary when changes are made in
n-e-j itself.
## Projects using nix-eval-jobs ## Projects using nix-eval-jobs

View file

@ -11,7 +11,7 @@ let
in in
stdenv.mkDerivation { stdenv.mkDerivation {
pname = "nix-eval-jobs"; pname = "nix-eval-jobs";
version = "2.19.0"; version = "2.90.0-unstable";
src = if srcDir == null then filterMesonBuild ./. else srcDir; src = if srcDir == null then filterMesonBuild ./. else srcDir;
buildInputs = with pkgs; [ buildInputs = with pkgs; [
nlohmann_json nlohmann_json

View file

@ -23,11 +23,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1701473968, "lastModified": 1722555600,
"narHash": "sha256-YcVE5emp1qQ8ieHUnxt1wCZCC3ZfAS+SRRWZ2TMda7E=", "narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=",
"owner": "hercules-ci", "owner": "hercules-ci",
"repo": "flake-parts", "repo": "flake-parts",
"rev": "34fed993f1674c8d06d58b37ce1e0fe5eebcb9f5", "rev": "8471fe90ad337a8074e957b69ca4d0089218391d",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -39,6 +39,7 @@
"lix": { "lix": {
"inputs": { "inputs": {
"flake-compat": "flake-compat", "flake-compat": "flake-compat",
"nix2container": "nix2container",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
], ],
@ -46,18 +47,15 @@
"pre-commit-hooks": "pre-commit-hooks" "pre-commit-hooks": "pre-commit-hooks"
}, },
"locked": { "locked": {
"lastModified": 1714955862, "lastModified": 1723577950,
"narHash": "sha256-REWlo2RYHfJkxnmZTEJu3Cd/2VM+wjjpPy7Xi4BdDTQ=", "narHash": "sha256-kOpGI9WPmte1L4QWHviuXsr8jxmGn27zwi82jtzYObM=",
"ref": "refs/tags/2.90-beta.1", "rev": "b016eb0895bb6714a4f6530d9a2bb6577ac6c3cf",
"rev": "b6799ab0374a8e1907a48915d3187e07da41d88c", "type": "tarball",
"revCount": 15501, "url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/b016eb0895bb6714a4f6530d9a2bb6577ac6c3cf.tar.gz?rev=b016eb0895bb6714a4f6530d9a2bb6577ac6c3cf"
"type": "git",
"url": "https://git@git.lix.systems/lix-project/lix"
}, },
"original": { "original": {
"ref": "refs/tags/2.90-beta.1", "type": "tarball",
"type": "git", "url": "https://git.lix.systems/lix-project/lix/archive/main.tar.gz"
"url": "https://git@git.lix.systems/lix-project/lix"
} }
}, },
"nix-github-actions": { "nix-github-actions": {
@ -67,11 +65,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1701208414, "lastModified": 1720066371,
"narHash": "sha256-xrQ0FyhwTZK6BwKhahIkUVZhMNk21IEI1nUcWSONtpo=", "narHash": "sha256-uPlLYH2S0ACj0IcgaK9Lsf4spmJoGejR9DotXiXSBZQ=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nix-github-actions", "repo": "nix-github-actions",
"rev": "93e39cc1a087d65bcf7a132e75a650c44dd2b734", "rev": "622f829f5fe69310a866c8a6cd07e747c44ef820",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -80,18 +78,34 @@
"type": "github" "type": "github"
} }
}, },
"nix2container": {
"flake": false,
"locked": {
"lastModified": 1720642556,
"narHash": "sha256-qsnqk13UmREKmRT7c8hEnz26X3GFFyIQrqx4EaRc1Is=",
"owner": "nlewo",
"repo": "nix2container",
"rev": "3853e5caf9ad24103b13aa6e0e8bcebb47649fe4",
"type": "github"
},
"original": {
"owner": "nlewo",
"repo": "nix2container",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1703134684, "lastModified": 1723540975,
"narHash": "sha256-SQmng1EnBFLzS7WSRyPM9HgmZP2kLJcPAz+Ug/nug6o=", "narHash": "sha256-rxpxOz2VSqgmwI7g7FGVAoye5bxwO1MSpnELY5bsITw=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "d6863cbcbbb80e71cecfc03356db1cda38919523", "rev": "fb81cec9eda2a6b5365ad723995f0329d9e356fd",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixpkgs-unstable", "ref": "nixos-24.05-small",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@ -115,11 +129,11 @@
"pre-commit-hooks": { "pre-commit-hooks": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1712055707, "lastModified": 1721042469,
"narHash": "sha256-4XLvuSIDZJGS17xEwSrNuJLL7UjDYKGJSbK1WWX2AK8=", "narHash": "sha256-6FPUl7HVtvRHCCBQne7Ylp4p+dpP3P/OYuzjztZ4s70=",
"owner": "cachix", "owner": "cachix",
"repo": "git-hooks.nix", "repo": "git-hooks.nix",
"rev": "e35aed5fda3cc79f88ed7f1795021e559582093a", "rev": "f451c19376071a90d8c58ab1a953c6e9840527fd",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -144,11 +158,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1702979157, "lastModified": 1723454642,
"narHash": "sha256-RnFBbLbpqtn4AoJGXKevQMCGhra4h6G2MPcuTSZZQ+g=", "narHash": "sha256-S0Gvsenh0II7EAaoc9158ZB4vYyuycvMGKGxIbERNAM=",
"owner": "numtide", "owner": "numtide",
"repo": "treefmt-nix", "repo": "treefmt-nix",
"rev": "2961375283668d867e64129c22af532de8e77734", "rev": "349de7bc435bdff37785c2466f054ed1766173be",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -1,7 +1,7 @@
{ {
description = "Hydra's builtin hydra-eval-jobs as a standalone"; description = "Hydra's builtin hydra-eval-jobs as a standalone";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05-small";
inputs.flake-parts.url = "github:hercules-ci/flake-parts"; inputs.flake-parts.url = "github:hercules-ci/flake-parts";
inputs.flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs"; inputs.flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs";
inputs.treefmt-nix.url = "github:numtide/treefmt-nix"; inputs.treefmt-nix.url = "github:numtide/treefmt-nix";
@ -9,7 +9,7 @@
inputs.nix-github-actions.url = "github:nix-community/nix-github-actions"; inputs.nix-github-actions.url = "github:nix-community/nix-github-actions";
inputs.nix-github-actions.inputs.nixpkgs.follows = "nixpkgs"; inputs.nix-github-actions.inputs.nixpkgs.follows = "nixpkgs";
inputs.lix = { inputs.lix = {
url = "git+https://git@git.lix.systems/lix-project/lix?ref=refs/tags/2.90-beta.1"; url = "https://git.lix.systems/lix-project/lix/archive/main.tar.gz";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
@ -17,7 +17,6 @@
let let
inherit (inputs.nixpkgs) lib; inherit (inputs.nixpkgs) lib;
inherit (inputs) self; inherit (inputs) self;
nixVersion = lib.fileContents ./.nix-version;
in in
flake-parts.lib.mkFlake { inherit inputs; } flake-parts.lib.mkFlake { inherit inputs; }
{ {

View file

@ -1,6 +1,11 @@
project('nix-eval-jobs', 'cpp', project('nix-eval-jobs', 'cpp',
version : '0.1.6', version : '0.1.6',
license : 'GPL-3.0', license : 'GPL-3.0',
default_options : [
'debug=true',
'optimization=2',
'cpp_std=c++20',
],
) )
nix_main_dep = dependency('lix-main', required: true) nix_main_dep = dependency('lix-main', required: true)

View file

@ -23,6 +23,7 @@ in
pkgs.mkShell { pkgs.mkShell {
inherit (nix-eval-jobs) buildInputs; inherit (nix-eval-jobs) buildInputs;
nativeBuildInputs = nix-eval-jobs.nativeBuildInputs ++ [ nativeBuildInputs = nix-eval-jobs.nativeBuildInputs ++ [
pkgs.clang-tools
(pkgs.python3.withPackages (ps: [ (pkgs.python3.withPackages (ps: [
ps.pytest ps.pytest
])) ]))

View file

@ -23,14 +23,17 @@
#include "drv.hh" #include "drv.hh"
#include "eval-args.hh" #include "eval-args.hh"
static bool queryIsCached(nix::Store &store, static bool
std::map<std::string, std::string> &outputs) { queryIsCached(nix::Store &store,
std::map<std::string, std::optional<std::string>> &outputs) {
uint64_t downloadSize, narSize; uint64_t downloadSize, narSize;
nix::StorePathSet willBuild, willSubstitute, unknown; nix::StorePathSet willBuild, willSubstitute, unknown;
std::vector<nix::StorePathWithOutputs> paths; std::vector<nix::StorePathWithOutputs> paths;
for (auto const &[key, val] : outputs) { for (auto const &[key, val] : outputs) {
paths.push_back(followLinksToStorePathWithOutputs(store, val)); if (val) {
paths.push_back(followLinksToStorePathWithOutputs(store, *val));
}
} }
store.queryMissing(toDerivedPaths(paths), willBuild, willSubstitute, store.queryMissing(toDerivedPaths(paths), willBuild, willSubstitute,
@ -45,9 +48,19 @@ Drv::Drv(std::string &attrPath, nix::EvalState &state, nix::DrvInfo &drvInfo,
auto localStore = state.store.dynamic_pointer_cast<nix::LocalFSStore>(); auto localStore = state.store.dynamic_pointer_cast<nix::LocalFSStore>();
try { try {
for (auto out : drvInfo.queryOutputs(true)) { // CA derivations do not have static output paths, so we have to
if (out.second) // defensively not query output paths in case we encounter one.
outputs[out.first] = localStore->printStorePath(*out.second); for (auto &[outputName, optOutputPath] :
drvInfo.queryOutputs(!nix::experimentalFeatureSettings.isEnabled(
nix::Xp::CaDerivations))) {
if (optOutputPath) {
outputs[outputName] =
localStore->printStorePath(*optOutputPath);
} else {
assert(nix::experimentalFeatureSettings.isEnabled(
nix::Xp::CaDerivations));
outputs[outputName] = std::nullopt;
}
} }
} catch (const std::exception &e) { } catch (const std::exception &e) {
throw nix::EvalError(state, throw nix::EvalError(state,
@ -98,10 +111,16 @@ Drv::Drv(std::string &attrPath, nix::EvalState &state, nix::DrvInfo &drvInfo,
} }
void to_json(nlohmann::json &json, const Drv &drv) { void to_json(nlohmann::json &json, const Drv &drv) {
std::map<std::string, nlohmann::json> outputsJson;
for (auto &[name, optPath] : drv.outputs) {
outputsJson[name] =
optPath ? nlohmann::json(*optPath) : nlohmann::json(nullptr);
}
json = nlohmann::json{{"name", drv.name}, json = nlohmann::json{{"name", drv.name},
{"system", drv.system}, {"system", drv.system},
{"drvPath", drv.drvPath}, {"drvPath", drv.drvPath},
{"outputs", drv.outputs}, {"outputs", outputsJson},
{"inputDrvs", drv.inputDrvs}}; {"inputDrvs", drv.inputDrvs}};
if (drv.meta.has_value()) { if (drv.meta.has_value()) {

View file

@ -24,7 +24,7 @@ struct Drv {
std::string drvPath; std::string drvPath;
enum class CacheStatus { Cached, Uncached, Unknown } cacheStatus; enum class CacheStatus { Cached, Uncached, Unknown } cacheStatus;
std::map<std::string, std::string> outputs; std::map<std::string, std::optional<std::string>> outputs;
std::map<std::string, std::set<std::string>> inputDrvs; std::map<std::string, std::set<std::string>> inputDrvs;
std::optional<nlohmann::json> meta; std::optional<nlohmann::json> meta;

View file

@ -12,7 +12,7 @@
class MyArgs : virtual public nix::MixEvalArgs, class MyArgs : virtual public nix::MixEvalArgs,
virtual public nix::MixCommonArgs, virtual public nix::MixCommonArgs,
virtual nix::RootArgs { virtual public nix::RootArgs {
public: public:
std::string releaseExpr; std::string releaseExpr;
nix::Path gcRootsDir; nix::Path gcRootsDir;

View file

@ -1,10 +1,10 @@
src = [ src = files(
'nix-eval-jobs.cc', 'nix-eval-jobs.cc',
'eval-args.cc', 'eval-args.cc',
'drv.cc', 'drv.cc',
'buffered-io.cc', 'buffered-io.cc',
'worker.cc' 'worker.cc',
] )
cc = meson.get_compiler('cpp') cc = meson.get_compiler('cpp')
@ -31,4 +31,4 @@ executable('nix-eval-jobs', src,
threads_dep threads_dep
], ],
install: true, install: true,
cpp_args: ['-std=c++2a', '-fvisibility=hidden', '--include', 'autotools-config.h']) cpp_args: ['--include', 'autotools-config.h'])

View file

@ -8,6 +8,7 @@
#include <sys/wait.h> #include <sys/wait.h>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <errno.h> #include <errno.h>
#include <pthread.h>
#include <signal.h> #include <signal.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -17,13 +18,13 @@
#include <lix/libutil/error.hh> #include <lix/libutil/error.hh>
#include <lix/libstore/globals.hh> #include <lix/libstore/globals.hh>
#include <lix/libutil/logging.hh> #include <lix/libutil/logging.hh>
#include <lix/libutil/terminal.hh>
#include <nlohmann/detail/iterators/iter_impl.hpp> #include <nlohmann/detail/iterators/iter_impl.hpp>
#include <nlohmann/detail/json_ref.hpp> #include <nlohmann/detail/json_ref.hpp>
#include <nlohmann/json_fwd.hpp> #include <nlohmann/json_fwd.hpp>
#include <lix/libutil/ref.hh> #include <lix/libutil/ref.hh>
#include <lix/libstore/store-api.hh> #include <lix/libstore/store-api.hh>
#include <map> #include <map>
#include <thread>
#include <condition_variable> #include <condition_variable>
#include <filesystem> #include <filesystem>
#include <exception> #include <exception>
@ -92,12 +93,60 @@ struct Proc {
to = std::move(toPipe.writeSide); to = std::move(toPipe.writeSide);
from = std::move(fromPipe.readSide); from = std::move(fromPipe.readSide);
pid = p; pid = std::move(p);
} }
~Proc() {} ~Proc() {}
}; };
// We'd highly prefer using std::thread here; but this won't let us configure the stack
// size. macOS uses 512KiB size stacks for non-main threads, and musl defaults to 128k.
// While Nix configures a 64MiB size for the main thread, this doesn't propagate to the
// threads we launch here. It turns out, running the evaluator under an anemic stack of
// 0.5MiB has it overflow way too quickly. Hence, we have our own custom Thread struct.
struct Thread {
pthread_t thread;
Thread(const Thread &) = delete;
Thread(Thread &&) noexcept = default;
Thread(std::function<void(void)> f) {
int s;
pthread_attr_t attr;
auto func = std::make_unique<std::function<void(void)>>(std::move(f));
if ((s = pthread_attr_init(&attr)) != 0) {
throw SysError(s, "calling pthread_attr_init");
}
if ((s = pthread_attr_setstacksize(&attr, 64 * 1024 * 1024)) != 0) {
throw SysError(s, "calling pthread_attr_setstacksize");
}
if ((s = pthread_create(&thread, &attr, Thread::init, func.release())) != 0) {
throw SysError(s, "calling pthread_launch");
}
if ((s = pthread_attr_destroy(&attr)) != 0) {
throw SysError(s, "calling pthread_attr_destroy");
}
}
void join() {
int s;
s = pthread_join(thread, nullptr);
if (s != 0) {
throw SysError(s, "calling pthread_join");
}
}
private:
static void *init(void *ptr) {
std::unique_ptr<std::function<void(void)>> func;
func.reset(static_cast<std::function<void(void)> *>(ptr));
(*func)();
return 0;
}
};
struct State { struct State {
std::set<json> todo = json::array({json::array()}); std::set<json> todo = json::array({json::array()});
std::set<json> active; std::set<json> active;
@ -331,10 +380,10 @@ int main(int argc, char **argv) {
Sync<State> state_; Sync<State> state_;
/* Start a collector thread per worker process. */ /* Start a collector thread per worker process. */
std::vector<std::thread> threads; std::vector<Thread> threads;
std::condition_variable wakeup; std::condition_variable wakeup;
for (size_t i = 0; i < myArgs.nrWorkers; i++) { for (size_t i = 0; i < myArgs.nrWorkers; i++) {
threads.emplace_back(collector, std::ref(state_), std::ref(wakeup)); threads.emplace_back(std::bind(collector, std::ref(state_), std::ref(wakeup)));
} }
for (auto &thread : threads) for (auto &thread : threads)

View file

@ -27,18 +27,15 @@
#include <lix/libstore/store-api.hh> #include <lix/libstore/store-api.hh>
#include <lix/libexpr/symbol-table.hh> #include <lix/libexpr/symbol-table.hh>
#include <lix/libutil/types.hh> #include <lix/libutil/types.hh>
#include <lix/libutil/util.hh>
#include <lix/libexpr/value.hh> #include <lix/libexpr/value.hh>
#include <lix/libutil/terminal.hh>
#include <exception> #include <exception>
#include <map>
#include <memory>
#include <numeric> #include <numeric>
#include <optional> #include <optional>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <utility> #include <utility>
#include <vector>
#include "worker.hh" #include "worker.hh"
#include "drv.hh" #include "drv.hh"
@ -51,7 +48,7 @@ static nix::Value *releaseExprTopLevelValue(nix::EvalState &state,
nix::Value vTop; nix::Value vTop;
if (args.fromArgs) { if (args.fromArgs) {
nix::Expr *e = state.parseExprFromString( nix::Expr &e = state.parseExprFromString(
args.releaseExpr, state.rootPath(nix::CanonPath::fromCwd())); args.releaseExpr, state.rootPath(nix::CanonPath::fromCwd()));
state.eval(e, vTop); state.eval(e, vTop);
} else { } else {