aboutsummaryrefslogtreecommitdiff
path: root/src/threading/pool.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/threading/pool.c')
-rw-r--r--src/threading/pool.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/threading/pool.c b/src/threading/pool.c
new file mode 100644
index 0000000..266254e
--- /dev/null
+++ b/src/threading/pool.c
@@ -0,0 +1,95 @@
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <pthread.h>
+
+#include "cpu.h"
+#include "pool.h"
+
+struct worker_t {
+ struct pool_t* pool;
+ int id;
+};
+
+struct pool_t* pool_init()
+{
+ struct pool_t* pool = malloc(sizeof(struct pool_t));
+
+ pool->workers = get_core_count();
+ pool->tasks = NULL;
+ pool->task_next = NULL;
+ pool->pool_size = 0;
+ pool->condition = NULL;
+
+ return pool;
+}
+
+void pool_free(struct pool_t* pool)
+{
+ if (pool->tasks)
+ free(pool->tasks);
+ free(pool);
+}
+
+void pool_submit(struct pool_t* pool, worker_func func, void* arg)
+{
+ pool->pool_size++;
+ pool->tasks = realloc(pool->tasks, sizeof(struct pool_task_t) * (pool->pool_size));
+
+ struct pool_task_t* task = &pool->tasks[pool->pool_size-1];
+ task->func = func;
+ task->arg = arg;
+ task->done = 0;
+}
+
+static void* task_executor(void* pinfo)
+{
+ struct worker_t* worker = (struct worker_t*)pinfo;
+ struct pool_t* pool = worker->pool;
+
+ if (pool->task_next)
+ {
+ struct pool_task_t* pool_end = pool->tasks + pool->pool_size;
+ struct pool_task_t* task = pool->task_next++;
+ while (pool_end > task)
+ {
+ if (!task->done)
+ {
+ task->func(task->arg);
+ task->done = 1;
+ }
+
+ task = pool->task_next++;
+ }
+ }
+
+ return NULL;
+}
+
+void pool_complete(struct pool_t* pool)
+{
+ pthread_t* threads = malloc(sizeof(pthread_t) * pool->workers);
+ struct worker_t* workers = malloc(sizeof(struct worker_t) * pool->workers);
+
+ if (pool->pool_size)
+ pool->task_next = &pool->tasks[0];
+
+ for (int i = 0; i < pool->workers && (pool->condition == NULL || *pool->condition); ++i)
+ {
+ struct worker_t* worker = &workers[i];
+ pthread_t* thread = &threads[i];
+
+ worker->pool = pool;
+ worker->id = i;
+
+ pthread_create(thread, NULL, task_executor, worker);
+ }
+
+ for (int i = 0; i < pool->workers; ++i)
+ {
+ pthread_join(threads[i], NULL);
+ }
+
+ free(threads);
+ free(workers);
+} \ No newline at end of file