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...")
 
Line 1: Line 1:
 +
  
 
[[Category:NBD]]
 
[[Category:NBD]]
Line 26: Line 27:
 
char *mytext = $T("THis text will be stored in a 16-bit aligned memory block");
 
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.  
 
var txt = $POINTER(mytext);    // creates a var that represents the created C pointer.  
</syntaxhighlight lang="c" line="1" >
+
</syntaxhighlight>
  
 
IF you want to use pointers to automatic variables macro ALIGNED must be used.
 
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.
+
* $ALIGNED ( declaration ): Creates a C variable in a 16 bit aligned position of stack memory.
 
<syntaxhighlight lang="c" line="1" >
 
<syntaxhighlight lang="c" line="1" >
 
// creation of an aligned int  
 
// creation of an aligned int  
Line 36: Line 37:
 
// now &a is 16-bit aligned  
 
// now &a is 16-bit aligned  
 
var p = $POINTER(&a);
 
var p = $POINTER(&a);
</syntaxhighlight lang="c" line="1" >
+
</syntaxhighlight>
  
 
These macros have the following declaration:
 
These macros have the following declaration:
Line 42: Line 43:
 
#define $T(_x_) ({ static char __x__[] __attribute__ ((aligned (16))) = _x_;__x__; })
 
#define $T(_x_) ({ static char __x__[] __attribute__ ((aligned (16))) = _x_;__x__; })
 
#define $ALIGNED(_decl_)  _decl_ __attribute__ ((aligned (16)))
 
#define $ALIGNED(_decl_)  _decl_ __attribute__ ((aligned (16)))
</syntaxhighlight lang="c" line="1" >
+
</syntaxhighlight >
  
 
=== Arena API ===
 
=== Arena API ===
Line 48: Line 49:
 
These macros will allow to use arenas.
 
These macros will allow to use arenas.
  
** $A . Returns an arena.
+
* $A . Returns an arena.
  
 
Variants:
 
Variants:
  
*** $A(number)  : Returns a new arena with size 'number' bytes. Number must be signed or unsigned int or int64_t .
+
* $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" >
 
<syntaxhighlight lang="c" line="1" >
 
// creation of an arena with 1Kb of free memory  
 
// creation of an arena with 1Kb of free memory  
 
var arena = $A(1024);
 
var arena = $A(1024);
</syntaxhighlight lang="c" line="1" >
+
</syntaxhighlight>
  
 
The arena will have 1kb of free memory. If more than 1kb is needed, the arena will grown automatically as needed.  
 
The arena will have 1kb of free memory. If more than 1kb is needed, the arena will grown automatically as needed.  
Line 62: Line 63:
  
  
*** $A(var)  : Returns the arena used by an existing object.
+
* $A(var)  : Returns the arena used by an existing object.
 
<syntaxhighlight lang="c" line="1" >
 
<syntaxhighlight lang="c" line="1" >
 
var arena_1 = $A(1024);    // create an arena
 
var arena_1 = $A(1024);    // create an arena
Line 71: Line 72:
  
  
** $A_malloc(arena, type, n ) : Returns space to store n type objects. (space will be n * sizeof(type)).  
+
* $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.
 
The space will be reset to zeros.
 
<syntaxhighlight lang="c" line="1" >
 
<syntaxhighlight lang="c" line="1" >
Line 83: Line 84:
  
  
** $A_destroy(arena) : Frees arena and frees all the allocated memory. Registered destructors with $A_reg will be called before the memory cleaning.
+
* $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" >
 
<syntaxhighlight lang="c" line="1" >
 
var arena = $A(1024);    // create an arena
 
var arena = $A(1024);    // create an arena
Line 92: Line 93:
 
</syntaxhighlight lang="c" line="1" >
 
</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.  
+
* $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.
 
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.
  
Line 107: Line 108:
  
  
** $A_reg(arena, var o, void (*f) (var o)) : Register a destructor for o var. Sometimes deleting objects needs  
+
* $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.
 
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.
 
Every time an object, that uses non-arena resources, is created its destructor must be registered to prevent leaks.
Line 124: Line 125:
  
  
** $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  
+
* $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.
 
even if a exception is throwed from the block.
 
<syntaxhighlight lang="c" line="1" >
 
<syntaxhighlight lang="c" line="1" >
Line 135: Line 136:
 
</syntaxhighlight lang="c" line="1" >
 
</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
+
* $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.
 
in its original arena. The result will be a var not stored in arena_from.
 
<syntaxhighlight lang="c" line="1" >
 
<syntaxhighlight lang="c" line="1" >
Line 151: Line 152:
 
$TRACE ($GET(ar2,0);  // will print [ "Text to be migrated" , "Text to not be migrated" ]
 
$TRACE ($GET(ar2,0);  // will print [ "Text to be migrated" , "Text to not be migrated" ]
 
);
 
);
</syntaxhighlight lang="c" line="1" >
+
</syntaxhighlight>

Revision as of 11:20, 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.
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.

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.
// creation of an aligned int 
$ALIGNED(int a) = 34;  
// now &a is 16-bit aligned 
var p = $POINTER(&a);

These macros have the following declaration:

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

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 .
// creation of an arena with 1Kb of free memory 
var arena = $A(1024);

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.
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" ]
);