From 1d485e56bc0ab992a76b289a7bcfd77ef13945bf Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 3 Dec 2005 06:29:12 +0000 Subject: [PATCH] Document the slice allocator --- docs/reference/ChangeLog | 10 ++ docs/reference/glib/glib-docs.sgml | 2 + docs/reference/glib/glib-sections.txt | 20 +++ docs/reference/glib/tmpl/memory_chunks.sgml | 37 +++- docs/reference/glib/tmpl/memory_slices.sgml | 179 ++++++++++++++++++++ 5 files changed, 242 insertions(+), 6 deletions(-) create mode 100644 docs/reference/glib/tmpl/memory_slices.sgml diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index 83cdef78f..5e179171b 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,3 +1,13 @@ +2005-12-03 Matthias Clasen + + * 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 * glib/building.sgml: diff --git a/docs/reference/glib/glib-docs.sgml b/docs/reference/glib/glib-docs.sgml index 22ff89c26..2c9260aae 100644 --- a/docs/reference/glib/glib-docs.sgml +++ b/docs/reference/glib/glib-docs.sgml @@ -32,6 +32,7 @@ + @@ -153,6 +154,7 @@ synchronize their operation. GLib Data Types + &glib-Memory-Slices; &glib-Memory-Chunks; &glib-Doubly-Linked-Lists; &glib-Singly-Linked-Lists; diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt index 59be0ca50..8ca31b826 100644 --- a/docs/reference/glib/glib-sections.txt +++ b/docs/reference/glib/glib-sections.txt @@ -1566,6 +1566,26 @@ g_mem_chunk_print +
+Memory Slices +memory_slices +g_slice_alloc +g_slice_alloc0 +g_slice_free1 +g_slice_free_chain + + +g_slice_new +g_slice_new0 +g_slice_free + + +GSliceConfig +g_slice_set_config +g_slice_get_config +g_slice_get_config_state +
+
Doubly-Linked Lists linked_lists_double diff --git a/docs/reference/glib/tmpl/memory_chunks.sgml b/docs/reference/glib/tmpl/memory_chunks.sgml index 519904d61..8335c408a 100644 --- a/docs/reference/glib/tmpl/memory_chunks.sgml +++ b/docs/reference/glib/tmpl/memory_chunks.sgml @@ -2,15 +2,18 @@ Memory Chunks -efficient way to allocate groups of equal-sized chunks of memory. +deprecated way to allocate groups of equal-sized chunks of memory. -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 -Doubly Linked Lists -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 +slice allocator, +which has been added in 2.10. All internal uses of memory chunks in +GLib have been converted to the g_slice API. 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 slice allocator + instead @@ -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 @@ -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 @@ -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 @@ -204,6 +212,8 @@ Frees all of the memory allocated for a #GMemChunk. @mem_chunk: a #GMemChunk. +@Deprecated: Use the slice allocator + instead @@ -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 slice allocator + instead @@ -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 @@ -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 @@ -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 @@ -268,6 +283,8 @@ It frees all of the currently allocated blocks of memory. @mem_chunk: a #GMemChunk. +@Deprecated: Use the slice allocator + instead @@ -276,6 +293,8 @@ Frees any blocks in a #GMemChunk which are no longer being used. @mem_chunk: a #GMemChunk. +@Deprecated: Use the slice allocator + instead @@ -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. +@Deprecated: Use the slice allocator + instead @@ -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. +@Deprecated: Use the slice allocator + instead @@ -302,5 +325,7 @@ the number of bytes used, and the number of blocks of memory allocated. @mem_chunk: a #GMemChunk. +@Deprecated: Use the slice allocator + instead diff --git a/docs/reference/glib/tmpl/memory_slices.sgml b/docs/reference/glib/tmpl/memory_slices.sgml new file mode 100644 index 000000000..790a7d0fd --- /dev/null +++ b/docs/reference/glib/tmpl/memory_slices.sgml @@ -0,0 +1,179 @@ + +Memory Slices + + +efficient way to allocate groups of equal-sized chunks of memory. + + + +Memory slices provide a space-efficient way to allocate equal-sized +pieces of memory, just like #GMemChunks, while avoiding their scalability +and performance problems. + + + +To achieve these goals, the slice allocator uses a sophisticated, +layered design that has been inspired by Bonwick's slab allocator +[Bonwick94] Jeff Bonwick, The slab allocator: An object-caching kernel +memory allocator. USENIX 1994, and + [Bonwick01] Bonwick and Jonathan Adams, Magazines and vmem: Extending the +slab allocator to many cpu's and arbitrary resources. USENIX 2001. +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. + + + +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 g_slice 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. + + + +Using the slice allocator + + 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]); + } + + + +Using the slice allocator with data structures + + 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); + + + + + + + + + + + + + +Allocates a block of memory from the slice allocator. + + +@block_size: the number of bytes to allocate +@Returns: a pointer to the allocated +@Since: 2.10 + + + + +Allocates a block of memory from the slice allocator, setting the +memory to 0. + + +@block_size: the number of bytes to allocate +@Returns: a pointer to the allocated block +@Since: 2.10 + + + + +Frees a block of memory. The memory must have been allocated from +the slice allocator. + + +@block_size: the size of the block +@mem_block: a pointer to the block to free +@Since: 2.10 + + + +Frees a linked list of memory block. The memory blocks must be equal-sized, +allocated from the slice allocator and linked together by a +next pointer stored in the @next_offset's word of +each block. + + +Currently, this function only supports blocks which store their +next pointer in the same position as #GSList. +Therefore, @next_offset must be 1. + + +@block_size: the size of the blocks +@mem_chain: a pointer to the first block +@next_offset: the offset of the next pointer +@Since: 2.10 + + + + +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. + + +@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 + + + + +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. + + +@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 + + + + +A convenience macro to free a block of memory that has been allocated +from the slice allocator. It calls g_slice_free1() using +sizeof (type) as the block size. + + +@type: the type of the block to free, typically a structure name +@mem_block: a pointer to the block to free +@Since: 2.10 +