Jamie has a co-worker who subscribes to the “malloc is slow” school of thought. Now, for most programs, it’s fine, but Jamie works on a high-performance computing system operating in a massively parallel configuration, so there are portions of their application where that philosophy is completely valid.

In this case, however, the code Jamie’s co-worker wrote is in their message handling layer. There’s really no reason to pool buffers there, as the performance gain is practically non-existent based on the frequency of buffer allocation. That doesn’t change Jamie’s co-worker’s opinion though- malloc is slow.

void *buf_mem;
int *big_int_buf;
double *big_double_buf;
double **double_in, **double_out;
int **int_in, **int_out;
int num_connections, max_num_in, max_num_out;
/**
* Names have been changed to protect the guilty.
*/
int reallocate_buffers( void )
{
    free( buf_mem );
    buf_mem = malloc( (max_num_in + max_num_out) * 64 * 10000 * num_connections );
    big_int_buf = buf_mem;
    big_double_buf = buf_mem;
    for( int i = 0; i < num_connections; i++ )
    {
        int_in[i] = ((int *)buf_mem) [max_num_in * i ];
        int_out[i] = ((int *)buf_mem) [max_num_in * num_connections + i * max_num_out ];
        double_in[i] = ((double *)buf_mem) [max_num_in * i ];
        double_out[i] = ((double *)buf_mem) [max_num_in * num_connections + i * max_num_out ];
        long_in[i] = ((double *)buf_mem) [max_num_in * i ];
        long_out[i] = ((double *)buf_mem) [max_num_in * num_connections + i * max_num_out ];
    }
    return 0;
}

Now, there are few treats in here. First, this buffer implementation is a header included in every C file in their code base, even files that never need a buffer. The number 10,000 is a “magic” number- magic in that the developer had no idea how big the buffer needed to be, and just kept throwing successively larger numbers at it until it stopped crashing.

But what makes this a pièce de resistance are the variables big_int_buf and big_double_buf- both of which point to the same buf_mem memory address. I hope you didn’t try and use both of those variables to store different types of data at the same time, because if you did, you’re going to have one heck of a time figuring out the resulting bugs. Sadly, Jamie did- and spent more time than healthy untangling strange and inexplicable bugs.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!