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...")
 
 
(2 intermediate revisions by the same user not shown)
Line 21: Line 21:
 
Static allocated strings will be 16-bit aligned using the $T macro:
 
Static allocated strings will be 16-bit aligned using the $T macro:
  
** $T ( const char "..."): Creates a constant char * with 16-bit alignment.
+
* $T ( const char "..."): Creates a constant char * with 16-bit alignment.
  
 
<syntaxhighlight lang="c" line="1" >
 
<syntaxhighlight lang="c" line="1" >
 
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 36:
 
// 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 42:
 
#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 48:
 
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 62:
  
  
*** $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 68: Line 68:
 
// ...
 
// ...
 
var arena_2 = $A(hash);      // arena_2 points to the arena of hash (arena_1 in this example)
 
var arena_2 = $A(hash);      // arena_2 points to the arena of hash (arena_1 in this example)
</syntaxhighlight lang="c" line="1" >
+
</syntaxhighlight>
  
  
** $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 80: Line 80:
 
double *m  = $A_malloc(arena, double , 128);  // create a list of 128 doubles.
 
double *m  = $A_malloc(arena, double , 128);  // create a list of 128 doubles.
 
// ...
 
// ...
</syntaxhighlight lang="c" line="1" >
+
</syntaxhighlight>
  
  
** $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 90: Line 90:
 
// ...
 
// ...
 
$A_destroy(arena);
 
$A_destroy(arena);
</syntaxhighlight lang="c" line="1" >
+
</syntaxhighlight>
  
** $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 to the system. Memory will not be set to zeros. The arena can be reused as a new arena.
  
 
<syntaxhighlight lang="c" line="1" >
 
<syntaxhighlight lang="c" line="1" >
Line 104: Line 104:
 
$A_reset(arena);
 
$A_reset(arena);
 
}
 
}
</syntaxhighlight lang="c" line="1" >
+
</syntaxhighlight>
  
  
** $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.  
to close connections or free non arena-resources.
+
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.
 
Every time an object, that uses non-arena resources, is created its destructor must be registered to prevent leaks.
 
<syntaxhighlight lang="c" line="1" >
 
<syntaxhighlight lang="c" line="1" >
Line 120: Line 120:
 
$A_reg(arena, $P(connection), destructor);
 
$A_reg(arena, $P(connection), destructor);
 
$A_destroy(arena); // destroy an arena and free memory and resources.
 
$A_destroy(arena); // destroy an arena and free memory and resources.
</syntaxhighlight lang="c" line="1" >
+
</syntaxhighlight>
  
  
  
** $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.  
even if a exception is throwed from the block.
+
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" >
 
<syntaxhighlight lang="c" line="1" >
 
$AB( tmp_a , {
 
$AB( tmp_a , {
Line 133: Line 133:
 
}
 
}
 
);
 
);
</syntaxhighlight lang="c" line="1" >
+
</syntaxhighlight>
  
** $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.  
in its original arena. The result will be a var not stored in arena_from.
+
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" >
 
<syntaxhighlight lang="c" line="1" >
 
var a1 = $A(10000);
 
var a1 = $A(10000);
Line 151: Line 151:
 
$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>

Latest revision as of 11:23, 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)


  • $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.

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.
// ...


  • $A_destroy(arena) : Frees arena and frees all the allocated memory. Registered destructors with $A_reg will be called before the memory cleaning.
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);
  • $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 to the system. Memory will not be set to zeros. The arena can be reused as a new arena.

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);
}


  • $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.

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.


  • $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.

$AB( tmp_a , {
		var s = $STRING(tmp_a, $TEXT("abcde"));
		var h = $H(tmp_a);
		...
	}
);
  • $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.

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