commit aebc8255cb23a657a06c99fdd1bd59848feff327 Author: Dnomd343 Date: Tue Jan 31 10:11:19 2023 +0800 feat: framework of tiny thread pool diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4475b96 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/cmake-build-debug/ +/cmake-build-release/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2b2a0a7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.0) + +set(CMAKE_C_STANDARD 99) + +project(tiny_thread_pool LANGUAGES C) + +add_executable(tiny_pool main.c tiny_pool.c) +target_link_libraries(tiny_pool pthread) diff --git a/main.c b/main.c new file mode 100644 index 0000000..08fe349 --- /dev/null +++ b/main.c @@ -0,0 +1,23 @@ +#include +#include +#include "tiny_pool.h" + +void* demo_fun(void *i) { + printf("demo func -> %d\n", *(int*)i); + return NULL; +} + +int main() { + + pthread_t tid; + + int d = 123; + + pool_t *pool = tiny_pool_create(0); + + tiny_pool_submit(pool, demo_fun, (void*)&d); + + + + return 0; +} diff --git a/tiny_pool.c b/tiny_pool.c new file mode 100644 index 0000000..7f76da7 --- /dev/null +++ b/tiny_pool.c @@ -0,0 +1,100 @@ +#include +#include "tiny_pool.h" + +pool_t* tiny_pool_create(uint32_t size) { + + pool_t *pool = (pool_t*)malloc(sizeof(pool_t)); + + for (int i = 0; i < 8; ++i) { + pool->threads[i] = 0; + } + + pool->task_queue_front = NULL; + pool->task_queue_rear = NULL; + pool->task_queue_size = 0; + + return pool; + +} + +void tiny_pool_submit(pool_t *pool, void* (*func)(void*), void *arg) { + + task_t *new_task = (task_t*)malloc(sizeof(task_t)); + + new_task->func = func; + new_task->arg = arg; + new_task->next = NULL; + + // TODO: lock task queue + + if (pool->task_queue_rear == NULL) { // queue without element + + pool->task_queue_front = new_task; + pool->task_queue_rear = new_task; + + } else { // queue emplace back + + pool->task_queue_rear->next = new_task; + pool->task_queue_rear = new_task; + + } + + ++pool->task_queue_size; + + // TODO: unlock task queue + +} + +task_t* task_queue_pop(pool_t *pool) { + + // TODO: lock task queue + + if (pool->task_queue_front == NULL) { + + return NULL; // pop failed -> empty queue + + } + + task_t *tmp = pool->task_queue_front; + + if (pool->task_queue_front == pool->task_queue_rear) { + + // queue is empty now + pool->task_queue_front = NULL; + pool->task_queue_rear = NULL; + + } else { + + pool->task_queue_front = tmp->next; + + } + + // TODO: unlock task queue + + return tmp; + +} + + +void* thread_working() { + + // TODO: main loop for one thread + + // TODO: check if thread pool exiting + + // TODO: pop one task --failed--> blocking wait + // --success--> start running and then free task_t + + return NULL; + +} + + +void tiny_pool_boot(pool_t *pool) { + + // TODO: create admin thread + + // TODO: create N work-threads (using N = 8 in dev) + +} + diff --git a/tiny_pool.h b/tiny_pool.h new file mode 100644 index 0000000..2c8a01d --- /dev/null +++ b/tiny_pool.h @@ -0,0 +1,37 @@ +#ifndef TINY_POOL_H_ +#define TINY_POOL_H_ + +#include +#include + +typedef struct task_t { + void* (*func)(void*); + void *arg; + struct task_t *next; +} task_t; + + +typedef struct { + + pthread_t threads[8]; + + task_t *task_queue_front; + task_t *task_queue_rear; + uint32_t task_queue_size; + pthread_mutex_t task_queue_busy; + +} pool_t; + + +pool_t* tiny_pool_create(uint32_t size); + +void tiny_pool_submit(pool_t *pool, void* (*func)(void*), void *arg); + +// TODO: confirm just run once +void tiny_pool_boot(pool_t *pool); + +// TODO: thread pool status -> preparing / running / exiting / exited + +// TODO: destroy method + +#endif