Created threadsafe MEM_malloc versions in BLI_threads.h, now in use

for compositing code.

Officially malloc/calloc/free is threadsafe, but our secure malloc system
requires all memory blocks to be stored in a single list, so when two
threads write in this list you get conflicts.
This commit is contained in:
Ton Roosendaal
2006-01-30 11:09:50 +00:00
parent 18ab7c468f
commit e193648595
4 changed files with 57 additions and 23 deletions

View File

@@ -50,8 +50,8 @@
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
#include "BLI_threads.h"
#include "MEM_guardedalloc.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -74,16 +74,16 @@ typedef struct CompBuf {
static CompBuf *alloc_compbuf(int sizex, int sizey, int type, int alloc)
{
CompBuf *cbuf= MEM_callocN(sizeof(CompBuf), "compbuf");
CompBuf *cbuf= MEM_callocT(sizeof(CompBuf), "compbuf");
cbuf->x= sizex;
cbuf->y= sizey;
cbuf->type= type;
if(alloc) {
if(cbuf->type==CB_RGBA)
cbuf->rect= MEM_mallocN(4*sizeof(float)*sizex*sizey, "compbuf RGBA rect");
cbuf->rect= MEM_mallocT(4*sizeof(float)*sizex*sizey, "compbuf RGBA rect");
else
cbuf->rect= MEM_mallocN(sizeof(float)*sizex*sizey, "compbuf Fac rect");
cbuf->rect= MEM_mallocT(sizeof(float)*sizex*sizey, "compbuf Fac rect");
cbuf->malloc= 1;
}
cbuf->disprect.xmin= 0;
@@ -97,8 +97,8 @@ static CompBuf *alloc_compbuf(int sizex, int sizey, int type, int alloc)
void free_compbuf(CompBuf *cbuf)
{
if(cbuf->malloc && cbuf->rect)
MEM_freeN(cbuf->rect);
MEM_freeN(cbuf);
MEM_freeT(cbuf->rect);
MEM_freeT(cbuf);
}
void print_compbuf(char *str, CompBuf *cbuf)
@@ -525,7 +525,7 @@ static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **i
CompBuf *outbuf, *zbuf=NULL;
if(rr->rectf)
MEM_freeN(rr->rectf);
MEM_freeT(rr->rectf);
outbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 1);
if(in[1]->data==NULL)
@@ -535,7 +535,7 @@ static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **i
if(in[2]->data) {
if(rr->rectz)
MEM_freeN(rr->rectz);
MEM_freeT(rr->rectz);
zbuf= alloc_compbuf(rr->rectx, rr->recty, CB_VAL, 1);
composit1_pixel_processor(node, zbuf, in[2]->data, in[2]->vec, do_copy_value);
rr->rectz= zbuf->rect;
@@ -1398,7 +1398,7 @@ static float *make_gausstab(int rad)
n = 2 * rad + 1;
gausstab = (float *) MEM_mallocN(n * sizeof(float), "gauss");
gausstab = (float *) MEM_mallocT(n * sizeof(float), "gauss");
sum = 0.0f;
for (i = -rad; i <= rad; i++) {
@@ -1421,7 +1421,7 @@ static float *make_bloomtab(int rad)
n = 2 * rad + 1;
bloomtab = (float *) MEM_mallocN(n * sizeof(float), "bloom");
bloomtab = (float *) MEM_mallocT(n * sizeof(float), "bloom");
for (i = -rad; i <= rad; i++) {
val = pow(1.0 - fabs((float)i)/((float)rad), 4.0);
@@ -1488,7 +1488,7 @@ static void blur_single_image(CompBuf *new, CompBuf *img, float blurx, float blu
}
/* vertical */
MEM_freeN(gausstab);
MEM_freeT(gausstab);
rad = ceil(blury);
if(rad>imgy/2)
@@ -1535,7 +1535,7 @@ static void blur_single_image(CompBuf *new, CompBuf *img, float blurx, float blu
}
free_compbuf(work);
MEM_freeN(gausstab);
MEM_freeT(gausstab);
}
/* reference has to be mapped 0-1, and equal in size */
@@ -1570,7 +1570,7 @@ static void bloom_with_reference(CompBuf *new, CompBuf *img, CompBuf *ref, float
rady= 1;
x= MAX2(radx, rady);
maintabs= MEM_mallocN(x*sizeof(void *), "gauss array");
maintabs= MEM_mallocT(x*sizeof(void *), "gauss array");
for(i= 0; i<x; i++)
maintabs[i]= make_bloomtab(i+1);
@@ -1654,8 +1654,8 @@ static void bloom_with_reference(CompBuf *new, CompBuf *img, CompBuf *ref, float
x= MAX2(radx, rady);
for(i= 0; i<x; i++)
MEM_freeN(maintabs[i]);
MEM_freeN(maintabs);
MEM_freeT(maintabs[i]);
MEM_freeT(maintabs);
}
@@ -1700,7 +1700,7 @@ static void blur_with_reference(CompBuf *new, CompBuf *img, CompBuf *ref, float
rady= 1;
x= MAX2(radx, rady);
maintabs= MEM_mallocN(x*sizeof(void *), "gauss array");
maintabs= MEM_mallocT(x*sizeof(void *), "gauss array");
for(i= 0; i<x; i++)
maintabs[i]= make_gausstab(i+1);
@@ -1763,8 +1763,8 @@ static void blur_with_reference(CompBuf *new, CompBuf *img, CompBuf *ref, float
x= MAX2(radx, rady);
for(i= 0; i<x; i++)
MEM_freeN(maintabs[i]);
MEM_freeN(maintabs);
MEM_freeT(maintabs[i]);
MEM_freeT(maintabs);
}

View File

@@ -35,10 +35,14 @@
void BLI_init_threads (ListBase *threadbase, int (*do_thread)(void *), int tot);
int BLI_available_threads(ListBase *threadbase);
int BLI_available_thread_index(ListBase *threadbase);
void BLI_insert_thread (ListBase *threadbase, void *callerdata);
void BLI_insert_thread (ListBase *threadbase, void *callerdata);
void BLI_remove_thread (ListBase *threadbase, void *callerdata);
void BLI_end_threads (ListBase *threadbase);
/* threadsafe version of MEM_malloc and friends */
void *MEM_mallocT(int len, char *name);
void *MEM_callocT(int len, char *name);
void MEM_freeT(void *poin);
#endif

View File

@@ -82,6 +82,7 @@ A sample loop can look like this (pseudo c);
BLI_end_threads(&lb);
************************************************ */
static SDL_mutex *_malloc_lock= NULL;
/* just a max for security reasons */
#define RE_MAX_THREAD 8
@@ -94,8 +95,6 @@ typedef struct ThreadSlot {
int avail;
} ThreadSlot;
static ThreadSlot threadslots[RE_MAX_THREAD];
void BLI_init_threads(ListBase *threadbase, int (*do_thread)(void *), int tot)
{
int a;
@@ -112,6 +111,8 @@ void BLI_init_threads(ListBase *threadbase, int (*do_thread)(void *), int tot)
BLI_addtail(threadbase, tslot);
tslot->do_thread= do_thread;
}
_malloc_lock = SDL_CreateMutex();
}
/* amount of available threads */
@@ -178,6 +179,35 @@ void BLI_end_threads(ListBase *threadbase)
}
}
BLI_freelistN(threadbase);
if(_malloc_lock) SDL_DestroyMutex(_malloc_lock);
_malloc_lock= NULL;
}
/* ***************** Thread safe MEM_malloc/calloc/free ************************** */
void *MEM_mallocT(int len, char *name)
{
void *mem;
if(_malloc_lock) SDL_mutexP(_malloc_lock);
mem= MEM_mallocN(len, name);
if(_malloc_lock) SDL_mutexV(_malloc_lock);
return mem;
}
void *MEM_callocT(int len, char *name)
{
void *mem;
if(_malloc_lock) SDL_mutexP(_malloc_lock);
mem= MEM_callocN(len, name);
if(_malloc_lock) SDL_mutexV(_malloc_lock);
return mem;
}
void MEM_freeT(void *poin)
{
if(_malloc_lock) SDL_mutexP(_malloc_lock);
MEM_freeN(poin);
if(_malloc_lock) SDL_mutexV(_malloc_lock);
}
/* eof */

View File

@@ -106,7 +106,7 @@ Render R;
/* ********* alloc and free ******** */
SDL_mutex *malloc_lock= NULL;
static SDL_mutex *malloc_lock= NULL;
void *RE_mallocN(int len, char *name)
{