#include #include #include #include #include #include #include "threadpool.h" // use gcc builtin fetch_and_add 0->no 1->yes #define DO_ATOMIC_FETCH_AND_ADD 0 struct threadpool { int max_threads; int current_threads; int busy_threads; pthread_t pids[]; }; int threadpool_create(THREADPOOL *threadpoolptr, int max_threads) { size_t size = sizeof (struct threadpool) + max_threads*sizeof (pthread_t); struct threadpool *threadpool = (struct threadpool *) malloc(size); if (threadpool == 0) return ENOMEM; threadpool->max_threads = max_threads; threadpool->current_threads = 0; threadpool->busy_threads = 0; int i; for (i=0; ipids[i] = 0; *threadpoolptr = threadpool; return 0; } void threadpool_destroy(THREADPOOL *threadpoolptr) { struct threadpool *threadpool = *threadpoolptr; int i; for (i=0; icurrent_threads; i++) { int r; void *ret; r = pthread_join(threadpool->pids[i], &ret); assert(r == 0); } *threadpoolptr = 0; free(threadpool); } void threadpool_maybe_add(THREADPOOL threadpool, void *(*f)(void *), void *arg) { if (threadpool->current_threads < threadpool->max_threads) { int r = pthread_create(&threadpool->pids[threadpool->current_threads], 0, f, arg); if (r == 0) { threadpool->current_threads++; threadpool_set_thread_busy(threadpool); } } } void threadpool_set_thread_busy(THREADPOOL threadpool) { #if DO_ATOMIC_FETCH_AND_ADD (void) __sync_fetch_and_add(&threadpool->busy_threads, 1); #else threadpool->busy_threads++; #endif } void threadpool_set_thread_idle(THREADPOOL threadpool) { #if DO_ATOMIC_FETCH_AND_ADD (void) __sync_fetch_and_add(&threadpool->busy_threads, -1); #else threadpool->busy_threads--; #endif } int threadpool_get_current_threads(THREADPOOL threadpool) { return threadpool->current_threads; }