diff -urN rt_v42/img.c rt_v43/img.c --- rt_v42/img.c 2018-05-29 21:41:28.000000000 +0900 +++ rt_v43/img.c 2018-05-30 21:34:32.000000000 +0900 @@ -122,15 +122,63 @@ } static struct ut_cache_tbl cache_tbl = { - 256, NULL, ut_cache_geti_int, + 256, 0, NULL, ut_cache_geti_int, }; struct img_col_cache_inf{ - int w, h, frn; + int fn, w, h, frn; double fps; struct ut_cache_tbl img_tbl; }; +struct i_img{ + int i; + unsigned char *img; +}; + +static struct img_col_cache_inf * +get_inf(int fn) +{ + struct img_col_cache_inf *inf = ut_cache_get(&cache_tbl, &fn, sizeof(fn)); + if(!inf){ + int wh[2]; + + inf = malloc( sizeof(*inf) ); + inf->fn = fn; + img_wh(fn, wh); + inf->w = wh[0]; + inf->h = wh[1]; + inf->frn = img_frn(fn); + inf->fps = img_fps(fn); + + inf->img_tbl.n = 2; /* ! */ + inf->img_tbl.chain_max_n = 1; /* ! */ + inf->img_tbl.tbl = NULL; + inf->img_tbl.geti = ut_cache_geti_int; + ut_cache_alloc(&inf->img_tbl); + + ut_cache_set(&cache_tbl, &inf->fn, sizeof(inf->fn), inf); + } + return inf; +} + +static unsigned char * +get_img(struct ut_cache_tbl *img_tbl, int i, int fn, double sec) +{ + struct i_img *del_v, *p = ut_cache_get(img_tbl, &i, sizeof(i)); + if(!p){ + p = malloc( sizeof(*p) ); + p->i = i; + p->img = img_col_wh(fn, sec, NULL); + del_v = ut_cache_set(img_tbl, &p->i, sizeof(p->i), p); + if(del_v){ + free(del_v->img); + free(del_v); + } + } + return p->img; +} + void rep_xy(int *px, int *py, int w, int h, int rep_x, int rep_y) { @@ -145,11 +193,12 @@ *py = y; } +pthread_mutex_t lock_inf = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t lock_img = PTHREAD_MUTEX_INITIALIZER; + void img_col_cache(int fn, double sec, int x, int y, int *def_col, int rep_x, int rep_y, int *ret_col) { - void *k = &fn; - int ksz = sizeof(fn); struct img_col_cache_inf *inf; int i; unsigned char *img; @@ -158,24 +207,9 @@ ut_cache_alloc(&cache_tbl); } - inf = ut_cache_get(&cache_tbl, k, ksz); - if(!inf){ - int wh[2]; - - inf = malloc( sizeof(*inf) ); - img_wh(fn, wh); - inf->w = wh[0]; - inf->h = wh[1]; - inf->frn = img_frn(fn); - inf->fps = img_fps(fn); - - inf->img_tbl.n = inf->frn; - inf->img_tbl.tbl = NULL; - inf->img_tbl.geti = ut_cache_geti_int; - ut_cache_alloc(&inf->img_tbl); - - ut_cache_set(&cache_tbl, k, ksz, inf); - } + pthread_mutex_lock(&lock_inf); + inf = get_inf(fn); + pthread_mutex_unlock(&lock_inf); if(!in_wh(x, y, inf->w, inf->h)){ if(!rep_x && !rep_y){ @@ -189,11 +223,9 @@ i = (int)(inf->fps * sec) % inf->frn; - img = ut_cache_get(&inf->img_tbl, &i, sizeof(i)); - if(!img){ - img = img_col_wh(fn, sec, NULL); - ut_cache_set(&inf->img_tbl, &i, sizeof(i), img); - } + pthread_mutex_lock(&lock_img); + img = get_img(&inf->img_tbl, i, fn, sec); + pthread_mutex_unlock(&lock_img); i = (y * inf->w + x) * 3; *ret_col++ = img[i++]; diff -urN rt_v42/ut.c rt_v43/ut.c --- rt_v42/ut.c 2018-05-30 11:36:27.000000000 +0900 +++ rt_v43/ut.c 2018-05-30 20:09:11.000000000 +0900 @@ -108,9 +108,10 @@ return p ? p->v : NULL; } -void +void * ut_cache_set(struct ut_cache_tbl *t, void *k, int ksz, void *v) { + void *del_v = NULL; int i = (*t->geti)(k, ksz) % t->n; struct ut_cache *p = malloc( sizeof(*p) ); p->k = k; @@ -118,17 +119,33 @@ p->v = v; p->next = t->tbl[i]; t->tbl[i] = p; + + if(t->chain_max_n > 0){ + for(i=0; ichain_max_n; i++){ + if(!p){ + break; + } + p = p->next; + } + if(p){ /* ! 1 */ + del_v = ut_cache_del(t, p->k, p->ksz); + } + } + return del_v; } -void +void * ut_cache_del(struct ut_cache_tbl *t, void *k, int ksz) { + void *v = NULL; struct ut_cache **pp = ut_cache_get_pptr(t, k, ksz); if(pp){ struct ut_cache *p = *pp; *pp = p->next; + v = p->v; free(p); } + return v; } void @@ -140,7 +157,7 @@ struct ut_cache *p = t->tbl[i]; while(p){ struct ut_cache *n = p->next; - free(p); + free(p); /* ! p->v not free */ p = n; } } diff -urN rt_v42/ut.h rt_v43/ut.h --- rt_v42/ut.h 2018-05-30 11:35:55.000000000 +0900 +++ rt_v43/ut.h 2018-05-30 20:09:11.000000000 +0900 @@ -29,6 +29,7 @@ struct ut_cache_tbl{ int n; + int chain_max_n; /* <= 0 : no limit */ struct ut_cache **tbl; int (*geti)(void *k, int ksz); }; @@ -37,8 +38,8 @@ struct ut_cache **ut_cache_get_pptr(struct ut_cache_tbl *t, void *k, int ksz); struct ut_cache *ut_cache_get_ptr(struct ut_cache_tbl *t, void *k, int ksz); void *ut_cache_get(struct ut_cache_tbl *t, void *k, int ksz); -void ut_cache_set(struct ut_cache_tbl *t, void *k, int ksz, void *v); -void ut_cache_del(struct ut_cache_tbl *t, void *k, int ksz); +void *ut_cache_set(struct ut_cache_tbl *t, void *k, int ksz, void *v); +void *ut_cache_del(struct ut_cache_tbl *t, void *k, int ksz); void ut_cache_free(struct ut_cache_tbl *t); int ut_cache_geti_int(void *k, int ksz);