Search code examples
cmultithreadingmemory-managementdynamic-memory-allocation

Best way of dynamic memory request in a rapidly called short function


I'm coding a dynamic website with C and FCGI which will be running in multiple threads (compiled by clang 3.1).

I have for each grounding HTML page a own function. Inside some of them they are allocating some mini sprites which are building a randomly generated map for example.

Now when I'm about to request the memory for the page which will be fired into stdout at end of the function and the memory isn't needed anymore until next call.

My first Idea was of simply declaring a automatic pointer and doing it like this:

Sprite *Identifier = malloc (CURRENT_SPRITES * SIZE_OFSPRITE);
/*...*/
free (Identifier);

But when the page would be going to get accessed multiple thousand times per thread this would be slowing down the server drasticly, wouldn't it?

So my next idea was as I know the max amount of sprites I want my server to be supporting, I could just do:

Sprite Identifier[MAX_SPIRTES_PER_MAP];
/*...*/

But this is just a pain in my eyes when I'm concerning the amount of stack memory this would take.

So I was thinking about something like:

static inttype DynamicCurrentAmount = 0;
static Sprite *Identifier;

somethreadsafingmutexfunctionLOCK();

if (DynamicCurrentAmount == 0)
{
    Identifier = malloc (ParamRecivedByFunctionCall* sizeof (Sprite));        
    ReturnValCheck(Identifier);
}

if (DynamicMaxAmount < ParamRecivedByFunctionCall)
{
    DynamicMaxAmount = ParamRecivedByFunctionCall;
    Identifier = realloc (Identifier, ParamRecivedByFunctionCall* sizeof (Sprite));        
    ReturnValCheck(Identifier);
}

somethreadsafingmutexfunctionUNLOCK();

But the cons of this Way is, just 1 Client per time could get served the HTML page by his thread. And additional I'm not sure, under which conditions could even the lock/unlock take more time as a simple memory allocation?

And my last and probably crayziest idea was this one:

Sprite Identifier[(strlen ("some HTML stuff per Sprite in map")) * ParamRecivedByFunction) + strlen ("htmlbased sprite map table torso")];

As I'm in pure C99 and not using VisualC and I'm in function scope, I would be able to use a variable length array.

But I never really used it before and I have not a clue whats the taken time of allocating such kind of array on the stack in relation to the taken time of my other ideas.

Is here anyone who could point me the advantages and disadvantages of this methods of requesting my memory, and give me a hint what could be the best way (or maybe a different one) for my situation?


Solution

  • If you compile your program with GCC, you can use thread-local storage.

    static __thread Sprite* Identifier = malloc(CURRENT_SPRITES * SIZE_OFSPRITE);
    /* Clear Identifier's content */
    /* ... */
    /* Do not free it. Just reuse it at the next function call. */
    

    By thread local storage, the static __thread local variable's lifetime is the same as the thread. Thus, you could allocate it once and reuse many times so the time for (de)allocation is saved. Also, since different thread owns different copy of thread local variable, you don't require mutex (un)lock to prevent data race. Thus, the thread efficiency is still high.

    Allocating the variable on stack is the simplest. However as you said, the stack size is limited. Also, calling strlen() for the same string again and again for each call doesn't look like a good idea.