diff options
author | sinanmohd <sinan@sinanmohd.com> | 2024-06-14 12:18:40 +0530 |
---|---|---|
committer | sinanmohd <sinan@sinanmohd.com> | 2024-06-14 18:53:40 +0530 |
commit | 58fe7d147774960e3fb7dbc53a3e5ecf106ebf01 (patch) | |
tree | 0b8651b5a69666605125c05ee18ee68bd13308e1 | |
parent | 6627adcbc2d2ade8db1fd2ed26e03d37b53fde62 (diff) |
build: init
-rw-r--r-- | include/build.h | 12 | ||||
-rw-r--r-- | include/jobs.h | 5 | ||||
-rw-r--r-- | include/queue.h | 14 | ||||
-rw-r--r-- | src/build.c | 69 | ||||
-rw-r--r-- | src/evanix.c | 24 | ||||
-rw-r--r-- | src/meson.build | 1 | ||||
-rw-r--r-- | src/queue.c | 52 |
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); |