libresman
changeset 17:43a9fe4a80ee
merged
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 11 Feb 2014 18:48:24 +0200 |
parents | 0a789208498d 2b8281a146af |
children | 711698580eb0 |
files | examples/imgthumbs/src/thumbs.c |
diffstat | 3 files changed, 54 insertions(+), 5 deletions(-) [+] |
line diff
1.1 --- a/examples/imgthumbs/src/thumbs.c Tue Feb 11 18:47:33 2014 +0200 1.2 +++ b/examples/imgthumbs/src/thumbs.c Tue Feb 11 18:48:24 2014 +0200 1.3 @@ -16,6 +16,7 @@ 1.4 #endif 1.5 1.6 struct resman *texman; 1.7 +struct thumbnail *dbg; 1.8 1.9 static int load_res_texture(const char *fname, int id, void *cls); 1.10 static int done_res_texture(int id, void *cls); 1.11 @@ -28,6 +29,7 @@ 1.12 struct dirent *dent; 1.13 /* allocate dummy head node */ 1.14 struct thumbnail *list = calloc(1, sizeof *list); 1.15 + dbg = list; 1.16 1.17 if(!texman) { 1.18 texman = resman_create(); 1.19 @@ -89,6 +91,7 @@ 1.20 1.21 node->next = list->next; 1.22 node->prev = list; 1.23 + list->next = node; 1.24 } 1.25 closedir(dir); 1.26 1.27 @@ -123,7 +126,7 @@ 1.28 float view_aspect; 1.29 1.30 glGetIntegerv(GL_VIEWPORT, vp); 1.31 - view_aspect = (float)(vp[2] - vp[0]) / (vp[3] - vp[1]); 1.32 + view_aspect = (float)(vp[2] - vp[0]) / (float)(vp[3] - vp[1]); 1.33 1.34 glMatrixMode(GL_PROJECTION); 1.35 glPushMatrix(); 1.36 @@ -134,6 +137,7 @@ 1.37 1.38 thumbs = thumbs->next; /* skip dummy node */ 1.39 while(thumbs) { 1.40 + printf("drawing thumb: %s\n", thumbs->fname); 1.41 glPushMatrix(); 1.42 glTranslatef(x, y, 0); 1.43 1.44 @@ -253,6 +257,8 @@ 1.45 { 1.46 struct thumbnail *thumb = resman_get_res_data(texman, id); 1.47 1.48 + printf("deleting thumb %d: %s\n", id, thumb->fname); 1.49 + 1.50 if(thumb) { 1.51 if(thumb->tex) { 1.52 glDeleteTextures(1, &thumb->tex);
2.1 --- a/src/resman.c Tue Feb 11 18:47:33 2014 +0200 2.2 +++ b/src/resman.c Tue Feb 11 18:48:24 2014 +0200 2.3 @@ -14,6 +14,7 @@ 2.4 int result; /* last callback-reported success/fail code */ 2.5 2.6 int done_pending; 2.7 + int delete_pending; 2.8 pthread_mutex_t done_lock; 2.9 }; 2.10 2.11 @@ -56,9 +57,16 @@ 2.12 2.13 int resman_init(struct resman *rman) 2.14 { 2.15 + const char *env; 2.16 + int num_threads = TPOOL_AUTO; 2.17 + 2.18 memset(rman, 0, sizeof *rman); 2.19 2.20 - if(!(rman->tpool = tpool_create(TPOOL_AUTO))) { 2.21 + if((env = getenv("RESMAN_THREADS"))) { 2.22 + num_threads = atoi(env); 2.23 + } 2.24 + 2.25 + if(!(rman->tpool = tpool_create(num_threads))) { 2.26 return -1; 2.27 } 2.28 tpool_set_work_func(rman->tpool, work_func, rman); 2.29 @@ -131,11 +139,27 @@ 2.30 { 2.31 int i, num_res; 2.32 2.33 + /* first check all the resources to see if any is pending deletion */ 2.34 + num_res = dynarr_size(rman->res); 2.35 + for(i=0; i<num_res; i++) { 2.36 + struct resource *res = rman->res[i]; 2.37 + if(!res) { 2.38 + continue; 2.39 + } 2.40 + 2.41 + if(res->delete_pending) { 2.42 + if(rman->destroy_func) { 2.43 + rman->destroy_func(i, rman->destroy_func_cls); 2.44 + } 2.45 + remove_resource(rman, i); 2.46 + } 2.47 + } 2.48 + 2.49 + 2.50 if(!rman->done_func) { 2.51 return 0; /* no done callback; there's no point in checking anything */ 2.52 } 2.53 2.54 - num_res = dynarr_size(rman->res); 2.55 for(i=0; i<num_res; i++) { 2.56 struct resource *res = rman->res[i]; 2.57 if(!res) { 2.58 @@ -278,8 +302,10 @@ 2.59 2.60 res->result = rman->load_func(res->name, res->id, rman->load_func_cls); 2.61 if(res->result == -1 && !rman->done_func) { 2.62 - /* if there's no done function and we got an error, remove the resource now */ 2.63 - remove_resource(rman, res->id); 2.64 + /* if there's no done function and we got an error, mark this 2.65 + * resource for deletion in the caller context 2.66 + */ 2.67 + res->delete_pending = 1; 2.68 return; 2.69 } 2.70
3.1 --- a/src/threadpool.c Tue Feb 11 18:47:33 2014 +0200 3.2 +++ b/src/threadpool.c Tue Feb 11 18:48:24 2014 +0200 3.3 @@ -5,6 +5,7 @@ 3.4 #include "threadpool.h" 3.5 3.6 struct work_item { 3.7 + int id; /* just for debugging messages */ 3.8 void *data; 3.9 struct work_item *next; 3.10 }; 3.11 @@ -106,6 +107,7 @@ 3.12 int tpool_add_work(struct thread_pool *tpool, void *data) 3.13 { 3.14 struct work_item *node; 3.15 + static int jcounter; 3.16 3.17 if(!(node = alloc_node())) { 3.18 fprintf(stderr, "%s: failed to allocate new work item node\n", __FUNCTION__); 3.19 @@ -115,6 +117,9 @@ 3.20 node->next = 0; 3.21 3.22 pthread_mutex_lock(&tpool->work_lock); 3.23 + node->id = jcounter++; 3.24 + 3.25 + printf("TPOOL: adding work item: %d\n", node->id); 3.26 3.27 if(!tpool->work_list) { 3.28 tpool->work_list = tpool->work_list_tail = node; 3.29 @@ -132,8 +137,17 @@ 3.30 3.31 static void *thread_func(void *tp) 3.32 { 3.33 + int i, tidx = -1; 3.34 struct work_item *job; 3.35 struct thread_pool *tpool = tp; 3.36 + pthread_t tid = pthread_self(); 3.37 + 3.38 + for(i=0; i<tpool->num_workers; i++) { 3.39 + if(tpool[i].workers[i] == tid) { 3.40 + tidx = i; 3.41 + break; 3.42 + } 3.43 + } 3.44 3.45 pthread_mutex_lock(&tpool->work_lock); 3.46 for(;;) { 3.47 @@ -143,11 +157,14 @@ 3.48 continue; /* spurious wakeup, go back to sleep */ 3.49 } 3.50 3.51 + printf("TPOOL: worker %d start job: %d\n", tidx, job->id); 3.52 + 3.53 job = tpool->work_list; 3.54 tpool->work_list = tpool->work_list->next; 3.55 3.56 tpool->work_func(job->data, tpool->cls); 3.57 3.58 + printf("TPOOL: worker %d completed job: %d\n", tidx, job->id); 3.59 free_node(job); 3.60 } 3.61 pthread_mutex_unlock(&tpool->work_lock);