Difference between revisions of "C memory (v0.9)"

From Native Big Data Documentation
Jump to: navigation, search
(Created page with " Category:NBD == C memory API == NBD memory is managed by arenas. An arena is a collection of allocated objects that can be efficiently deallocated all at once. See h...")
(No difference)

Revision as of 11:17, 16 May 2019


C memory API

NBD memory is managed by arenas. An arena is a collection of allocated objects that can be efficiently deallocated all at once. See [[1]] for more information. Every time something is created from C language in NBD, it is stored in an arena. When the execution of something ends all the used arenas are deleted and the reserved memory is returned to the system. Memory reserved using malloc, calloc, strdup don't use arenas. We discourage using these functions in NBD native modules.


Using vars and C pointers

All the internal objects in NDB are of type 'var'. A 'var' can be a value or a pointer to a struct (objects). vars are non-typed variables and can reference numbers, strings, arrays, ... NBD provides an API to know what is the type of a var. Often this functionality is called reflection [[2]]. Generically C Pointers can be used as vars but they must be 16-bit aligned. Pointer to functions can be automatic 16-bit aligned by gcc using the parameter '-falign-functions=16'. Heap allocated object will be always 16-bit aligned using Arenas because arenas will always return 16-bit aligned memory.

Static allocated strings will be 16-bit aligned using the $T macro:

    • $T ( const char "..."): Creates a constant char * with 16-bit alignment.

<syntaxhighlight lang="c" line="1" > char *mytext = $T("THis text will be stored in a 16-bit aligned memory block"); var txt = $POINTER(mytext); // creates a var that represents the created C pointer. </syntaxhighlight lang="c" line="1" >

IF you want to use pointers to automatic variables macro ALIGNED must be used.

    • $ALIGNED ( declaration ): Creates a C variable in a 16 bit aligned position of stack memory.

<syntaxhighlight lang="c" line="1" > // creation of an aligned int $ALIGNED(int a) = 34; // now &a is 16-bit aligned var p = $POINTER(&a); </syntaxhighlight lang="c" line="1" >

These macros have the following declaration: <syntaxhighlight lang="c" line="1" >

  1. define $T(_x_) ({ static char __x__[] __attribute__ ((aligned (16))) = _x_;__x__; })
  2. define $ALIGNED(_decl_) _decl_ __attribute__ ((aligned (16)))

</syntaxhighlight lang="c" line="1" >

Arena API

These macros will allow to use arenas.

    • $A . Returns an arena.

Variants:

      • $A(number)  : Returns a new arena with size 'number' bytes. Number must be signed or unsigned int or int64_t .

<syntaxhighlight lang="c" line="1" > // creation of an arena with 1Kb of free memory var arena = $A(1024); </syntaxhighlight lang="c" line="1" >

The arena will have 1kb of free memory. If more than 1kb is needed, the arena will grown automatically as needed. The predefined size of 1kb is used to optimize the allocated memory.


      • $A(var)  : Returns the arena used by an existing object.

<syntaxhighlight lang="c" line="1" > var arena_1 = $A(1024); // create an arena var hash = $H(arena_1); // create a hash in arena_1 // ... var arena_2 = $A(hash); // arena_2 points to the arena of hash (arena_1 in this example) </syntaxhighlight lang="c" line="1" >


    • $A_malloc(arena, type, n ) : Returns space to store n type objects. (space will be n * sizeof(type)).

The space will be reset to zeros. <syntaxhighlight lang="c" line="1" > var arena = $A(1024); // create an arena char *pool = $A_malloc(arena, char , 1024); // create a buffer of 1024 bytes var **m = $A_malloc(arena, var * , 1024); // create a list of 1024 var pointers. var *k = $A_malloc(arena, var , 512); // create a list of 512 vars. double *m = $A_malloc(arena, double , 128); // create a list of 128 doubles. // ... </syntaxhighlight lang="c" line="1" >


    • $A_destroy(arena) : Frees arena and frees all the allocated memory. Registered destructors with $A_reg will be called before the memory cleaning.

<syntaxhighlight lang="c" line="1" > var arena = $A(1024); // create an arena char *pool = $A_malloc(arena, char , 1024); // create a buffer of 1024 bytes var **m = $A_malloc(arena, var * , 1024); // create a list of 1024 var pointers. // ... $A_destroy(arena); </syntaxhighlight lang="c" line="1" >

    • $A_reset(arena) : Frees objects stored in arena but don't returns the memory to the system. Registered destructors with $A_reg will be called.

Memory in the arena is reusable but is not returned tho the system. Memory will not be set to zeros. The arena can be reused as a new arena.

<syntaxhighlight lang="c" line="1" > var arena = $A(1024); for (int i=0;i<100;i++) { char *buffer = $A_malloc(arena,char,100); snprintf(buffer,99, "number %d", i); var s = $S(arena, buffer); $TRACE(s); $A_reset(arena); } </syntaxhighlight lang="c" line="1" >


    • $A_reg(arena, var o, void (*f) (var o)) : Register a destructor for o var. Sometimes deleting objects needs

to close connections or free non arena-resources. Every time an object, that uses non-arena resources, is created its destructor must be registered to prevent leaks. <syntaxhighlight lang="c" line="1" > void destructor(var o) { conn_t *oo = $POINTER(o); // destrucction code close(oo); } var arena = $A(1024); // create an arena conn_t *connection = $A_malloc(arena, conn_t, 1); $A_reg(arena, $P(connection), destructor); $A_destroy(arena); // destroy an arena and free memory and resources. </syntaxhighlight lang="c" line="1" >


    • $AB(arena, code) : Creates a block with a temporal arena. The arena can be used inside the block and will be destroyed when the execution go out the block

even if a exception is throwed from the block. <syntaxhighlight lang="c" line="1" > $AB( tmp_a , { var s = $STRING(tmp_a, $TEXT("abcde")); var h = $H(tmp_a); ... } ); </syntaxhighlight lang="c" line="1" >

    • $A_migrate(o, arena_from, arena_to): Moves a var from arena_from to arena_to. Only vars in arena_from will be migrated (cloned). Other vars will remain

in its original arena. The result will be a var not stored in arena_from. <syntaxhighlight lang="c" line="1" > var a1 = $A(10000); var a2 = $A(10000); var b = $A(10000);

var s1 = $S( a1, $TEXT("Text to be migrated") ); var s2 = $S( a2, $TEXT("Text to not be migrated") );

var ar = $AR(a1, s1,s2); // creates the array [s1,s2]

var ar2 = $A_migrate(ar, a1,b); // ar will be cloned in b arena and all objects inside ar and stored in a1 will be moved to b $A_destroy(a1): // ar2 and chilren are safe objects. a1, s1 and ar are not safe !!! $TRACE ($GET(ar2,0); // will print [ "Text to be migrated" , "Text to not be migrated" ] ); </syntaxhighlight lang="c" line="1" >