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);