mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-26 22:16:16 +01:00
Document the slice allocator
This commit is contained in:
parent
1fe373b279
commit
1d485e56bc
@ -1,3 +1,13 @@
|
||||
2005-12-03 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* glib/tmpl/memory_chunks.sgml: Document GMemChunk
|
||||
as deprecated.
|
||||
|
||||
* glib/glib-docs.sgml:
|
||||
* glib/glib-sections.txt:
|
||||
* glib/tmpl/memory_slices.sgml: Document the slice
|
||||
allocator.
|
||||
|
||||
2005-12-02 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* glib/building.sgml:
|
||||
|
@ -32,6 +32,7 @@
|
||||
<!ENTITY glib-Automatic-String-Completion SYSTEM "xml/completion.xml">
|
||||
<!ENTITY glib-Windows-Compatability-Functions SYSTEM "xml/windows.xml">
|
||||
<!ENTITY glib-Memory-Chunks SYSTEM "xml/memory_chunks.xml">
|
||||
<!ENTITY glib-Memory-Slices SYSTEM "xml/memory_slices.xml">
|
||||
<!ENTITY glib-Doubly-Linked-Lists SYSTEM "xml/linked_lists_double.xml">
|
||||
<!ENTITY glib-Singly-Linked-Lists SYSTEM "xml/linked_lists_single.xml">
|
||||
<!ENTITY glib-Double-ended-Queues SYSTEM "xml/queue.xml">
|
||||
@ -153,6 +154,7 @@ synchronize their operation.
|
||||
|
||||
<chapter id="glib-data-types">
|
||||
<title>GLib Data Types</title>
|
||||
&glib-Memory-Slices;
|
||||
&glib-Memory-Chunks;
|
||||
&glib-Doubly-Linked-Lists;
|
||||
&glib-Singly-Linked-Lists;
|
||||
|
@ -1566,6 +1566,26 @@ g_mem_chunk_print
|
||||
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<TITLE>Memory Slices</TITLE>
|
||||
<FILE>memory_slices</FILE>
|
||||
g_slice_alloc
|
||||
g_slice_alloc0
|
||||
g_slice_free1
|
||||
g_slice_free_chain
|
||||
|
||||
<SUBSECTION>
|
||||
g_slice_new
|
||||
g_slice_new0
|
||||
g_slice_free
|
||||
|
||||
<SUBSECTION Private>
|
||||
GSliceConfig
|
||||
g_slice_set_config
|
||||
g_slice_get_config
|
||||
g_slice_get_config_state
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<TITLE>Doubly-Linked Lists</TITLE>
|
||||
<FILE>linked_lists_double</FILE>
|
||||
|
@ -2,15 +2,18 @@
|
||||
Memory Chunks
|
||||
|
||||
<!-- ##### SECTION Short_Description ##### -->
|
||||
efficient way to allocate groups of equal-sized chunks of memory.
|
||||
deprecated way to allocate groups of equal-sized chunks of memory.
|
||||
|
||||
<!-- ##### SECTION Long_Description ##### -->
|
||||
<para>
|
||||
Memory chunks provide an efficient way to allocate equal-sized pieces of
|
||||
memory, called atoms. They are used extensively within GLib itself.
|
||||
For example, the
|
||||
<link linkend="glib-Doubly-Linked-lists">Doubly Linked Lists</link>
|
||||
use memory chunks to allocate space for elements of the lists.
|
||||
Memory chunks provide an space-efficient way to allocate equal-sized
|
||||
pieces of memory, called atoms. However, due to the administrative
|
||||
overhead (in particular for #G_ALLOC_AND_FREE, and when used from multiple
|
||||
threads), they are in practise often slower than direct use of g_malloc().
|
||||
Therefore, memory chunks have been deprecated in favor of the
|
||||
<link linkend="glib-Memory-Slices">slice allocator</link>,
|
||||
which has been added in 2.10. All internal uses of memory chunks in
|
||||
GLib have been converted to the <literal>g_slice</literal> API.
|
||||
</para>
|
||||
<para>
|
||||
There are two types of memory chunks, #G_ALLOC_ONLY, and #G_ALLOC_AND_FREE.
|
||||
@ -167,6 +170,8 @@ the atoms.
|
||||
#G_ALLOC_ONLY is quicker, since it does not need to track free atoms,
|
||||
but it obviously wastes memory if you no longer need many of the atoms.
|
||||
@Returns: the new #GMemChunk.
|
||||
@Deprecated: Use the <link linkend="glib-Memory-Slices">slice allocator</link>
|
||||
instead
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_mem_chunk_alloc ##### -->
|
||||
@ -176,6 +181,7 @@ Allocates an atom of memory from a #GMemChunk.
|
||||
|
||||
@mem_chunk: a #GMemChunk.
|
||||
@Returns: a pointer to the allocated atom.
|
||||
@Deprecated: Use g_slice_alloc() instead
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_mem_chunk_alloc0 ##### -->
|
||||
@ -185,6 +191,7 @@ Allocates an atom of memory from a #GMemChunk, setting the memory to 0.
|
||||
|
||||
@mem_chunk: a #GMemChunk.
|
||||
@Returns: a pointer to the allocated atom.
|
||||
@Deprecated: Use g_slice_alloc0() instead
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_mem_chunk_free ##### -->
|
||||
@ -196,6 +203,7 @@ This should only be called if the #GMemChunk was created with
|
||||
|
||||
@mem_chunk: a #GMemChunk.
|
||||
@mem: a pointer to the atom to free.
|
||||
@Deprecated: Use g_slice_free1() instead
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_mem_chunk_destroy ##### -->
|
||||
@ -204,6 +212,8 @@ Frees all of the memory allocated for a #GMemChunk.
|
||||
</para>
|
||||
|
||||
@mem_chunk: a #GMemChunk.
|
||||
@Deprecated: Use the <link linkend="glib-Memory-Slices">slice allocator</link>
|
||||
instead
|
||||
|
||||
|
||||
<!-- ##### MACRO g_mem_chunk_create ##### -->
|
||||
@ -223,6 +233,8 @@ the atom size.
|
||||
#G_ALLOC_ONLY is quicker, since it does not need to track free atoms,
|
||||
but it obviously wastes memory if you no longer need many of the atoms.
|
||||
@Returns: the new #GMemChunk.
|
||||
@Deprecated: Use the <link linkend="glib-Memory-Slices">slice allocator</link>
|
||||
instead
|
||||
|
||||
|
||||
<!-- ##### MACRO g_chunk_new ##### -->
|
||||
@ -235,6 +247,7 @@ the given type, avoiding a type cast in the source code.
|
||||
@type: the type of the #GMemChunk atoms, typically a structure name.
|
||||
@chunk: a #GMemChunk.
|
||||
@Returns: a pointer to the allocated atom, cast to a pointer to @type.
|
||||
@Deprecated: Use g_slice_new() instead
|
||||
|
||||
|
||||
<!-- ##### MACRO g_chunk_new0 ##### -->
|
||||
@ -247,6 +260,7 @@ the given type, avoiding a type cast in the source code.
|
||||
@type: the type of the #GMemChunk atoms, typically a structure name.
|
||||
@chunk: a #GMemChunk.
|
||||
@Returns: a pointer to the allocated atom, cast to a pointer to @type.
|
||||
@Deprecated: Use g_slice_new0() instead
|
||||
|
||||
|
||||
<!-- ##### MACRO g_chunk_free ##### -->
|
||||
@ -259,6 +273,7 @@ and g_chunk_new0().
|
||||
|
||||
@mem: a pointer to the atom to be freed.
|
||||
@mem_chunk: a #GMemChunk.
|
||||
@Deprecated: Use g_slice_free() instead
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_mem_chunk_reset ##### -->
|
||||
@ -268,6 +283,8 @@ It frees all of the currently allocated blocks of memory.
|
||||
</para>
|
||||
|
||||
@mem_chunk: a #GMemChunk.
|
||||
@Deprecated: Use the <link linkend="glib-Memory-Slices">slice allocator</link>
|
||||
instead
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_mem_chunk_clean ##### -->
|
||||
@ -276,6 +293,8 @@ Frees any blocks in a #GMemChunk which are no longer being used.
|
||||
</para>
|
||||
|
||||
@mem_chunk: a #GMemChunk.
|
||||
@Deprecated: Use the <link linkend="glib-Memory-Slices">slice allocator</link>
|
||||
instead
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_blow_chunks ##### -->
|
||||
@ -283,6 +302,8 @@ Frees any blocks in a #GMemChunk which are no longer being used.
|
||||
Calls g_mem_chunk_clean() on all #GMemChunk objects.
|
||||
</para>
|
||||
|
||||
@Deprecated: Use the <link linkend="glib-Memory-Slices">slice allocator</link>
|
||||
instead
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_mem_chunk_info ##### -->
|
||||
@ -292,6 +313,8 @@ It outputs the number of #GMemChunk objects currently allocated,
|
||||
and calls g_mem_chunk_print() to output information on each one.
|
||||
</para>
|
||||
|
||||
@Deprecated: Use the <link linkend="glib-Memory-Slices">slice allocator</link>
|
||||
instead
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_mem_chunk_print ##### -->
|
||||
@ -302,5 +325,7 @@ the number of bytes used, and the number of blocks of memory allocated.
|
||||
</para>
|
||||
|
||||
@mem_chunk: a #GMemChunk.
|
||||
@Deprecated: Use the <link linkend="glib-Memory-Slices">slice allocator</link>
|
||||
instead
|
||||
|
||||
|
||||
|
179
docs/reference/glib/tmpl/memory_slices.sgml
Normal file
179
docs/reference/glib/tmpl/memory_slices.sgml
Normal file
@ -0,0 +1,179 @@
|
||||
<!-- ##### 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 way to allocate equal-sized
|
||||
pieces of memory, just like #GMemChunks, while avoiding their 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.
|
||||
</para>
|
||||
|
||||
@block_size: the number of bytes to allocate
|
||||
@Returns: a pointer to the allocated
|
||||
@Since: 2.10
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_slice_alloc0 ##### -->
|
||||
<para>
|
||||
Allocates a block of memory from the slice allocator, setting the
|
||||
memory to 0.
|
||||
</para>
|
||||
|
||||
@block_size: the number of bytes to allocate
|
||||
@Returns: a pointer to the allocated block
|
||||
@Since: 2.10
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_slice_free1 ##### -->
|
||||
<para>
|
||||
Frees a block of memory. The memory must have been allocated from
|
||||
the slice allocator.
|
||||
</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 ##### -->
|
||||
<para>
|
||||
Frees a linked list of memory block. The memory blocks must be equal-sized,
|
||||
allocated from the slice allocator and linked together by a
|
||||
<literal>next</literal> pointer stored in the @next_offset's word of
|
||||
each block.
|
||||
</para>
|
||||
<para>
|
||||
Currently, this function only supports blocks which store their
|
||||
<literal>next</literal> pointer in the same position as #GSList.
|
||||
Therefore, @next_offset must be 1.
|
||||
</para>
|
||||
|
||||
@block_size: the size of the blocks
|
||||
@mem_chain: a pointer to the first block
|
||||
@next_offset: the offset of the <literal>next</literal> pointer
|
||||
@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() and casts the returned pointer to a pointer to
|
||||
the given type, avoiding a type cast in the source code.
|
||||
</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() and casts the returned
|
||||
pointer to a pointer to the given type, avoiding a type cast in the source
|
||||
code.
|
||||
</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_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.
|
||||
</para>
|
||||
|
||||
@type: the type of the block to free, typically a structure name
|
||||
@mem_block: a pointer to the block to free
|
||||
@Since: 2.10
|
||||
|
Loading…
Reference in New Issue
Block a user