Document the slice allocator
authorMatthias Clasen <matthiasc@src.gnome.org>
Sat, 3 Dec 2005 06:29:12 +0000 (06:29 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Sat, 3 Dec 2005 06:29:12 +0000 (06:29 +0000)
docs/reference/ChangeLog
docs/reference/glib/glib-docs.sgml
docs/reference/glib/glib-sections.txt
docs/reference/glib/tmpl/memory_chunks.sgml
docs/reference/glib/tmpl/memory_slices.sgml [new file with mode: 0644]

index 83cdef78fcb530232ca3745e8b629f22df10e24b..5e179171ba4b9bc3ec8270a9e18f4ad9b184e887 100644 (file)
@@ -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: 
index 22ff89c265c8e14d95507fd6430ce1c278b2820d..2c9260aae62fb83306e7a150a0a64650598139fd 100644 (file)
@@ -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;
index 59be0ca500046353b7243e98948ade520f9fea60..8ca31b826504acbfd86ce7523aacca8db3e6f470 100644 (file)
@@ -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>
index 519904d61c7adf00682f2b6a930eaf3536b7c2f6..8335c408afe92e8c74e8eb710e3e398f30d79c2e 100644 (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
 
 
diff --git a/docs/reference/glib/tmpl/memory_slices.sgml b/docs/reference/glib/tmpl/memory_slices.sgml
new file mode 100644 (file)
index 0000000..790a7d0
--- /dev/null
@@ -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 &lt; 10000; i++)
+    {
+      mem[i] = g_slice_alloc (50);
+
+      /* Fill in the memory with some junk. */
+      for (j = 0; j &lt; 50; j++)
+       mem[i][j] = i * j;
+    }
+
+  /* Now free all of the blocks. */
+  for (i = 0; i &lt; 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
+