Move slice and hook docs inline

This commit is contained in:
Matthias Clasen 2011-11-13 00:26:57 -05:00
parent bad6c0ad15
commit c8b0617a2b
5 changed files with 676 additions and 728 deletions

View File

@ -24,6 +24,7 @@ gvarianttype.sgml
gwakeup.sgml
hash_tables.sgml
hmac.sgml
hooks.sgml
iochannels.sgml
keyfile.sgml
linked_lists_double.sgml
@ -31,6 +32,7 @@ linked_lists_single.sgml
main.sgml
markup.sgml
memory_chunks.sgml
memory_slices.sgml
memory.sgml
messages.sgml
misc_utils.sgml

View File

@ -1,470 +0,0 @@
<!-- ##### SECTION Title ##### -->
Hook Functions
<!-- ##### SECTION Short_Description ##### -->
support for manipulating lists of hook functions
<!-- ##### SECTION Long_Description ##### -->
<para>
The #GHookList, #GHook and their related functions provide support for
lists of hook functions. Functions can be added and removed from the lists,
and the list of hook functions can be invoked.
</para>
<!-- ##### SECTION See_Also ##### -->
<para>
</para>
<!-- ##### SECTION Stability_Level ##### -->
<!-- ##### SECTION Image ##### -->
<!-- ##### STRUCT GHookList ##### -->
<para>
The <structname>GHookList</structname> struct represents a
list of hook functions.
</para>
@seq_id: the next free #GHook id
@hook_size: the size of the #GHookList elements, in bytes
@is_setup: 1 if the #GHookList has been initialized
@hooks: the first #GHook element in the list
@dummy3: unused
@finalize_hook: the function to call to finalize a #GHook element. The
default behaviour is to call the hooks <function>destroy</function> function
@dummy: unused
<!-- ##### USER_FUNCTION GHookFinalizeFunc ##### -->
<para>
Defines the type of function to be called when a hook in a
list of hooks gets finalized.
</para>
@hook_list: a #GHookList
@hook: the hook in @hook_list that gets finalized
<!-- ##### STRUCT GHook ##### -->
<para>
The <structname>GHook</structname> struct represents a single hook
function in a #GHookList.
</para>
@data: data which is passed to func when this hook is invoked
@next: pointer to the next hook in the list
@prev: pointer to the previous hook in the list
@ref_count: the reference count of this hook
@hook_id: the id of this hook, which is unique within its list
@flags: flags which are set for this hook. See #GHookFlagMask for
predefined flags
@func: the function to call when this hook is invoked. The possible
signatures for this function are #GHookFunc and #GHookCheckFunc
@destroy: the default <function>finalize_hook</function> function of a
#GHookList calls this member of the hook that is being finalized
<!-- ##### USER_FUNCTION GHookFunc ##### -->
<para>
Defines the type of a hook function that can be invoked
by g_hook_list_invoke().
</para>
@data: the data field of the #GHook is passed to the hook function here
<!-- ##### USER_FUNCTION GHookCheckFunc ##### -->
<para>
Defines the type of a hook function that can be invoked
by g_hook_list_invoke_check().
</para>
@data: the data field of the #GHook is passed to the hook function here
@Returns: %FALSE if the #GHook should be destroyed
<!-- ##### FUNCTION g_hook_list_init ##### -->
<para>
Initializes a #GHookList.
This must be called before the #GHookList is used.
</para>
@hook_list: a #GHookList
@hook_size: the size of each element in the #GHookList, typically
<literal>sizeof (GHook)</literal>
<!-- ##### FUNCTION g_hook_list_invoke ##### -->
<para>
Calls all of the #GHook functions in a #GHookList.
</para>
@hook_list: a #GHookList
@may_recurse: %TRUE if functions which are already running (e.g. in another
thread) can be called. If set to %FALSE, these are skipped
<!-- ##### FUNCTION g_hook_list_invoke_check ##### -->
<para>
Calls all of the #GHook functions in a #GHookList.
Any function which returns %FALSE is removed from the #GHookList.
</para>
@hook_list: a #GHookList
@may_recurse: %TRUE if functions which are already running (e.g. in another
thread) can be called. If set to %FALSE, these are skipped
<!-- ##### FUNCTION g_hook_list_marshal ##### -->
<para>
Calls a function on each valid #GHook.
</para>
@hook_list: a #GHookList
@may_recurse: %TRUE if hooks which are currently running (e.g. in another
thread) are considered valid. If set to %FALSE, these are skipped
@marshaller: the function to call for each #GHook
@marshal_data: data to pass to @marshaller
<!-- ##### USER_FUNCTION GHookMarshaller ##### -->
<para>
Defines the type of function used by g_hook_list_marshal().
</para>
@hook: a #GHook
@marshal_data: user data
<!-- ##### FUNCTION g_hook_list_marshal_check ##### -->
<para>
Calls a function on each valid #GHook and destroys it if the
function returns %FALSE.
</para>
@hook_list: a #GHookList
@may_recurse: %TRUE if hooks which are currently running (e.g. in another
thread) are considered valid. If set to %FALSE, these are skipped
@marshaller: the function to call for each #GHook
@marshal_data: data to pass to @marshaller
<!-- ##### USER_FUNCTION GHookCheckMarshaller ##### -->
<para>
Defines the type of function used by g_hook_list_marshal_check().
</para>
@hook: a #GHook
@marshal_data: user data
@Returns: %FALSE if @hook should be destroyed
<!-- ##### FUNCTION g_hook_list_clear ##### -->
<para>
Removes all the #GHook elements from a #GHookList.
</para>
@hook_list: a #GHookList
<!-- ##### FUNCTION g_hook_alloc ##### -->
<para>
Allocates space for a #GHook and initializes it.
</para>
@hook_list: a #GHookList
@Returns: a new #GHook
<!-- ##### MACRO g_hook_append ##### -->
<para>
Appends a #GHook onto the end of a #GHookList.
</para>
@hook_list: a #GHookList
@hook: the #GHook to add to the end of @hook_list
<!-- ##### FUNCTION g_hook_prepend ##### -->
<para>
Prepends a #GHook on the start of a #GHookList.
</para>
@hook_list: a #GHookList
@hook: the #GHook to add to the start of @hook_list
<!-- ##### FUNCTION g_hook_insert_before ##### -->
<para>
Inserts a #GHook into a #GHookList, before a given #GHook.
</para>
@hook_list: a #GHookList
@sibling: the #GHook to insert the new #GHook before
@hook: the #GHook to insert
<!-- ##### FUNCTION g_hook_insert_sorted ##### -->
<para>
Inserts a #GHook into a #GHookList, sorted by the given function.
</para>
@hook_list: a #GHookList
@hook: the #GHook to insert
@func: the comparison function used to sort the #GHook elements
<!-- ##### USER_FUNCTION GHookCompareFunc ##### -->
<para>
Defines the type of function used to compare #GHook elements in
g_hook_insert_sorted().
</para>
@new_hook: the #GHook being inserted
@sibling: the #GHook to compare with @new_hook
@Returns: a value &lt;= 0 if @new_hook should be before @sibling
<!-- ##### FUNCTION g_hook_compare_ids ##### -->
<para>
Compares the ids of two #GHook elements, returning a negative value
if the second id is greater than the first.
</para>
@new_hook: a #GHook
@sibling: a #GHook to compare with @new_hook
@Returns: a value &lt;= 0 if the id of @sibling is >= the id of @new_hook
<!-- ##### FUNCTION g_hook_get ##### -->
<para>
Returns the #GHook with the given id, or %NULL if it is not found.
</para>
@hook_list: a #GHookList
@hook_id: a hook id
@Returns: the #GHook with the given id, or %NULL if it is not found
<!-- ##### FUNCTION g_hook_find ##### -->
<para>
Finds a #GHook in a #GHookList using the given function to test for a match.
</para>
@hook_list: a #GHookList
@need_valids: %TRUE if #GHook elements which have been destroyed should be
skipped
@func: the function to call for each #GHook, which should return %TRUE when
the #GHook has been found
@data: the data to pass to @func
@Returns: the found #GHook or %NULL if no matching #GHook is found
<!-- ##### USER_FUNCTION GHookFindFunc ##### -->
<para>
Defines the type of the function passed to g_hook_find().
</para>
@hook: a #GHook
@data: user data passed to g_hook_find_func()
@Returns: %TRUE if the required #GHook has been found
<!-- ##### FUNCTION g_hook_find_data ##### -->
<para>
Finds a #GHook in a #GHookList with the given data.
</para>
@hook_list: a #GHookList
@need_valids: %TRUE if #GHook elements which have been destroyed should be
skipped
@data: the data to find
@Returns: the #GHook with the given @data or %NULL if no matching
#GHook is found
<!-- ##### FUNCTION g_hook_find_func ##### -->
<para>
Finds a #GHook in a #GHookList with the given function.
</para>
@hook_list: a #GHookList
@need_valids: %TRUE if #GHook elements which have been destroyed should be
skipped
@func: the function to find
@Returns: the #GHook with the given @func or %NULL if no matching
#GHook is found
<!-- ##### FUNCTION g_hook_find_func_data ##### -->
<para>
Finds a #GHook in a #GHookList with the given function and data.
</para>
@hook_list: a #GHookList
@need_valids: %TRUE if #GHook elements which have been destroyed should be
skipped
@func: the function to find
@data: the data to find
@Returns: the #GHook with the given @func and @data or %NULL if no matching
#GHook is found
<!-- ##### FUNCTION g_hook_first_valid ##### -->
<para>
Returns the first #GHook in a #GHookList which has not been destroyed.
The reference count for the #GHook is incremented, so you must call
g_hook_unref() to restore it when no longer needed. (Or call
g_hook_next_valid() if you are stepping through the #GHookList.)
</para>
@hook_list: a #GHookList
@may_be_in_call: %TRUE if hooks which are currently running (e.g. in another
thread) are considered valid. If set to %FALSE, these are skipped
@Returns: the first valid #GHook, or %NULL if none are valid
<!-- ##### FUNCTION g_hook_next_valid ##### -->
<para>
Returns the next #GHook in a #GHookList which has not been destroyed.
The reference count for the #GHook is incremented, so you must call
g_hook_unref() to restore it when no longer needed. (Or continue to call
g_hook_next_valid() until %NULL is returned.)
</para>
@hook_list: a #GHookList
@hook: the current #GHook
@may_be_in_call: %TRUE if hooks which are currently running (e.g. in another
thread) are considered valid. If set to %FALSE, these are skipped
@Returns: the next valid #GHook, or %NULL if none are valid
<!-- ##### ENUM GHookFlagMask ##### -->
<para>
Flags used internally in the #GHook implementation.
</para>
@G_HOOK_FLAG_ACTIVE: set if the hook has not been destroyed
@G_HOOK_FLAG_IN_CALL: set if the hook is currently being run
@G_HOOK_FLAG_MASK: A mask covering all bits reserved for
hook flags; see #G_HOOK_FLAGS_USER_SHIFT
<!-- ##### MACRO G_HOOK_FLAGS ##### -->
<para>
Returns the flags of a hook.
</para>
@hook: a #GHook
<!-- ##### MACRO G_HOOK_FLAG_USER_SHIFT ##### -->
<para>
The position of the first bit which is not reserved for internal
use be the #GHook implementation, i.e.
<literal>1 &lt;&lt; G_HOOK_FLAG_USER_SHIFT</literal> is the first bit
which can be used for application-defined flags.
</para>
<!-- ##### MACRO G_HOOK ##### -->
<para>
Casts a pointer to a <literal>GHook*</literal>.
</para>
@hook: a pointer
<!-- ##### MACRO G_HOOK_IS_VALID ##### -->
<para>
Returns %TRUE if the #GHook is valid, i.e. it is in a #GHookList, it is active
and it has not been destroyed.
</para>
@hook: a #GHook
@Returns: %TRUE if the #GHook is valid
<!-- ##### MACRO G_HOOK_ACTIVE ##### -->
<para>
Returns %TRUE if the #GHook is active, which is normally %TRUE until the #GHook
is destroyed.
</para>
@hook: a #GHook
@Returns: %TRUE if the #GHook is active
<!-- ##### MACRO G_HOOK_IN_CALL ##### -->
<para>
Returns %TRUE if the #GHook function is currently executing.
</para>
@hook: a #GHook
@Returns: %TRUE if the #GHook function is currently executing
<!-- ##### MACRO G_HOOK_IS_UNLINKED ##### -->
<para>
Returns %TRUE if the #GHook is not in a #GHookList.
</para>
@hook: a #GHook
@Returns: %TRUE if the #GHook is not in a #GHookList
<!-- ##### FUNCTION g_hook_ref ##### -->
<para>
Increments the reference count for a #GHook.
</para>
@hook_list: a #GHookList
@hook: the #GHook to increment the reference count of
@Returns: the @hook that was passed in (since 2.6)
<!-- ##### FUNCTION g_hook_unref ##### -->
<para>
Decrements the reference count of a #GHook.
If the reference count falls to 0, the #GHook is removed from the #GHookList
and g_hook_free() is called to free it.
</para>
@hook_list: a #GHookList
@hook: the #GHook to unref
<!-- ##### FUNCTION g_hook_free ##### -->
<para>
Calls the #GHookList @finalize_hook function if it exists, and frees the memory
allocated for the #GHook.
</para>
@hook_list: a #GHookList
@hook: the #GHook to free
<!-- ##### FUNCTION g_hook_destroy ##### -->
<para>
Destroys a #GHook, given its ID.
</para>
@hook_list: a #GHookList
@hook_id: a hook ID
@Returns: %TRUE if the #GHook was found in the #GHookList and destroyed
<!-- ##### FUNCTION g_hook_destroy_link ##### -->
<para>
Removes one #GHook from a #GHookList, marking it inactive and calling
g_hook_unref() on it.
</para>
@hook_list: a #GHookList
@hook: the #GHook to remove

View File

@ -1,256 +0,0 @@
<!-- ##### 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 &lt;= 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 &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 ##### -->
<!-- ##### SECTION Image ##### -->
<!-- ##### 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

View File

@ -38,6 +38,146 @@
#include "gtestutils.h"
#include "gslice.h"
/**
* SECTION:hooks
* @title: Hook Functions
* @short_description: support for manipulating lists of hook functions
*
* The #GHookList, #GHook and their related functions provide support for
* lists of hook functions. Functions can be added and removed from the lists,
* and the list of hook functions can be invoked.
*/
/**
* GHookList:
* @seq_id: the next free #GHook id
* @hook_size: the size of the #GHookList elements, in bytes
* @is_setup: 1 if the #GHookList has been initialized
* @hooks: the first #GHook element in the list
* @dummy3: unused
* @finalize_hook: the function to call to finalize a #GHook element.
* The default behaviour is to call the hooks @destroy function
* @dummy: unused
*
* The <structname>GHookList</structname> struct represents a
* list of hook functions.
*/
/**
* GHookFinalizeFunc:
* @hook_list: a #GHookList
* @hook: the hook in @hook_list that gets finalized
*
* Defines the type of function to be called when a hook in a
* list of hooks gets finalized.
*/
/**
* GHookFlagMask:
* @G_HOOK_FLAG_ACTIVE: set if the hook has not been destroyed
* @G_HOOK_FLAG_IN_CALL: set if the hook is currently being run
* @G_HOOK_FLAG_MASK: A mask covering all bits reserved for
* hook flags; see #G_HOOK_FLAGS_USER_SHIFT
*
* Flags used internally in the #GHook implementation.
*/
/**
* G_HOOK_FLAGS:
* @hook: a #GHook
*
* Returns the flags of a hook.
*/
/**
* G_HOOK_FLAG_USER_SHIFT:
*
* The position of the first bit which is not reserved for internal
* use be the #GHook implementation, i.e.
* <literal>1 &lt;&lt; G_HOOK_FLAG_USER_SHIFT</literal> is the first
* bit which can be used for application-defined flags.
*/
/**
* G_HOOK:
* @hook: a pointer
*
* Casts a pointer to a <literal>GHook*</literal>.
*/
/**
* G_HOOK_IS_VALID:
* @hook: a #GHook
*
* Returns %TRUE if the #GHook is valid, i.e. it is in a #GHookList,
* it is active and it has not been destroyed.
*
* Returns: %TRUE if the #GHook is valid
*/
/**
* G_HOOK_ACTIVE:
* @hook: a #GHook
*
* Returns %TRUE if the #GHook is active, which is normally the case
* until the #GHook is destroyed.
*
* Returns: %TRUE if the #GHook is active
*/
/**
* G_HOOK_IN_CALL:
* @hook: a #GHook
*
* Returns %TRUE if the #GHook function is currently executing.
*
* Returns: %TRUE if the #GHook function is currently executing
*/
/**
* G_HOOK_IS_UNLINKED:
* @hook: a #GHook
*
* Returns %TRUE if the #GHook is not in a #GHookList.
* Returns: %TRUE if the #GHook is not in a #GHookList
*/
/**
* GHook:
* @data: data which is passed to func when this hook is invoked
* @next: pointer to the next hook in the list
* @prev: pointer to the previous hook in the list
* @ref_count: the reference count of this hook
* @hook_id: the id of this hook, which is unique within its list
* @flags: flags which are set for this hook. See #GHookFlagMask for
* predefined flags
* @func: the function to call when this hook is invoked. The possible
* signatures for this function are #GHookFunc and #GHookCheckFunc
* @destroy: the default @finalize_hook function of a #GHookList calls
* this member of the hook that is being finalized
*
* The <structname>GHook</structname> struct represents a single hook
* function in a #GHookList.
*/
/**
* GHookFunc:
* @data: the data field of the #GHook is passed to the hook function here
*
* Defines the type of a hook function that can be invoked
* by g_hook_list_invoke().
*/
/**
* GHookCheckFunc:
* @data: the data field of the #GHook is passed to the hook function here
*
* Defines the type of a hook function that can be invoked
* by g_hook_list_invoke_check().
*
* Returns: %FALSE if the #GHook should be destroyed
*/
/* --- functions --- */
static void
@ -53,6 +193,15 @@ default_finalize_hook (GHookList *hook_list,
}
}
/**
* g_hook_list_init:
* @hook_list: a #GHookList
* @hook_size: the size of each element in the #GHookList,
* typically <literal>sizeof (GHook)</literal>
*
* Initializes a #GHookList.
* This must be called before the #GHookList is used.
*/
void
g_hook_list_init (GHookList *hook_list,
guint hook_size)
@ -70,6 +219,12 @@ g_hook_list_init (GHookList *hook_list,
hook_list->dummy[1] = NULL;
}
/**
* g_hook_list_clear:
* @hook_list: a #GHookList
*
* Removes all the #GHook elements from a #GHookList.
*/
void
g_hook_list_clear (GHookList *hook_list)
{
@ -101,6 +256,14 @@ g_hook_list_clear (GHookList *hook_list)
}
}
/**
* g_hook_alloc:
* @hook_list: a #GHookList
*
* Allocates space for a #GHook and initializes it.
*
* Returns: a new #GHook
*/
GHook*
g_hook_alloc (GHookList *hook_list)
{
@ -121,7 +284,14 @@ g_hook_alloc (GHookList *hook_list)
return hook;
}
/**
* g_hook_free:
* @hook_list: a #GHookList
* @hook: the #GHook to free
*
* Calls the #GHookList @finalize_hook function if it exists,
* and frees the memory allocated for the #GHook.
*/
void
g_hook_free (GHookList *hook_list,
GHook *hook)
@ -137,6 +307,14 @@ g_hook_free (GHookList *hook_list,
g_slice_free1 (hook_list->hook_size, hook);
}
/**
* g_hook_destroy_link:
* @hook_list: a #GHookList
* @hook: the #GHook to remove
*
* Removes one #GHook from a #GHookList, marking it
* inactive and calling g_hook_unref() on it.
*/
void
g_hook_destroy_link (GHookList *hook_list,
GHook *hook)
@ -152,6 +330,15 @@ g_hook_destroy_link (GHookList *hook_list,
}
}
/**
* g_hook_destroy:
* @hook_list: a #GHookList
* @hook_id: a hook ID
*
* Destroys a #GHook, given its ID.
*
* Returns: %TRUE if the #GHook was found in the #GHookList and destroyed
*/
gboolean
g_hook_destroy (GHookList *hook_list,
gulong hook_id)
@ -171,6 +358,15 @@ g_hook_destroy (GHookList *hook_list,
return FALSE;
}
/**
* g_hook_unref:
* @hook_list: a #GHookList
* @hook: the #GHook to unref
*
* Decrements the reference count of a #GHook.
* If the reference count falls to 0, the #GHook is removed
* from the #GHookList and g_hook_free() is called to free it.
*/
void
g_hook_unref (GHookList *hook_list,
GHook *hook)
@ -212,6 +408,15 @@ g_hook_unref (GHookList *hook_list,
}
}
/**
* g_hook_ref:
* @hook_list: a #GHookList
* @hook: the #GHook to increment the reference count of
*
* Increments the reference count for a #GHook.
*
* Returns: the @hook that was passed in (since 2.6)
*/
GHook *
g_hook_ref (GHookList *hook_list,
GHook *hook)
@ -225,6 +430,21 @@ g_hook_ref (GHookList *hook_list,
return hook;
}
/**
* g_hook_append:
* @hook_list: a #GHookList
* @hook: the #GHook to add to the end of @hook_list
*
* Appends a #GHook onto the end of a #GHookList.
*/
/**
* g_hook_prepend:
* @hook_list: a #GHookList
* @hook: the #GHook to add to the start of @hook_list
*
* Prepends a #GHook on the start of a #GHookList.
*/
void
g_hook_prepend (GHookList *hook_list,
GHook *hook)
@ -234,6 +454,14 @@ g_hook_prepend (GHookList *hook_list,
g_hook_insert_before (hook_list, hook_list->hooks, hook);
}
/**
* g_hook_insert_before:
* @hook_list: a #GHookList
* @sibling: the #GHook to insert the new #GHook before
* @hook: the #GHook to insert
*
* Inserts a #GHook into a #GHookList, before a given #GHook.
*/
void
g_hook_insert_before (GHookList *hook_list,
GHook *sibling,
@ -279,6 +507,15 @@ g_hook_insert_before (GHookList *hook_list,
}
}
/**
* g_hook_list_invoke:
* @hook_list: a #GHookList
* @may_recurse: %TRUE if functions which are already running
* (e.g. in another thread) can be called. If set to %FALSE,
* these are skipped
*
* Calls all of the #GHook functions in a #GHookList.
*/
void
g_hook_list_invoke (GHookList *hook_list,
gboolean may_recurse)
@ -306,6 +543,16 @@ g_hook_list_invoke (GHookList *hook_list,
}
}
/**
* g_hook_list_invoke_check:
* @hook_list: a #GHookList
* @may_recurse: %TRUE if functions which are already running
* (e.g. in another thread) can be called. If set to %FALSE,
* these are skipped
*
* Calls all of the #GHook functions in a #GHookList.
* Any function which returns %FALSE is removed from the #GHookList.
*/
void
g_hook_list_invoke_check (GHookList *hook_list,
gboolean may_recurse)
@ -336,6 +583,28 @@ g_hook_list_invoke_check (GHookList *hook_list,
}
}
/**
* GHookCheckMarshaller:
* @hook: a #GHook
* @marshal_data: user data
*
* Defines the type of function used by g_hook_list_marshal_check().
*
* Returns: %FALSE if @hook should be destroyed
*/
/**
* g_hook_list_marshal_check:
* @hook_list: a #GHookList
* @may_recurse: %TRUE if hooks which are currently running
* (e.g. in another thread) are considered valid. If set to %FALSE,
* these are skipped
* @marshaller: the function to call for each #GHook
* @marshal_data: data to pass to @marshaller
*
* Calls a function on each valid #GHook and destroys it if the
* function returns %FALSE.
*/
void
g_hook_list_marshal_check (GHookList *hook_list,
gboolean may_recurse,
@ -366,6 +635,25 @@ g_hook_list_marshal_check (GHookList *hook_list,
}
}
/**
* GHookMarshaller:
* @hook: a #GHook
* @marshal_data: user data
*
* Defines the type of function used by g_hook_list_marshal().
*/
/**
* g_hook_list_marshal:
* @hook_list: a #GHookList
* @may_recurse: %TRUE if hooks which are currently running
* (e.g. in another thread) are considered valid. If set to %FALSE,
* these are skipped
* @marshaller: the function to call for each #GHook
* @marshal_data: data to pass to @marshaller
*
* Calls a function on each valid #GHook.
*/
void
g_hook_list_marshal (GHookList *hook_list,
gboolean may_recurse,
@ -393,6 +681,20 @@ g_hook_list_marshal (GHookList *hook_list,
}
}
/**
* g_hook_first_valid:
* @hook_list: a #GHookList
* @may_be_in_call: %TRUE if hooks which are currently running
* (e.g. in another thread) are considered valid. If set to %FALSE,
* these are skipped
*
* Returns the first #GHook in a #GHookList which has not been destroyed.
* The reference count for the #GHook is incremented, so you must call
* g_hook_unref() to restore it when no longer needed. (Or call
* g_hook_next_valid() if you are stepping through the #GHookList.)
*
* Returns: the first valid #GHook, or %NULL if none are valid
*/
GHook*
g_hook_first_valid (GHookList *hook_list,
gboolean may_be_in_call)
@ -417,6 +719,21 @@ g_hook_first_valid (GHookList *hook_list,
return NULL;
}
/**
* g_hook_next_valid:
* @hook_list: a #GHookList
* @hook: the current #GHook
* @may_be_in_call: %TRUE if hooks which are currently running
* (e.g. in another thread) are considered valid. If set to %FALSE,
* these are skipped
*
* Returns the next #GHook in a #GHookList which has not been destroyed.
* The reference count for the #GHook is incremented, so you must call
* g_hook_unref() to restore it when no longer needed. (Or continue to call
* g_hook_next_valid() until %NULL is returned.)
*
* Returns: the next valid #GHook, or %NULL if none are valid
*/
GHook*
g_hook_next_valid (GHookList *hook_list,
GHook *hook,
@ -446,6 +763,15 @@ g_hook_next_valid (GHookList *hook_list,
return NULL;
}
/**
* g_hook_get:
* @hook_list: a #GHookList
* @hook_id: a hook id
*
* Returns the #GHook with the given id, or %NULL if it is not found.
*
* Returns: the #GHook with the given id, or %NULL if it is not found
*/
GHook*
g_hook_get (GHookList *hook_list,
gulong hook_id)
@ -466,6 +792,30 @@ g_hook_get (GHookList *hook_list,
return NULL;
}
/**
* GHookFindFunc:
* @hook: a #GHook
* @data: user data passed to g_hook_find_func()
*
* Defines the type of the function passed to g_hook_find().
*
* Returns: %TRUE if the required #GHook has been found
*/
/**
* g_hook_find:
* @hook_list: a #GHookList
* @need_valids: %TRUE if #GHook elements which have been destroyed
* should be skipped
* @func: the function to call for each #GHook, which should return
* %TRUE when the #GHook has been found
* @data: the data to pass to @func
*
* Finds a #GHook in a #GHookList using the given function to
* test for a match.
*
* Returns: the found #GHook or %NULL if no matching #GHook is found
*/
GHook*
g_hook_find (GHookList *hook_list,
gboolean need_valids,
@ -506,6 +856,18 @@ g_hook_find (GHookList *hook_list,
return NULL;
}
/**
* g_hook_find_data:
* @hook_list: a #GHookList
* @need_valids: %TRUE if #GHook elements which have been destroyed
* should be skipped
* @data: the data to find
*
* Finds a #GHook in a #GHookList with the given data.
*
* Returns: the #GHook with the given @data or %NULL if no matching
* #GHook is found
*/
GHook*
g_hook_find_data (GHookList *hook_list,
gboolean need_valids,
@ -530,6 +892,18 @@ g_hook_find_data (GHookList *hook_list,
return NULL;
}
/**
* g_hook_find_func:
* @hook_list: a #GHookList
* @need_valids: %TRUE if #GHook elements which have been destroyed
* should be skipped
* @func: the function to find
*
* Finds a #GHook in a #GHookList with the given function.
*
* Returns: the #GHook with the given @func or %NULL if no matching
* #GHook is found
*/
GHook*
g_hook_find_func (GHookList *hook_list,
gboolean need_valids,
@ -555,6 +929,19 @@ g_hook_find_func (GHookList *hook_list,
return NULL;
}
/**
* g_hook_find_func_data:
* @hook_list: a #GHookList
* @need_valids: %TRUE if #GHook elements which have been destroyed
* should be skipped
* @func: the function to find
* @data: the data to find
*
* Finds a #GHook in a #GHookList with the given function and data.
*
* Returns: the #GHook with the given @func and @data or %NULL if
* no matching #GHook is found
*/
GHook*
g_hook_find_func_data (GHookList *hook_list,
gboolean need_valids,
@ -582,6 +969,25 @@ g_hook_find_func_data (GHookList *hook_list,
return NULL;
}
/**
* GHookCompareFunc:
* @new_hook: the #GHook being inserted
* @sibling: the #GHook to compare with @new_hook
*
* Defines the type of function used to compare #GHook elements in
* g_hook_insert_sorted().
*
* Returns: a value &lt;= 0 if @new_hook should be before @sibling
*/
/**
* g_hook_insert_sorted:
* @hook_list: a #GHookList
* @hook: the #GHook to insert
* @func: the comparison function used to sort the #GHook elements
*
* Inserts a #GHook into a #GHookList, sorted by the given function.
*/
void
g_hook_insert_sorted (GHookList *hook_list,
GHook *hook,
@ -619,11 +1025,22 @@ g_hook_insert_sorted (GHookList *hook_list,
g_hook_unref (hook_list, sibling);
sibling = tmp;
}
}
g_hook_insert_before (hook_list, sibling, hook);
}
/**
* g_hook_compare_ids:
* @new_hook: a #GHook
* @sibling: a #GHook to compare with @new_hook
*
* Compares the ids of two #GHook elements, returning a negative value
* if the second id is greater than the first.
*
* Returns: a value &lt;= 0 if the id of @sibling is >= the id of @new_hook
*/
gint
g_hook_compare_ids (GHook *new_hook,
GHook *sibling)

View File

@ -53,6 +53,87 @@
#include "gthread.h"
#include "glib_trace.h"
/**
* SECTION:memory_slices
* @title: Memory Slices
* @short_description: efficient way to allocate groups of equal-sized
* chunks of memory
*
* 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.
*
* 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.
*
* 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.
*
* <example>
* <title>Using the slice allocator</title>
* <programlisting>
* gchar *mem[10000];
* gint i;
*
* /&ast; Allocate 10000 blocks. &ast;/
* for (i = 0; i &lt; 10000; i++)
* {
* mem[i] = g_slice_alloc (50);
*
* /&ast; Fill in the memory with some junk. &ast;/
* for (j = 0; j &lt; 50; j++)
* mem[i][j] = i * j;
* }
*
* /&ast; Now free all of the blocks. &ast;/
* 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;
*
* /&ast; Allocate one block, using the g_slice_new() macro. &ast;/
* array = g_slice_new (GRealArray);
* /&ast; We can now use array just like a normal pointer to a structure. &ast;/
* 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;
*
* /&ast; We can free the block, so it can be reused. &ast;/
* g_slice_free (GRealArray, array);
* </programlisting></example>
*/
/* the GSlice allocator is split up into 4 layers, roughly modelled after the slab
* allocator and magazine extensions as outlined in:
* + [Bonwick94] Jeff Bonwick, The slab allocator: An object-caching kernel
@ -771,6 +852,118 @@ thread_memory_magazine2_free (ThreadMemory *tmem,
}
/* --- API functions --- */
/**
* g_slice_new:
* @type: the type to allocate, typically a structure name
*
* 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.
*
* Returns: a pointer to the allocated block, cast to a pointer to @type
*
* Since: 2.10
*/
/**
* g_slice_new0:
* @type: the type to allocate, typically a structure name
*
* 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.
*
* Since: 2.10
*/
/**
* g_slice_dup:
* @type: the type to duplicate, typically a structure name
* @mem: the memory to copy into the allocated block
*
* 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.
*
* Returns: a pointer to the allocated block, cast to a pointer to @type
*
* Since: 2.14
*/
/**
* g_slice_free:
* @type: the type of the block to free, typically a structure name
* @mem: a pointer to the block to free
*
* 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.
*
* Since: 2.10
*/
/**
* g_slice_free_chain:
* @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
*
* 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.
*
* Since: 2.10
*/
/**
* g_slice_alloc:
* @block_size: the number of bytes to allocate
*
* 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.
*
* Returns: a pointer to the allocated memory block
*
* Since: 2.10
*/
gpointer
g_slice_alloc (gsize mem_size)
{
@ -816,6 +1009,20 @@ g_slice_alloc (gsize mem_size)
return mem;
}
/**
* g_slice_alloc0:
* @block_size: the number of bytes to allocate
*
* Allocates a block of memory via g_slice_alloc() and initializes
* 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.
*
* Returns: a pointer to the allocated block
*
* Since: 2.10
*/
gpointer
g_slice_alloc0 (gsize mem_size)
{
@ -825,6 +1032,18 @@ g_slice_alloc0 (gsize mem_size)
return mem;
}
/**
* g_slice_copy:
* @block_size: the number of bytes to allocate
* @mem_block: the memory to copy
*
* Allocates a block of memory from the slice allocator
* and copies @block_size bytes into it from @mem_block.
*
* Returns: a pointer to the allocated memory block
*
* Since: 2.14
*/
gpointer
g_slice_copy (gsize mem_size,
gconstpointer mem_block)
@ -835,6 +1054,23 @@ g_slice_copy (gsize mem_size,
return mem;
}
/**
* g_slice_free1:
* @block_size: the size of the block
* @mem_block: a pointer to the block to free
*
* 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.
*
* Since: 2.10
*/
void
g_slice_free1 (gsize mem_size,
gpointer mem_block)
@ -877,6 +1113,25 @@ g_slice_free1 (gsize mem_size,
TRACE (GLIB_SLICE_FREE((void*)mem_block, mem_size));
}
/**
* g_slice_free_chain_with_offset:
* @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
*
* 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.
*
* Since: 2.10
*/
void
g_slice_free_chain_with_offset (gsize mem_size,
gpointer mem_chain,