| <!-- ##### SECTION Title ##### --> |
| Memory Slices |
| |
| <!-- ##### SECTION Short_Description ##### --> |
| efficient way to allocate groups of equal-sized chunks of memory |
| |
| <!-- ##### SECTION Long_Description ##### --> |
| <para> |
| Memory slices provide a space-efficient and multi-processing scalable |
| way to allocate equal-sized pieces of memory, just like the original |
| #GMemChunks (from GLib <= 2.8), while avoiding their excessive |
| memory-waste, scalability and performance problems. |
| </para> |
| |
| <para> |
| To achieve these goals, the slice allocator uses a sophisticated, |
| layered design that has been inspired by Bonwick's slab allocator |
| <footnote><para> |
| <ulink url="http://citeseer.ist.psu.edu/bonwick94slab.html">[Bonwick94]</ulink> Jeff Bonwick, The slab allocator: An object-caching kernel |
| memory allocator. USENIX 1994, and |
| <ulink url="http://citeseer.ist.psu.edu/bonwick01magazines.html">[Bonwick01]</ulink> Bonwick and Jonathan Adams, Magazines and vmem: Extending the |
| slab allocator to many cpu's and arbitrary resources. USENIX 2001 |
| </para></footnote>. |
| It uses posix_memalign() to optimize allocations of many equally-sized |
| chunks, and has per-thread free lists (the so-called magazine layer) |
| to quickly satisfy allocation requests of already known structure sizes. |
| This is accompanied by extra caching logic to keep freed memory around |
| for some time before returning it to the system. Memory that is unused |
| due to alignment constraints is used for cache colorization (random |
| distribution of chunk addresses) to improve CPU cache utilization. The |
| caching layer of the slice allocator adapts itself to high lock contention |
| to improve scalability. |
| </para> |
| |
| <para> |
| The slice allocator can allocate blocks as small as two pointers, and |
| unlike malloc(), it does not reserve extra space per block. For large block |
| sizes, g_slice_new() and g_slice_alloc() will automatically delegate to the |
| system malloc() implementation. For newly written code it is recommended |
| to use the new <literal>g_slice</literal> API instead of g_malloc() and |
| friends, as long as objects are not resized during their lifetime and the |
| object size used at allocation time is still available when freeing. |
| </para> |
| |
| <example> |
| <title>Using the slice allocator</title> |
| <programlisting> |
| gchar *mem[10000]; |
| gint i; |
| |
| /* Allocate 10000 blocks. */ |
| for (i = 0; i < 10000; i++) |
| { |
| mem[i] = g_slice_alloc (50); |
| |
| /* Fill in the memory with some junk. */ |
| for (j = 0; j < 50; j++) |
| mem[i][j] = i * j; |
| } |
| |
| /* Now free all of the blocks. */ |
| for (i = 0; i < 10000; i++) |
| { |
| g_slice_free1 (50, mem[i]); |
| } |
| </programlisting></example> |
| |
| <example> |
| <title>Using the slice allocator with data structures</title> |
| <programlisting> |
| GRealArray *array; |
| |
| /* Allocate one block, using the g_slice_new(<!-- -->) macro. */ |
| array = g_slice_new (GRealArray); |
| |
| /* We can now use array just like a normal pointer to a structure. */ |
| array->data = NULL; |
| array->len = 0; |
| array->alloc = 0; |
| array->zero_terminated = (zero_terminated ? 1 : 0); |
| array->clear = (clear ? 1 : 0); |
| array->elt_size = elt_size; |
| |
| /* We can free the block, so it can be reused. */ |
| g_slice_free (GRealArray, array); |
| </programlisting></example> |
| |
| <!-- ##### SECTION See_Also ##### --> |
| <para> |
| </para> |
| |
| <!-- ##### SECTION Stability_Level ##### --> |
| |
| |
| <!-- ##### FUNCTION g_slice_alloc ##### --> |
| <para> |
| Allocates a block of memory from the slice allocator. |
| The block adress handed out can be expected to be aligned |
| to at least <literal>1 * sizeof (void*)</literal>, |
| though in general slices are 2 * sizeof (void*) bytes aligned, |
| if a malloc() fallback implementation is used instead, |
| the alignment may be reduced in a libc dependent fashion. |
| Note that the underlying slice allocation mechanism can |
| be changed with the <link linkend="G_SLICE">G_SLICE=always-malloc</link> |
| environment variable. |
| </para> |
| |
| @block_size: the number of bytes to allocate |
| @Returns: a pointer to the allocated memory block |
| @Since: 2.10 |
| |
| |
| <!-- ##### FUNCTION g_slice_alloc0 ##### --> |
| <para> |
| Allocates a block of memory via g_slice_alloc() |
| and initialize the returned memory to 0. |
| Note that the underlying slice allocation mechanism can |
| be changed with the <link linkend="G_SLICE">G_SLICE=always-malloc</link> |
| environment variable. |
| </para> |
| |
| @block_size: the number of bytes to allocate |
| @Returns: a pointer to the allocated block |
| @Since: 2.10 |
| |
| |
| <!-- ##### FUNCTION g_slice_copy ##### --> |
| <para> |
| Allocates a block of memory from the slice allocator and copies |
| @block_size bytes into it from @mem_block. |
| </para> |
| |
| @block_size: the number of bytes to allocate |
| @mem_block: the memory to copy |
| @Returns: a pointer to the allocated memory block |
| @Since: 2.14 |
| |
| |
| <!-- ##### FUNCTION g_slice_free1 ##### --> |
| <para> |
| Frees a block of memory. The memory must have been allocated via |
| g_slice_alloc() or g_slice_alloc0() |
| and the @block_size has to match the size specified upon allocation. |
| Note that the exact release behaviour can be changed with the |
| <link linkend="G_DEBUG">G_DEBUG=gc-friendly</link> environment variable, |
| also see <link linkend="G_SLICE">G_SLICE</link> for related debugging options. |
| </para> |
| |
| @block_size: the size of the block |
| @mem_block: a pointer to the block to free |
| @Since: 2.10 |
| |
| |
| <!-- ##### FUNCTION g_slice_free_chain_with_offset ##### --> |
| <para> |
| Frees a linked list of memory blocks of structure type @type. |
| The memory blocks must be equal-sized, allocated via |
| g_slice_alloc() or g_slice_alloc0() |
| and linked together by a @next pointer (similar to #GSList). The offset |
| of the @next field in each block is passed as third argument. |
| Note that the exact release behaviour can be changed with the |
| <link linkend="G_DEBUG">G_DEBUG=gc-friendly</link> environment variable, |
| also see <link linkend="G_SLICE">G_SLICE</link> for related debugging options. |
| </para> |
| |
| @block_size: the size of the blocks |
| @mem_chain: a pointer to the first block of the chain |
| @next_offset: the offset of the @next field in the blocks |
| @Since: 2.10 |
| |
| |
| <!-- ##### MACRO g_slice_new ##### --> |
| <para> |
| A convenience macro to allocate a block of memory from the slice allocator. |
| It calls g_slice_alloc() with <literal>sizeof (@type)</literal> and casts |
| the returned pointer to a pointer of the given type, avoiding a type cast |
| in the source code. |
| Note that the underlying slice allocation mechanism can |
| be changed with the <link linkend="G_SLICE">G_SLICE=always-malloc</link> |
| environment variable. |
| </para> |
| |
| @type: the type to allocate, typically a structure name |
| @Returns: a pointer to the allocated block, cast to a pointer to @type. |
| @Since: 2.10 |
| |
| |
| <!-- ##### MACRO g_slice_new0 ##### --> |
| <para> |
| A convenience macro to allocate a block of memory from the slice allocator |
| and set the memory to 0. It calls g_slice_alloc0() with |
| <literal>sizeof (@type)</literal> and casts the returned pointer to a pointer |
| of the given type, avoiding a type cast in the source code. |
| Note that the underlying slice allocation mechanism can |
| be changed with the <link linkend="G_SLICE">G_SLICE=always-malloc</link> |
| environment variable. |
| </para> |
| |
| @type: the type to allocate, typically a structure name |
| @Returns: a pointer to the allocated block, cast to a pointer to @type. |
| @Since: 2.10 |
| |
| |
| <!-- ##### MACRO g_slice_dup ##### --> |
| <para> |
| A convenience macro to duplicate a block of memory using the slice allocator. |
| It calls g_slice_copy() with <literal>sizeof (@type)</literal> and casts |
| the returned pointer to a pointer of the given type, avoiding a type cast |
| in the source code. |
| Note that the underlying slice allocation mechanism can |
| be changed with the <link linkend="G_SLICE">G_SLICE=always-malloc</link> |
| environment variable. |
| </para> |
| |
| @type: the type to duplicate, typically a structure name |
| @mem: the memory to copy into the allocated block |
| @Returns: a pointer to the allocated block, cast to a pointer to @type. |
| @Since: 2.14 |
| |
| |
| <!-- ##### MACRO g_slice_free ##### --> |
| <para> |
| A convenience macro to free a block of memory that has been allocated |
| from the slice allocator. It calls g_slice_free1() using |
| <literal>sizeof (type)</literal> as the block size. |
| Note that the exact release behaviour can be changed with the |
| <link linkend="G_DEBUG">G_DEBUG=gc-friendly</link> environment variable, |
| also see <link linkend="G_SLICE">G_SLICE</link> for related debugging options. |
| </para> |
| |
| @type: the type of the block to free, typically a structure name |
| @mem: a pointer to the block to free |
| @Since: 2.10 |
| |
| |
| <!-- ##### MACRO g_slice_free_chain ##### --> |
| <para> |
| Frees a linked list of memory blocks of structure type @type. |
| The memory blocks must be equal-sized, allocated via |
| g_slice_alloc() or g_slice_alloc0() and linked together by a |
| @next pointer (similar to #GSList). The name of the |
| @next field in @type is passed as third argument. |
| Note that the exact release behaviour can be changed with the |
| <link linkend="G_DEBUG">G_DEBUG=gc-friendly</link> environment variable, |
| also see <link linkend="G_SLICE">G_SLICE</link> for related debugging options. |
| </para> |
| |
| @type: the type of the @mem_chain blocks |
| @mem_chain: a pointer to the first block of the chain |
| @next: the field name of the next pointer in @type |
| @Since: 2.10 |
| |
| |