New files to implement atomic operations for different platforms. Fixes

2004-02-26  Sebastian Wilhelmi  <seppi@seppi.de>

	* glib/gatomic.c, glib/gatomic.h: New files to implement atomic
	operations for different platforms. Fixes bug #63621.

	* glib/glib.h: Include gatomic.h.

	* configure.in: Add test for assembler routines for atomic operations.

	* glib/Makefile.am: Add gatomic.c, gatomic.h.

	* tests/Makefile.am, tests/atomic-test.c: Unit test for atomic
	operations.

	* glib/glib-overrides.txt, glib/glib-sections.txt,
	glib/glib-docs.sgml, glib/tmpl/atomic_operations.sgml: Add docs
	for atomic operations.
This commit is contained in:
Sebastian Wilhelmi
2004-02-26 14:30:35 +00:00
committed by Sebastian Wilhelmi
parent fc9afe0d21
commit dbbb29f608
18 changed files with 1171 additions and 0 deletions

View File

@@ -1,3 +1,9 @@
2004-02-26 Sebastian Wilhelmi <seppi@seppi.de>
* glib/glib-overrides.txt, glib/glib-sections.txt,
glib/glib-docs.sgml, glib/tmpl/atomic_operations.sgml: Add docs
for atomic operations.
Tue Feb 24 14:09:21 2004 Owen Taylor <otaylor@redhat.com>
* === Released 2.3.3 ===

View File

@@ -8,6 +8,7 @@
<!ENTITY glib-Byte-Order-Macros SYSTEM "xml/byte_order.xml">
<!ENTITY glib-Numerical-Definitions SYSTEM "xml/numerical.xml">
<!ENTITY glib-Miscellaneous-Macros SYSTEM "xml/macros_misc.xml">
<!ENTITY glib-Atomic-Operations SYSTEM "xml/atomic_operations.xml">
<!ENTITY glib-Memory-Allocation SYSTEM "xml/memory.xml">
<!ENTITY glib-Error-Reporting SYSTEM "xml/error_reporting.xml">
<!ENTITY glib-Warnings-and-Assertions SYSTEM "xml/warnings.xml">
@@ -106,6 +107,7 @@ synchronize their operation.
&glib-Byte-Order-Macros;
&glib-Numerical-Definitions;
&glib-Miscellaneous-Macros;
&glib-Atomic-Operations;
</chapter>
<chapter id="glib-core">

View File

@@ -288,6 +288,62 @@ gchar c
gchar c
</FUNCTION>
# g_atomic
<FUNCTION>
<NAME>g_atomic_int_get</NAME>
<RETURNS>gint32</RETURNS>
gint32 *atomic
</FUNCTION>
<FUNCTION>
<NAME>g_atomic_int_exchange_and_add</NAME>
<RETURNS>gint32</RETURNS>
gint32 *atomic
gint32 val
</FUNCTION>
<FUNCTION>
<NAME>g_atomic_int_add</NAME>
<RETURNS>void</RETURNS>
gint32 *atomic
gint32 val
</FUNCTION>
<FUNCTION>
<NAME>g_atomic_int_compare_and_exchange</NAME>
<RETURNS>gboolean</RETURNS>
gint32 *atomic
gint32 oldval
gint32 newval
</FUNCTION>
<FUNCTION>
<NAME>g_atomic_pointer_get</NAME>
<RETURNS>gpointer</RETURNS>
gpointer *atomic
</FUNCTION>
<FUNCTION>
<NAME>g_atomic_pointer_compare_and_exchange</NAME>
<RETURNS>gboolean</RETURNS>
gpointer *atomic
gpointer oldval
gpointer newval
</FUNCTION>
<FUNCTION>
<NAME>g_atomic_int_inc</NAME>
<RETURNS>void</RETURNS>
gint32 *atomic
</FUNCTION>
<FUNCTION>
<NAME>g_atomic_int_dec_and_test</NAME>
<RETURNS>gboolean</RETURNS>
gint32 *atomic
</FUNCTION>
<STRUCT>
<NAME>GIConv</NAME>
</STRUCT>

View File

@@ -652,6 +652,25 @@ g_async_queue_timed_pop_unlocked
g_async_queue_length_unlocked
</SECTION>
<SECTION>
<TITLE>Atomic Operations</TITLE>
<FILE>atomic_operations</FILE>
g_atomic_int_get
g_atomic_int_add
g_atomic_int_exchange_and_add
g_atomic_int_compare_and_exchange
g_atomic_pointer_get
g_atomic_pointer_compare_and_exchange
g_atomic_int_inc
g_atomic_int_dec_and_test
</SECTION>
<SUBSECTION Private>
g_atomic_int_add_fallback
g_atomic_int_exchange_and_add_fallback
g_atomic_int_compare_and_exchange_fallback
g_atomic_pointer_compare_and_exchange_fallback
<SECTION>
<TITLE>IO Channels</TITLE>
<FILE>iochannels</FILE>

View File

@@ -0,0 +1,156 @@
<!-- ##### SECTION Title ##### -->
Atomic Operations
<!-- ##### SECTION Short_Description ##### -->
basic atomic integer and pointer operations
<!-- ##### SECTION Long_Description ##### -->
<para>
The following functions can be used to atomically access integers and
pointers. They are implemented as inline assembler function on most
platforms and use slower fall-backs otherwise. Using them can sometimes
save you from using a performance-expensive #GMutex to protect the
integer or pointer.
</para>
<para>
The most important usage is reference counting. Using
g_atomic_int_inc() and g_atomic_int_dec_and_test() makes reference
counting a very fast operation.
</para>
<note>
<para>
You must not directly read integers or pointers concurrently accessed
by other threads with with the following functions directly. Always use
g_atomic_int_get() and g_atomic_pointer_get() respectively. They are
acting as a memory barrier.
</para>
</note>
<note>
<para>
If you are using those functions for anything apart from simple
reference counting, you should really be aware of the implications of
doing that. There are literally thousands of ways to shoot yourself in
the foot. So if in doubt, use a #GMutex. If you don't know, what
memory barriers are, do not use anything but g_atomic_int_inc() and
g_atomic_int_dec_and_test().
</para>
</note>
<note>
<para>
It is not safe to set an integer or pointer just by assigning to it,
when it is concurrently accessed by other threads with the following
functions. Use g_atomic_int_compare_and_exchange() or
g_atomic_pointer_compare_and_exchange() respectively.
</para>
</note>
<!-- ##### SECTION See_Also ##### -->
<para>
<variablelist>
<varlistentry>
<term>#GMutex</term>
<listitem><para>GLib mutual exclusions.</para></listitem>
</varlistentry>
</variablelist>
</para>
<!-- ##### FUNCTION g_atomic_int_get ##### -->
<para>
Reads the value of the integer pointed to by @atomic. Also acts as
a memory barrier.
</para>
@atomic: a pointer to a 32-bit integer.
@Returns: the value of *@atomic.
@Since: 2.4
<!-- ##### FUNCTION g_atomic_int_add ##### -->
<para>
Atomically adds @val to the integer pointed to by @atomic.
Also acts as a memory barrier.
</para>
@atomic: a pointer to a 32-bit integer.
@val: the value to add to *@atomic.
@Since: 2.4
<!-- ##### FUNCTION g_atomic_int_exchange_and_add ##### -->
<para>
Atomically adds @val to the integer pointed to by @atomic. It returns
the value of *@atomic just before the addition took place.
Also acts as a memory barrier.
</para>
@atomic: a pointer to a 32-bit integer.
@val: the value to add to *@atomic.
@Returns: the value of *@atomic before the addition.
@Since: 2.4
<!-- ##### FUNCTION g_atomic_int_compare_and_exchange ##### -->
<para>
Compares @oldval with the integer pointed to by @atomic and
if they are equal, atomically exchanges *@atomic with @newval.
Also acts as a memory barrier.
</para>
@atomic: a pointer to a 32-bit integer.
@oldval: the assumed old value of *@atomic.
@newval: the new value of *@atomic.
@Returns: %TRUE, if *@atomic was equal @oldval. %FALSE otherwise.
@Since: 2.4
<!-- ##### FUNCTION g_atomic_pointer_get ##### -->
<para>
Reads the value of the pointer pointed to by @atomic. Also acts as
a memory barrier.
</para>
@atomic: a pointer to a #gpointer.
@Returns: the value to add to *@atomic.
@Since: 2.4
<!-- ##### FUNCTION g_atomic_pointer_compare_and_exchange ##### -->
<para>
Compares @oldval with the pointer pointed to by @atomic and
if they are equal, atomically exchanges *@atomic with @newval.
Also acts as a memory barrier.
</para>
@atomic: a pointer to a #gpointer.
@oldval: the assumed old value of *@atomic.
@newval: the new value of *@atomic.
@Returns: %TRUE, if *@atomic was equal @oldval. %FALSE otherwise.
@Since: 2.4
<!-- ##### FUNCTION g_atomic_int_inc ##### -->
<para>
Atomically increments the integer pointed to by @atomic by 1.
</para>
@atomic: a pointer to a 32-bit integer.
@Since: 2.4
<!-- ##### FUNCTION g_atomic_int_dec_and_test ##### -->
<para>
Atomically decrements the integer pointed to by @atomic by 1.
</para>
@atomic: a pointer to a 32-bit integer.
@Returns: %TRUE, if the integer pointed to by @atomic is 0 after
decrementing it.
@Since: 2.4