# HG changeset patch # User John Tsiombikas # Date 1391397729 -7200 # Node ID 410c19c735b2b6eaffb42faec068bbe9b8392e34 # Parent bd9b4ff19c93132de2b85413c50f44c975a353ac - removed the glew dependency - initial thread pool implementation diff -r bd9b4ff19c93 -r 410c19c735b2 examples/imgthumbs/src/main.c --- a/examples/imgthumbs/src/main.c Sat Feb 01 08:02:08 2014 +0200 +++ b/examples/imgthumbs/src/main.c Mon Feb 03 05:22:09 2014 +0200 @@ -57,8 +57,6 @@ static int init(void) { - glewInit(); - thumbs = create_thumbs(path); return 0; } diff -r bd9b4ff19c93 -r 410c19c735b2 examples/imgthumbs/src/opengl.h --- a/examples/imgthumbs/src/opengl.h Sat Feb 01 08:02:08 2014 +0200 +++ b/examples/imgthumbs/src/opengl.h Mon Feb 03 05:22:09 2014 +0200 @@ -1,8 +1,6 @@ #ifndef OPENGL_H_ #define OPENGL_H_ -#include - #ifdef __APPLE__ #include #else diff -r bd9b4ff19c93 -r 410c19c735b2 examples/imgthumbs/src/thumbs.c --- a/examples/imgthumbs/src/thumbs.c Sat Feb 01 08:02:08 2014 +0200 +++ b/examples/imgthumbs/src/thumbs.c Mon Feb 03 05:22:09 2014 +0200 @@ -7,6 +7,10 @@ #include "opengl.h" #include "thumbs.h" +#ifndef GL_COMPRESSED_RGB +#define GL_COMPRESSED_RGB 0x84ed +#endif + struct thumbnail *create_thumbs(const char *dirpath) { DIR *dir; @@ -14,7 +18,7 @@ struct thumbnail *list = 0; unsigned int intfmt = GL_COMPRESSED_RGB; - if(!GLEW_ARB_texture_compression) { + if(!strstr(glGetString(GL_EXTENSIONS), "GL_ARB_texture_compression")) { printf("warning, no texture compression available.\n"); intfmt = GL_RGB; } diff -r bd9b4ff19c93 -r 410c19c735b2 src/resman.h --- a/src/resman.h Sat Feb 01 08:02:08 2014 +0200 +++ b/src/resman.h Mon Feb 03 05:22:09 2014 +0200 @@ -12,6 +12,10 @@ struct resman; +#ifdef __cplusplus +extern "C" { +#endif + struct resman *resman_create(void); void resman_free(struct resman *rman); @@ -31,5 +35,9 @@ void resman_set_res_data(struct resman *rman, int res_id, void *data); void *resman_get_res_data(struct resman *rman, int res_id); +#ifdef __cplusplus +} +#endif + #endif /* RESOURCE_MANAGER_H_ */ diff -r bd9b4ff19c93 -r 410c19c735b2 src/threadpool.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/threadpool.c Mon Feb 03 05:22:09 2014 +0200 @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#include "threadpool.h" + +struct work_item { + void *data; + struct work_item *next; +}; + +struct thread_pool { + pthread_t *workers; + int num_workers; + + pthread_mutex_t work_lock; + pthread_cond_t work_cond; + + tpool_work_func work_func; + void *cls; + + struct work_item *work_list, *work_list_tail; + int work_count; +}; + + +static void *thread_func(void *tp); +static struct work_item *alloc_node(void); +static void free_node(struct work_item *node); +static int get_processor_count(void); + + + +int tpool_init(struct thread_pool *tpool, int num_threads) +{ + int i; + + memset(tpool, 0, sizeof *tpool); + + if(num_threads <= 0) { + num_threads = get_processor_count(); + } + tpool->num_workers = num_threads; + + printf("initializing thread pool with %d worker threads\n", num_threads); + + for(i=0; iworkers + i, 0, thread_func, tpool) == -1) { + fprintf(stderr, "%s: failed to create thread %d\n", __FUNCTION__, i); + tpool_destroy(tpool); + return -1; + } + } + + pthread_mutex_init(&tpool->work_lock, 0); + pthread_cond_init(&tpool->work_cond, 0); + return 0; +} + +void tpool_destroy(struct thread_pool *tpool) +{ + int i; + for(i=0; inum_workers; i++) { + void *ret; + pthread_join(tpool->workers[i], &ret); + } + + pthread_mutex_destroy(&tpool->work_lock); + pthread_cond_destroy(&tpool->work_cond); +} + +void tpool_set_work_func(struct thread_pool *tpool, tpool_work_func func, void *cls) +{ + tpool->work_func = func; + tpool->cls = cls; +} + +int tpool_add_work(struct thread_pool *tpool, void *data) +{ + struct work_item *node; + + if(!(node = alloc_node())) { + fprintf(stderr, "%s: failed to allocate new work item node\n", __FUNCTION__); + return -1; + } + node->data = data; + node->next = 0; + + pthread_mutex_lock(&tpool->work_lock); + + if(!tpool->work_list) { + tpool->work_list = tpool->work_list_tail = node; + } else { + tpool->work_list_tail->next = node; + tpool->work_list_tail = node; + } + + pthread_mutex_unlock(&tpool->work_lock); + return 0; +} + + +static void *thread_func(void *tp) +{ + struct work_item *job; + struct thread_pool *tpool = tp; + + pthread_mutex_lock(&tpool->work_lock); + for(;;) { + /* while there aren't any work items to do go to sleep on the condvar */ + pthread_cond_wait(&tpool->work_cond, &tpool->work_lock); + if(!tpool->work_list) { + continue; /* spurious wakeup, go back to sleep */ + } + + job = tpool->work_list; + tpool->work_list = tpool->work_list->next; + + tpool->work_func(job->data, tpool->cls); + } + pthread_mutex_unlock(&tpool->work_lock); + return 0; +} + +/* TODO: custom allocator */ +static struct work_item *alloc_node(void) +{ + return malloc(sizeof(struct work_item)); +} + +static void free_node(struct work_item *node) +{ + free(node); +} + +/* The following highly platform-specific code detects the number + * of processors available in the system. It's used by the thread pool + * to autodetect how many threads to spawn. + * Currently works on: Linux, BSD, Darwin, and Windows. + */ + +#if defined(__APPLE__) && defined(__MACH__) +# ifndef __unix__ +# define __unix__ 1 +# endif /* unix */ +# ifndef __bsd__ +# define __bsd__ 1 +# endif /* bsd */ +#endif /* apple */ + +#if defined(unix) || defined(__unix__) +#include + +# ifdef __bsd__ +# include +# endif +#endif + +#if defined(WIN32) || defined(__WIN32__) +#include +#endif + + +static int get_processor_count(void) +{ +#if defined(unix) || defined(__unix__) +# if defined(__bsd__) + /* BSD systems provide the num.processors through sysctl */ + int num, mib[] = {CTL_HW, HW_NCPU}; + size_t len = sizeof num; + + sysctl(mib, 2, &num, &len, 0, 0); + return num; + +# elif defined(__sgi) + /* SGI IRIX flavour of the _SC_NPROC_ONLN sysconf */ + return sysconf(_SC_NPROC_ONLN); +# else + /* Linux (and others?) have the _SC_NPROCESSORS_ONLN sysconf */ + return sysconf(_SC_NPROCESSORS_ONLN); +# endif /* bsd/sgi/other */ + +#elif defined(WIN32) || defined(__WIN32__) + /* under windows we need to call GetSystemInfo */ + SYSTEM_INFO info; + GetSystemInfo(&info); + return info.dwNumberOfProcessors; +#endif +} diff -r bd9b4ff19c93 -r 410c19c735b2 src/threadpool.h --- a/src/threadpool.h Sat Feb 01 08:02:08 2014 +0200 +++ b/src/threadpool.h Mon Feb 03 05:22:09 2014 +0200 @@ -3,7 +3,7 @@ struct thread_pool; -typedef void (*tpool_work_func)(void*); +typedef void (*tpool_work_func)(void *data, void *cls); #define TPOOL_AUTO 0 int tpool_init(struct thread_pool *tpool, int num_threads); @@ -11,6 +11,6 @@ void tpool_set_work_func(struct thread_pool *tpool, tpool_work_func func, void *cls); -/* TODO cont. */ +int tpool_add_work(struct thread_pool *tpool, void *data); #endif /* THREAD_POOL_H_ */