commit
						aebc8255cb
					
				 5 changed files with 170 additions and 0 deletions
			
			
		@ -0,0 +1,2 @@ | 
				
			|||
/cmake-build-debug/ | 
				
			|||
/cmake-build-release/ | 
				
			|||
@ -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) | 
				
			|||
@ -0,0 +1,23 @@ | 
				
			|||
#include <stdio.h> | 
				
			|||
#include <pthread.h> | 
				
			|||
#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; | 
				
			|||
} | 
				
			|||
@ -0,0 +1,100 @@ | 
				
			|||
#include <malloc.h> | 
				
			|||
#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)
 | 
				
			|||
 | 
				
			|||
} | 
				
			|||
 | 
				
			|||
@ -0,0 +1,37 @@ | 
				
			|||
#ifndef TINY_POOL_H_ | 
				
			|||
#define TINY_POOL_H_ | 
				
			|||
 | 
				
			|||
#include <stdint.h> | 
				
			|||
#include <pthread.h> | 
				
			|||
 | 
				
			|||
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 | 
				
			|||
					Loading…
					
					
				
		Reference in new issue