aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsinanmohd <sinan@sinanmohd.com>2024-06-14 12:18:40 +0530
committersinanmohd <sinan@sinanmohd.com>2024-06-14 18:53:40 +0530
commit58fe7d147774960e3fb7dbc53a3e5ecf106ebf01 (patch)
tree0b8651b5a69666605125c05ee18ee68bd13308e1
parent6627adcbc2d2ade8db1fd2ed26e03d37b53fde62 (diff)
build: init
-rw-r--r--include/build.h12
-rw-r--r--include/jobs.h5
-rw-r--r--include/queue.h14
-rw-r--r--src/build.c69
-rw-r--r--src/evanix.c24
-rw-r--r--src/meson.build1
-rw-r--r--src/queue.c52
7 files changed, 171 insertions, 6 deletions
diff --git a/include/build.h b/include/build.h
new file mode 100644
index 0000000..c51bc5d
--- /dev/null
+++ b/include/build.h
@@ -0,0 +1,12 @@
+#include <pthread.h>
+#include <sys/queue.h>
+
+#include "queue.h"
+
+struct build_thread {
+ pthread_t tid;
+ struct queue *queue;
+};
+
+void *build_thread_entry(void *queue_thread);
+int build_thread_new(struct build_thread **build_thread, struct queue *q);
diff --git a/include/jobs.h b/include/jobs.h
index be95c57..1044eaa 100644
--- a/include/jobs.h
+++ b/include/jobs.h
@@ -1,6 +1,8 @@
#include <stdio.h>
#include <sys/queue.h>
+#ifndef JOBS_H
+
LIST_HEAD(output_dlist, output);
struct output {
char *name, *store_path;
@@ -23,3 +25,6 @@ int jobs_init(FILE **stream);
int job_new(struct job **j, char *name, char *drv_path);
void job_free(struct job *j);
int job_read(FILE *stream, struct job **jobs);
+
+#define JOBS_H
+#endif
diff --git a/include/queue.h b/include/queue.h
index ca11614..5f2d5f4 100644
--- a/include/queue.h
+++ b/include/queue.h
@@ -1,10 +1,20 @@
#include <pthread.h>
#include <sys/queue.h>
+#include <semaphore.h>
#include "jobs.h"
+#ifndef QUEUE_H
+
+typedef enum {
+ Q_ITS_OVER = 0,
+ Q_SEM_WAIT = 1,
+} queue_state_t;
+
struct queue {
struct job_clist jobs;
+ sem_t sem;
+ queue_state_t state;
pthread_mutex_t mutex;
};
@@ -17,3 +27,7 @@ struct queue_thread {
int queue_thread_new(struct queue_thread **queue_thread, FILE *stream);
void queue_thread_free(struct queue_thread *queue_thread);
void *queue_thread_entry(void *queue_thread);
+int queue_pop(struct queue *queue, struct job **job);
+
+#define QUEUE_H
+#endif
diff --git a/src/build.c b/src/build.c
new file mode 100644
index 0000000..d846217
--- /dev/null
+++ b/src/build.c
@@ -0,0 +1,69 @@
+#include <errno.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "build.h"
+#include "queue.h"
+#include "jobs.h"
+#include "util.h"
+
+static int build(struct queue *queue);
+
+void *build_thread_entry(void *build_thread)
+{
+ struct build_thread *bt = build_thread;
+ int ret = 0;
+
+ while (true) {
+ ret = sem_wait(&bt->queue->sem);
+ if (ret < 0) {
+ print_err("%s", strerror(errno));
+ goto out;
+ }
+
+ if (CIRCLEQ_EMPTY(&bt->queue->jobs)) {
+ if (bt->queue->state == Q_ITS_OVER)
+ goto out;
+ else if (bt->queue->state == Q_SEM_WAIT)
+ continue;
+ }
+
+ ret = build(bt->queue);
+ if (ret < 0)
+ goto out;
+ }
+
+out:
+ pthread_exit(NULL);
+}
+
+static int build(struct queue *queue) {
+ struct job *job;
+ int ret = 0;
+
+ ret = queue_pop(queue, &job);
+ if (ret < 0)
+ return ret;
+
+ printf("nix build %s^*\n", job->drv_path);
+ job_free(job);
+
+ return 0;
+}
+
+int build_thread_new(struct build_thread **build_thread, struct queue *q)
+{
+ struct build_thread *bt = NULL;
+
+ bt = malloc(sizeof(*bt));
+ if (bt == NULL) {
+ print_err("%s", strerror(errno));
+ return -errno;
+ }
+ bt->queue = q;
+
+ *build_thread = bt;
+ return 0;
+}
diff --git a/src/evanix.c b/src/evanix.c
index dcac070..e83d0ea 100644
--- a/src/evanix.c
+++ b/src/evanix.c
@@ -1,12 +1,14 @@
#include <stdlib.h>
#include <string.h>
+#include "build.h"
#include "queue.h"
#include "util.h"
int main(void)
{
struct queue_thread *queue_thread = NULL;
+ struct build_thread *build_thread = NULL;
FILE *stream = NULL;
int ret = 0;
@@ -20,22 +22,40 @@ int main(void)
goto out_free;
}
+ ret = build_thread_new(&build_thread, queue_thread->queue);
+ if (ret < 0) {
+ free(stream);
+ goto out_free;
+ }
+
ret = pthread_create(&queue_thread->tid, NULL, queue_thread_entry,
queue_thread);
if (ret < 0) {
print_err("%s", strerror(ret));
- ret = -ret;
+ goto out_free;
+ }
+
+ ret = pthread_create(&build_thread->tid, NULL, build_thread_entry,
+ build_thread);
+ if (ret < 0) {
+ print_err("%s", strerror(ret));
goto out_free;
}
ret = pthread_join(queue_thread->tid, NULL);
if (ret < 0) {
print_err("%s", strerror(ret));
- ret = -ret;
+ goto out_free;
+ }
+
+ ret = pthread_join(build_thread->tid, NULL);
+ if (ret < 0) {
+ print_err("%s", strerror(ret));
goto out_free;
}
out_free:
queue_thread_free(queue_thread);
+ free(build_thread);
exit(ret < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
}
diff --git a/src/meson.build b/src/meson.build
index bb68e18..41b31da 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -5,6 +5,7 @@ e = executable(
'jobs.c',
'util.c',
'queue.c',
+ 'build.c',
],
include_directories: evanix_inc,
diff --git a/src/queue.c b/src/queue.c
index 6bf9092..746750e 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -8,6 +8,8 @@
#include "queue.h"
#include "util.h"
+static void queue_push(struct queue *queue, struct job *job);
+
void *queue_thread_entry(void *queue_thread)
{
struct queue_thread *qt = queue_thread;
@@ -17,23 +19,51 @@ void *queue_thread_entry(void *queue_thread)
while (true) {
ret = job_read(qt->stream, &job);
if (ret == -EOF) {
+ qt->queue->state = Q_ITS_OVER;
+ sem_post(&qt->queue->sem);
+
ret = 0;
break;
} else if (ret < 0) {
break;
}
- pthread_mutex_lock(&qt->queue->mutex);
- CIRCLEQ_INSERT_TAIL(&qt->queue->jobs, job, clist);
- pthread_mutex_unlock(&qt->queue->mutex);
+ queue_push(qt->queue, job);
}
pthread_exit(NULL);
}
+int queue_pop(struct queue *queue, struct job **job)
+{
+ struct job *j = CIRCLEQ_FIRST(&queue->jobs);
+
+ if (CIRCLEQ_EMPTY(&queue->jobs)) {
+ print_err("%s", "Empty queue");
+ return -EPERM;
+ }
+
+ pthread_mutex_lock(&queue->mutex);
+ CIRCLEQ_REMOVE(&queue->jobs, j, clist);
+ pthread_mutex_unlock(&queue->mutex);
+
+ *job = j;
+ return 0;
+}
+
+static void queue_push(struct queue *queue, struct job *job)
+{
+ pthread_mutex_lock(&queue->mutex);
+ CIRCLEQ_INSERT_TAIL(&queue->jobs, job, clist);
+ pthread_mutex_unlock(&queue->mutex);
+
+ sem_post(&queue->sem);
+}
+
void queue_thread_free(struct queue_thread *queue_thread)
{
struct job *job;
+ int ret;
if (queue_thread == NULL)
return;
@@ -43,6 +73,13 @@ void queue_thread_free(struct queue_thread *queue_thread)
free(job);
}
+ ret = sem_destroy(&queue_thread->queue->sem);
+ if (ret < 0)
+ print_err("%s", strerror(errno));
+ ret = pthread_mutex_destroy(&queue_thread->queue->mutex);
+ if (ret < 0)
+ print_err("%s", strerror(errno));
+
free(queue_thread->queue);
fclose(queue_thread->stream);
}
@@ -57,7 +94,6 @@ int queue_thread_new(struct queue_thread **queue_thread, FILE *stream)
print_err("%s", strerror(errno));
return -errno;
}
-
qt->stream = stream;
qt->queue = malloc(sizeof(*qt->queue));
@@ -66,6 +102,14 @@ int queue_thread_new(struct queue_thread **queue_thread, FILE *stream)
ret = -errno;
goto out_free;
}
+ qt->queue->state = Q_SEM_WAIT;
+ ret = sem_init(&qt->queue->sem, 0, 0);
+ if (ret < 0) {
+ print_err("%s", strerror(errno));
+ ret = -errno;
+ goto out_free;
+ }
+
CIRCLEQ_INIT(&qt->queue->jobs);
pthread_mutex_init(&qt->queue->mutex, NULL);