From c3c983087206a0598b2610eed4dde02f15a0036f Mon Sep 17 00:00:00 2001 From: sinanmohd Date: Sun, 21 Jul 2024 11:54:13 +0530 Subject: evanix: add --solver flag --- include/evanix.h | 3 +++ include/solver_greedy.h | 2 +- include/solver_util.h | 2 ++ src/evanix.c | 22 +++++++++++++++++++++- src/queue.c | 12 +++++------- src/solver_greedy.c | 15 +++++++-------- src/solver_util.c | 12 ++++++++++++ 7 files changed, 51 insertions(+), 17 deletions(-) diff --git a/include/evanix.h b/include/evanix.h index df3e034..6832777 100644 --- a/include/evanix.h +++ b/include/evanix.h @@ -1,6 +1,8 @@ #include #include +#include "jobs.h" + #ifndef EVANIX_H struct evanix_opts_t { @@ -12,6 +14,7 @@ struct evanix_opts_t { bool check_cache_status; char *system; uint32_t max_build; + int (*solver)(struct job **, struct job_clist *, int32_t); }; extern struct evanix_opts_t evanix_opts; diff --git a/include/solver_greedy.h b/include/solver_greedy.h index 5119818..b76aed9 100644 --- a/include/solver_greedy.h +++ b/include/solver_greedy.h @@ -1,3 +1,3 @@ #include "jobs.h" -int solver_greedy(struct job_clist *q, int32_t *max_build, struct job **job); +int solver_greedy(struct job **job, struct job_clist *q, int32_t resources); diff --git a/include/solver_util.h b/include/solver_util.h index 08f7f16..f1c8d41 100644 --- a/include/solver_util.h +++ b/include/solver_util.h @@ -15,6 +15,8 @@ struct jobid { void jobid_free(struct jobid *jid); int jobid_init(struct job_clist *q, struct jobid **job_ids); +int solver_fcfs(struct job **job, struct job_clist *q, + __attribute__((unused)) int32_t resources); #define SOLVER_UTIL_H #endif diff --git a/src/evanix.c b/src/evanix.c index bcebf69..09fecb3 100644 --- a/src/evanix.c +++ b/src/evanix.c @@ -5,6 +5,8 @@ #include "build.h" #include "evanix.h" #include "queue.h" +#include "solver_greedy.h" +#include "solver_util.h" #include "util.h" static const char usage[] = @@ -20,6 +22,7 @@ static const char usage[] = " -p, --pipelined Use evanix build pipeline.\n" " -l, --check_cache-status Perform cache locality check.\n" " -c, --close-unused-fd Close stderr on exec.\n" + " -k, --solver fcfs|greedy Solver to use.\n" "\n"; struct evanix_opts_t evanix_opts = { @@ -31,6 +34,7 @@ struct evanix_opts_t evanix_opts = { .system = NULL, .solver_report = false, .check_cache_status = true, + .solver = solver_fcfs, }; static int evanix_build_thread_create(struct build_thread *build_thread); @@ -129,6 +133,7 @@ int main(int argc, char *argv[]) {"help", no_argument, NULL, 'h'}, {"flake", no_argument, NULL, 'f'}, {"dry-run", no_argument, NULL, 'd'}, + {"solver", required_argument, NULL, 'k'}, {"system", required_argument, NULL, 's'}, {"solver-report", no_argument, NULL, 'r'}, {"max-build", required_argument, NULL, 'm'}, @@ -138,7 +143,7 @@ int main(int argc, char *argv[]) {NULL, 0, NULL, 0}, }; - while ((c = getopt_long(argc, argv, "hfds:r::m:p:c:l:", longopts, + while ((c = getopt_long(argc, argv, "hfds:r::m:p:c:l:k:", longopts, &longindex)) != -1) { switch (c) { case 'h': @@ -157,6 +162,21 @@ int main(int argc, char *argv[]) case 'r': evanix_opts.solver_report = true; break; + case 'k': + if (!strcmp(optarg, "greedy")) { + evanix_opts.solver = solver_greedy; + } else if (!strcmp(optarg, "fcfs")) { + evanix_opts.solver = solver_fcfs; + } else { + fprintf(stderr, + "option -%c has an invalid solver " + "argument\n" + "Try 'evanix --help' for more " + "information.\n", + c); + exit(EXIT_FAILURE); + } + break; case 'm': ret = atoi(optarg); if (ret <= 0) { diff --git a/src/queue.c b/src/queue.c index 32e5705..98f3cf4 100644 --- a/src/queue.c +++ b/src/queue.c @@ -103,13 +103,11 @@ int queue_pop(struct queue *queue, struct job **job) } pthread_mutex_lock(&queue->mutex); - if (evanix_opts.max_build) { - ret = solver_greedy(&queue->jobs, &queue->resources, &j); - if (ret < 0) - goto out_mutex_unlock; - } else { - j = CIRCLEQ_FIRST(&queue->jobs); - } + ret = evanix_opts.solver(&j, &queue->jobs, queue->resources); + if (ret < 0) + goto out_mutex_unlock; + else if (evanix_opts.max_build) + queue->resources -= ret; ret = queue_dag_isolate(j, NULL, &queue->jobs, &queue->htab); if (ret < 0) goto out_mutex_unlock; diff --git a/src/solver_greedy.c b/src/solver_greedy.c index 9dd852e..160a035 100644 --- a/src/solver_greedy.c +++ b/src/solver_greedy.c @@ -35,7 +35,7 @@ static float conformity(struct job *job) return conformity; } -static void solver_report(struct job *job, int32_t max_build) +static void solver_report(struct job *job, int32_t resources) { if (!evanix_opts.solver_report) return; @@ -43,14 +43,14 @@ static void solver_report(struct job *job, int32_t max_build) return; job->reported = true; - printf("❌ cost: %2d > %2d <-> %s -> %s\n", job_cost(job), max_build, + printf("❌ cost: %2d > %2d <-> %s -> %s\n", job_cost(job), resources, job->name, job->drv_path); for (size_t i = 0; i < job->parents_filled; i++) - solver_report(job->parents[i], max_build); + solver_report(job->parents[i], resources); } -int solver_greedy(struct job_clist *q, int32_t *max_build, struct job **job) +int solver_greedy(struct job **job, struct job_clist *q, int32_t resources) { struct job *j; float conformity_cur; @@ -61,9 +61,9 @@ int solver_greedy(struct job_clist *q, int32_t *max_build, struct job **job) CIRCLEQ_FOREACH (j, q, clist) { if (j->stale) { continue; - } else if (job_cost(j) > *max_build) { + } else if (job_cost(j) > resources) { job_stale_set(j); - solver_report(j, *max_build); + solver_report(j, resources); continue; } } @@ -90,7 +90,6 @@ int solver_greedy(struct job_clist *q, int32_t *max_build, struct job **job) if (selected == NULL) return -ESRCH; - *max_build -= job_cost(selected); *job = selected; - return 0; + return job_cost(selected); } diff --git a/src/solver_util.c b/src/solver_util.c index 5731c9a..ec18f3c 100644 --- a/src/solver_util.c +++ b/src/solver_util.c @@ -99,3 +99,15 @@ out_free_jid: return ret; } + +int solver_fcfs(struct job **job, struct job_clist *q, + __attribute__((unused)) int32_t resources) +{ + if (CIRCLEQ_EMPTY(q)) { + print_err("%s", "Trying to pop from empty queue"); + return -ESRCH; + } + + *job = CIRCLEQ_FIRST(q); + return 0; +} -- cgit v1.2.3