summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsinanmohd <sinan@sinanmohd.com>2024-07-21 11:54:13 +0530
committersinanmohd <sinan@sinanmohd.com>2024-07-21 11:54:13 +0530
commitc3c983087206a0598b2610eed4dde02f15a0036f (patch)
tree2c90b3857f7d8f59ff9c2c723a9e05f16ec3c5bf
parent15a55c7f85c5d624e29c453d3f1c3af015123cdf (diff)
evanix: add --solver flag
-rw-r--r--include/evanix.h3
-rw-r--r--include/solver_greedy.h2
-rw-r--r--include/solver_util.h2
-rw-r--r--src/evanix.c22
-rw-r--r--src/queue.c12
-rw-r--r--src/solver_greedy.c15
-rw-r--r--src/solver_util.c12
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 <stdbool.h>
#include <stdint.h>
+#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 <bool> Use evanix build pipeline.\n"
" -l, --check_cache-status <bool> Perform cache locality check.\n"
" -c, --close-unused-fd <bool> 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;
+}