Restrict memory allocation

To be threadsafe, a well-behaved C UDR must not use system memory-management routines to allocate memory dynamically including the following operating-system calls:
  • calloc() free() malloc()
  • mmap() realloc()
  • shmat() valloc()

Many other system calls allocate memory as well.

These operating-system calls allocate memory from the program heap space. The location of this heap space on only one VP creates the following problems:
  • Heap memory available to one VP is not visible after a thread migrates to another VP.

    After the thread migrates, the UDR can no longer access any data that was stored in heap memory. Even if the UDR allocates heap memory at the beginning of execution and frees this memory before it completes, the thread might still migrate to a different VP during execution of the UDR.

  • Other VPs are not prevented from using the same address space for the shared-memory pool.

    When a VP needs to extend the virtual memory pool, it negotiates the addition of new shared-memory segments to the existing pool. The VP then updates the resident portion of shared memory and sends a signal to other VPs so that they can become aware of changes to shared memory.

    A VP that extends the memory pool is not aware of any portion of memory that malloc() (or any other system memory-management routine) is using. Therefore, the VP might try to use the same address space that a system memory-management call has reserved.

  • Heap memory that system memory-management calls allocate is not automatically freed.

    If a C UDR does not explicitly free this heap memory, memory leaks can occur.

For a C UDR to be well-behaved, it must handle dynamic memory allocation with the DataBlade® API memory-management functions. These DataBlade API functions provide the following benefits:
  • They allocate user memory from the database server shared memory.

    All VPs can access database server shared memory. Location of dynamically allocated memory for a C UDR shows the areas of memory from which DataBlade API and operating-system memory-management functions allocate. For more information, see Manage user memory.

  • They allocate user memory with a specified lifetime called a memory duration.

    If a C UDR does not explicitly free memory that these DataBlade API functions allocate, the database server automatically deallocates it when its memory duration has expired. This automatic reclamation reduces memory leaks. For more information, see Choose the memory duration.

Important: Do not call operating-system memory-management functions from within a C UDR. Use these DataBlade API memory-management functions instead. The DataBlade API memory-management functions are safer in a C UDR than their operating-system equivalents.
If you are porting legacy code to a C UDR, you might want to write simple C programs to implement system memory-management calls and link these functions into your code before you make the UDR shared-object module. The following code fragment shows a simple implementation of malloc() and free() functions:
/* mallocfix.c: This file contains "fixed" versions of the
 *              malloc() and free() system memory-management
 *              calls for use in legacy code that currently
 *              uses malloc() and free().
 * Use mi_alloc() and mi_free() in new code.
 */
#include <mi.h>
void *malloc(size_t size)
{
   return (mi_alloc((mi_integer)size));
}

void free(void *ptr)
{
   mi_free(ptr);
}

This code fragment uses mi_alloc(), which allocates user memory in the current memory duration. Therefore, the fragment allocates the memory with the default memory duration of PER_ROUTINE. For more information, see Manage the memory duration.

If you cannot avoid using system memory-management functions, your C UDR is ill-behaved. You can use system memory-management functions in your UDR only if you can guarantee that the thread will not migrate. A thread can migrate during any DataBlade API call. To guarantee that the thread never migrates, you can either allocate and free the memory inside a code block that does not execute any DataBlade API functions or use a single-instance VP.

This restriction means that if you must use a system memory-management function, you must segment the UDR into sections that use DataBlade API functions and sections that are not safe in the CPU VP. All files must be closed and memory deallocated before you leave the sections that are not safe in the CPU VP. For more information, see External-library routines.