mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-24 14:36:13 +01:00
glib: Rewrite gatomic.[ch]
- remove all inline assembly versions - implement the atomic operations using either GCC intrinsics, the Windows interlocked API or a mutex-based fallback - drop gatomic-gcc.c since these are now defined in the header file. Adjust Makefile.am accordingly. - expand the set of operations: support 'get', 'set', 'compare and exchange', 'add', 'or', and 'xor' for both integers and pointers - deprecate g_atomic_int_exchange_and_add since g_atomic_int_add (as with all the new arithmetic operations) now returns the prior value - unify the use of macros: all functions are now wrapped in macros that perform the proper casts and checks - remove G_GNUC_MAY_ALIAS use; it was never required for the integer operations (since casting between pointers that only vary in signedness of the target is explicitly permitted) and we avoid the need for the pointer operations by using simple 'void *' instead of 'gpointer *' (which caused the 'type-punned pointer' warning) - provide function implementations of g_atomic_int_inc and g_atomic_int_dec_and_test: these were strictly macros before - improve the documentation to make it very clear exactly which types of pointers these operations may be used with - remove a few uses of the now-deprecated g_atomic_int_exchange_and_add - drop initialisation of gatomic from gthread (by using a GStaticMutex instead of a GMutex) - update glib.symbols and documentation sections files Closes #650823 and #650935
This commit is contained in:
parent
2fb57ff46f
commit
8382135265
@ -759,17 +759,28 @@ g_async_queue_sort_unlocked
|
||||
|
||||
<SECTION>
|
||||
<TITLE>Atomic Operations</TITLE>
|
||||
<FILE>atomic_operations</FILE>g
|
||||
<FILE>atomic_operations</FILE>
|
||||
g_atomic_int_get
|
||||
g_atomic_int_set
|
||||
g_atomic_int_add
|
||||
g_atomic_int_exchange_and_add
|
||||
g_atomic_int_inc
|
||||
g_atomic_int_dec_and_test
|
||||
g_atomic_int_compare_and_exchange
|
||||
g_atomic_int_add
|
||||
g_atomic_int_and
|
||||
g_atomic_int_or
|
||||
g_atomic_int_xor
|
||||
|
||||
<SUBSECTION>
|
||||
g_atomic_pointer_get
|
||||
g_atomic_pointer_set
|
||||
g_atomic_pointer_compare_and_exchange
|
||||
g_atomic_int_inc
|
||||
g_atomic_int_dec_and_test
|
||||
g_atomic_pointer_add
|
||||
g_atomic_pointer_and
|
||||
g_atomic_pointer_or
|
||||
g_atomic_pointer_xor
|
||||
|
||||
<SUBSECTION>
|
||||
g_atomic_int_exchange_and_add
|
||||
|
||||
<SUBSECTION Private>
|
||||
G_ATOMIC_OP_MEMORY_BARRIER_NEEDED
|
||||
|
@ -42,12 +42,6 @@ gregex_c =
|
||||
gregex_h =
|
||||
endif
|
||||
|
||||
if HAVE_GCC_BUILTINS_FOR_ATOMIC_OPERATIONS
|
||||
gatomic_c = gatomic-gcc.c
|
||||
else
|
||||
gatomic_c = gatomic.c
|
||||
endif
|
||||
|
||||
SUBDIRS = libcharset $(PRINTF_SUBDIR) $(MAYBE_PCRE) update-pcre . tests
|
||||
|
||||
DIST_SUBDIRS = libcharset gnulib pcre update-pcre tests
|
||||
@ -121,7 +115,7 @@ libglib_2_0_la_SOURCES = \
|
||||
glib_probes.d \
|
||||
garray.c \
|
||||
gasyncqueue.c \
|
||||
$(gatomic_c) \
|
||||
gatomic.c \
|
||||
gbacktrace.c \
|
||||
gbase64.c \
|
||||
gbitlock.c \
|
||||
|
@ -1,104 +0,0 @@
|
||||
/* GLIB - Library of useful routines for C programming
|
||||
* gatomic-gcc.c: atomic operations using GCC builtins.
|
||||
* Copyright (C) 2009 Hiroyuki Ikezoe
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gatomic.h"
|
||||
|
||||
/* All atomic operations are available as macros evaluating
|
||||
* to gcc builtins (when using gcc builtins for atomic operations).
|
||||
* For ABI stability, we provide functions for them too.
|
||||
*
|
||||
* To avoid interference, undefine the macros first.
|
||||
*/
|
||||
|
||||
#undef g_atomic_int_exchange_and_add
|
||||
#undef g_atomic_int_compare_and_exchange
|
||||
#undef g_atomic_int_add
|
||||
#undef g_atomic_int_get
|
||||
#undef g_atomic_int_set
|
||||
#undef g_atomic_pointer_compare_and_exchange
|
||||
#undef g_atomic_pointer_get
|
||||
#undef g_atomic_pointer_set
|
||||
|
||||
gint
|
||||
g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
|
||||
gint val)
|
||||
{
|
||||
return __sync_fetch_and_add (atomic, val);
|
||||
}
|
||||
|
||||
void
|
||||
g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
|
||||
gint val)
|
||||
{
|
||||
__sync_fetch_and_add (atomic, val);
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
|
||||
gint oldval,
|
||||
gint newval)
|
||||
{
|
||||
return __sync_bool_compare_and_swap (atomic, oldval, newval);
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
|
||||
gpointer oldval,
|
||||
gpointer newval)
|
||||
{
|
||||
return __sync_bool_compare_and_swap (atomic, oldval, newval);
|
||||
}
|
||||
|
||||
void
|
||||
_g_atomic_thread_init (void)
|
||||
{
|
||||
}
|
||||
|
||||
gint
|
||||
g_atomic_int_get (volatile gint G_GNUC_MAY_ALIAS *atomic)
|
||||
{
|
||||
__sync_synchronize ();
|
||||
return *atomic;
|
||||
}
|
||||
|
||||
void
|
||||
g_atomic_int_set (volatile gint G_GNUC_MAY_ALIAS *atomic,
|
||||
gint newval)
|
||||
{
|
||||
*atomic = newval;
|
||||
__sync_synchronize ();
|
||||
}
|
||||
|
||||
gpointer
|
||||
g_atomic_pointer_get (volatile gpointer G_GNUC_MAY_ALIAS *atomic)
|
||||
{
|
||||
__sync_synchronize ();
|
||||
return *atomic;
|
||||
}
|
||||
|
||||
void
|
||||
g_atomic_pointer_set (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
|
||||
gpointer newval)
|
||||
{
|
||||
*atomic = newval;
|
||||
__sync_synchronize ();
|
||||
}
|
1892
glib/gatomic.c
1892
glib/gatomic.c
File diff suppressed because it is too large
Load Diff
324
glib/gatomic.h
324
glib/gatomic.h
@ -1,30 +1,22 @@
|
||||
/* GLIB - Library of useful routines for C programming
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
/*
|
||||
* Copyright © 2011 Ryan Lortie
|
||||
*
|
||||
* g_atomic_*: atomic operations.
|
||||
* Copyright (C) 2003 Sebastian Wilhelmi
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* licence, or (at your option) any later version.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GLib Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GLib at ftp://ftp.gtk.org/pub/gtk/.
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*
|
||||
* Author: Ryan Lortie <desrt@desrt.ca>
|
||||
*/
|
||||
|
||||
#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
|
||||
@ -34,122 +26,192 @@
|
||||
#ifndef __G_ATOMIC_H__
|
||||
#define __G_ATOMIC_H__
|
||||
|
||||
#include <glib/gtypes.h>
|
||||
#include "glib/gtypes.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gint g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
|
||||
gint val);
|
||||
void g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
|
||||
gint val);
|
||||
gboolean g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
|
||||
gint oldval,
|
||||
gint newval);
|
||||
gboolean g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
|
||||
gpointer oldval,
|
||||
gpointer newval);
|
||||
gint g_atomic_int_get (volatile gint *atomic);
|
||||
void g_atomic_int_set (volatile gint *atomic,
|
||||
gint newval);
|
||||
void g_atomic_int_inc (volatile gint *atomic);
|
||||
gboolean g_atomic_int_dec_and_test (volatile gint *atomic);
|
||||
gboolean g_atomic_int_compare_and_exchange (volatile gint *atomic,
|
||||
gint oldval,
|
||||
gint newval);
|
||||
gint g_atomic_int_add (volatile gint *atomic,
|
||||
gint val);
|
||||
guint g_atomic_int_and (volatile guint *atomic,
|
||||
guint val);
|
||||
guint g_atomic_int_or (volatile guint *atomic,
|
||||
guint val);
|
||||
guint g_atomic_int_xor (volatile guint *atomic,
|
||||
guint val);
|
||||
|
||||
gint g_atomic_int_get (volatile gint G_GNUC_MAY_ALIAS *atomic);
|
||||
void g_atomic_int_set (volatile gint G_GNUC_MAY_ALIAS *atomic,
|
||||
gint newval);
|
||||
gpointer g_atomic_pointer_get (volatile gpointer G_GNUC_MAY_ALIAS *atomic);
|
||||
void g_atomic_pointer_set (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
|
||||
gpointer newval);
|
||||
gpointer g_atomic_pointer_get (volatile void *atomic);
|
||||
void g_atomic_pointer_set (volatile void *atomic,
|
||||
gpointer newval);
|
||||
gboolean g_atomic_pointer_compare_and_exchange (volatile void *atomic,
|
||||
gpointer oldval,
|
||||
gpointer newval);
|
||||
gssize g_atomic_pointer_add (volatile void *atomic,
|
||||
gssize val);
|
||||
gsize g_atomic_pointer_and (volatile void *atomic,
|
||||
gsize val);
|
||||
gsize g_atomic_pointer_or (volatile void *atomic,
|
||||
gsize val);
|
||||
gsize g_atomic_pointer_xor (volatile void *atomic,
|
||||
gsize val);
|
||||
|
||||
#if defined(__GNUC__) && defined(G_ATOMIC_OP_USE_GCC_BUILTINS)
|
||||
|
||||
#define g_atomic_int_exchange_and_add(atomic,val) \
|
||||
__extension__ ({ G_STATIC_ASSERT_EXPR(sizeof (*(atomic)) == sizeof (gint)); \
|
||||
__sync_fetch_and_add((atomic),(val)); })
|
||||
|
||||
#define g_atomic_int_add(atomic,val) \
|
||||
__extension__ ({ G_STATIC_ASSERT_EXPR(sizeof (*(atomic)) == sizeof (gint)); \
|
||||
__sync_fetch_and_add((atomic),(val)); })
|
||||
|
||||
#define g_atomic_int_compare_and_exchange(atomic,oldval,newval) \
|
||||
__extension__ ({ G_STATIC_ASSERT_EXPR(sizeof (*(atomic)) == sizeof (gint)); \
|
||||
__sync_bool_compare_and_swap((atomic),(oldval),(newval)); })
|
||||
|
||||
#define g_atomic_int_get(atomic) \
|
||||
__extension__ ({ G_STATIC_ASSERT_EXPR(sizeof (*(atomic)) == sizeof (gint)); \
|
||||
__sync_synchronize(); *(atomic); })
|
||||
|
||||
#define g_atomic_int_set(atomic,newval) \
|
||||
__extension__ ({ G_STATIC_ASSERT_EXPR(sizeof (*(atomic)) == sizeof (gint)); \
|
||||
*(atomic) = (newval); __sync_synchronize(); })
|
||||
|
||||
#define g_atomic_pointer_compare_and_exchange(atomic,oldval,newval) \
|
||||
__extension__ ({ G_STATIC_ASSERT_EXPR(sizeof (*(atomic)) == sizeof (gpointer)); \
|
||||
__sync_bool_compare_and_swap((atomic),(oldval),(newval)); })
|
||||
|
||||
#define g_atomic_pointer_get(atomic) \
|
||||
__extension__ ({ G_STATIC_ASSERT_EXPR(sizeof (*(atomic)) == sizeof (gpointer)); \
|
||||
__sync_synchronize(); *(atomic); })
|
||||
|
||||
#define g_atomic_pointer_set(atomic,newval) \
|
||||
__extension__ ({ G_STATIC_ASSERT_EXPR(sizeof (*(atomic)) == sizeof (gpointer)); \
|
||||
*(atomic) = (newval); __sync_synchronize(); })
|
||||
|
||||
#elif !defined(G_ATOMIC_OP_MEMORY_BARRIER_NEEDED)
|
||||
|
||||
# define g_atomic_int_get(atomic) ((gint)*(atomic))
|
||||
# define g_atomic_int_set(atomic, newval) ((void) (*(atomic) = (newval)))
|
||||
# define g_atomic_pointer_get(atomic) ((gpointer)*(atomic))
|
||||
# define g_atomic_pointer_set(atomic, newval) ((void) (*(atomic) = (newval)))
|
||||
|
||||
#else
|
||||
|
||||
#define g_atomic_int_exchange_and_add(atomic,val) \
|
||||
(G_STATIC_ASSERT_EXPR(sizeof (*(atomic)) == sizeof (gint)), \
|
||||
(g_atomic_int_exchange_and_add) ((volatile gint G_GNUC_MAY_ALIAS *) (volatile void *) (atomic), (val)))
|
||||
#define g_atomic_int_add(atomic,val) \
|
||||
(G_STATIC_ASSERT_EXPR(sizeof (*(atomic)) == sizeof (gint)), \
|
||||
(g_atomic_int_add) ((volatile gint G_GNUC_MAY_ALIAS *) (volatile void *) (atomic), (val)))
|
||||
#define g_atomic_int_compare_and_exchange(atomic,oldval,newval) \
|
||||
(G_STATIC_ASSERT_EXPR(sizeof (*(atomic)) == sizeof (gint)), \
|
||||
(g_atomic_int_compare_and_exchange) ((volatile gint G_GNUC_MAY_ALIAS *) (volatile void *) (atomic), (oldval), (newval)))
|
||||
#define g_atomic_pointer_compare_and_exchange(atomic,oldval,newval) \
|
||||
(G_STATIC_ASSERT_EXPR(sizeof (*(atomic)) == sizeof (gpointer)), \
|
||||
(g_atomic_pointer_compare_and_exchange) ((volatile gpointer G_GNUC_MAY_ALIAS *) (volatile void *) (atomic), (oldval), (newval)))
|
||||
#define g_atomic_int_get(atomic) \
|
||||
(G_STATIC_ASSERT_EXPR(sizeof (*(atomic)) == sizeof (gint)), \
|
||||
(g_atomic_int_get) ((volatile gint G_GNUC_MAY_ALIAS *) (volatile void *) (atomic)))
|
||||
#define g_atomic_int_set(atomic, newval) \
|
||||
(G_STATIC_ASSERT_EXPR(sizeof (*(atomic)) == sizeof (gint)), \
|
||||
(g_atomic_int_set) ((volatile gint G_GNUC_MAY_ALIAS *) (volatile void *) (atomic), (newval)))
|
||||
#define g_atomic_pointer_get(atomic) \
|
||||
(G_STATIC_ASSERT_EXPR(sizeof (*(atomic)) == sizeof (gpointer)), \
|
||||
(g_atomic_pointer_get) ((volatile gpointer G_GNUC_MAY_ALIAS *) (volatile void *) (atomic)))
|
||||
#define g_atomic_pointer_set(atomic, newval) \
|
||||
(G_STATIC_ASSERT_EXPR(sizeof (*(atomic)) == sizeof (gpointer)), \
|
||||
(g_atomic_pointer_set) ((volatile gpointer G_GNUC_MAY_ALIAS *) (volatile void *) (atomic), (newval)))
|
||||
|
||||
#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
|
||||
|
||||
/**
|
||||
* g_atomic_int_inc:
|
||||
* @atomic: a pointer to an integer.
|
||||
*
|
||||
* Atomically increments the integer pointed to by @atomic by 1.
|
||||
*
|
||||
* Since: 2.4
|
||||
*/
|
||||
#define g_atomic_int_inc(atomic) (g_atomic_int_add ((atomic), 1))
|
||||
|
||||
/**
|
||||
* g_atomic_int_dec_and_test:
|
||||
* @atomic: a pointer to an integer
|
||||
*
|
||||
* Atomically decrements the integer pointed to by @atomic by 1.
|
||||
*
|
||||
* Returns: %TRUE if the integer pointed to by @atomic is 0
|
||||
* after decrementing it
|
||||
*
|
||||
* Since: 2.4
|
||||
*/
|
||||
#define g_atomic_int_dec_and_test(atomic) \
|
||||
(g_atomic_int_exchange_and_add ((atomic), -1) == 1)
|
||||
#ifndef G_DISABLE_DEPRECATED
|
||||
gint g_atomic_int_exchange_and_add (volatile gint *atomic,
|
||||
gint val);
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#if defined(__GNUC__) && defined(G_ATOMIC_OP_USE_GCC_BUILTINS)
|
||||
|
||||
#define g_atomic_int_get(atomic) \
|
||||
(__extension__ ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
|
||||
(void) (0 ? *(atomic) ^ *(atomic) : 0); \
|
||||
__sync_synchronize (); \
|
||||
(gint) *(atomic); \
|
||||
}))
|
||||
#define g_atomic_int_set(atomic, newval) \
|
||||
(__extension__ ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
|
||||
(void) (0 ? *(atomic) ^ (newval) : 0); \
|
||||
*(atomic) = (newval); \
|
||||
__sync_synchronize (); \
|
||||
}))
|
||||
#define g_atomic_int_inc(atomic) \
|
||||
(__extension__ ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
|
||||
(void) (0 ? *(atomic) ^ *(atomic) : 0); \
|
||||
(void) __sync_fetch_and_add ((atomic), 1); \
|
||||
}))
|
||||
#define g_atomic_int_dec_and_test(atomic) \
|
||||
(__extension__ ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
|
||||
(void) (0 ? *(atomic) ^ *(atomic) : 0); \
|
||||
__sync_fetch_and_sub ((atomic), 1) == 1; \
|
||||
}))
|
||||
#define g_atomic_int_compare_and_exchange(atomic, oldval, newval) \
|
||||
(__extension__ ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
|
||||
(void) (0 ? *(atomic) ^ (newval) ^ (oldval) : 0); \
|
||||
(gboolean) __sync_bool_compare_and_swap ((atomic), (oldval), (newval)); \
|
||||
}))
|
||||
#define g_atomic_int_add(atomic, val) \
|
||||
(__extension__ ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
|
||||
(void) (0 ? *(atomic) ^ (val) : 0); \
|
||||
(gint) __sync_fetch_and_add ((atomic), (val)); \
|
||||
}))
|
||||
#define g_atomic_int_and(atomic, val) \
|
||||
(__extension__ ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
|
||||
(void) (0 ? *(atomic) ^ (val) : 0); \
|
||||
(guint) __sync_fetch_and_and ((atomic), (val)); \
|
||||
}))
|
||||
#define g_atomic_int_or(atomic, val) \
|
||||
(__extension__ ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
|
||||
(void) (0 ? *(atomic) ^ (val) : 0); \
|
||||
(guint) __sync_fetch_and_or ((atomic), (val)); \
|
||||
}))
|
||||
#define g_atomic_int_xor(atomic, val) \
|
||||
(__extension__ ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
|
||||
(void) (0 ? *(atomic) ^ (val) : 0); \
|
||||
(guint) __sync_fetch_and_xor ((atomic), (val)); \
|
||||
}))
|
||||
|
||||
#define g_atomic_pointer_get(atomic) \
|
||||
(__extension__ ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
|
||||
__sync_synchronize (); \
|
||||
(gpointer) *(atomic); \
|
||||
}))
|
||||
#define g_atomic_pointer_set(atomic, newval) \
|
||||
(__extension__ ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
|
||||
(void) (0 ? (gpointer) *(atomic) : 0); \
|
||||
*(atomic) = (__typeof__ (*(atomic))) (gsize) (newval); \
|
||||
__sync_synchronize (); \
|
||||
}))
|
||||
#define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \
|
||||
(__extension__ ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
|
||||
(void) (0 ? (gpointer) *(atomic) : 0); \
|
||||
(gboolean) __sync_bool_compare_and_swap ((atomic), (oldval), (newval)); \
|
||||
}))
|
||||
#define g_atomic_pointer_add(atomic, val) \
|
||||
(__extension__ ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
|
||||
(void) (0 ? (gpointer) *(atomic) : 0); \
|
||||
(void) (0 ? (val) ^ (val) : 0); \
|
||||
(gssize) __sync_fetch_and_add ((atomic), (val)); \
|
||||
}))
|
||||
#define g_atomic_pointer_and(atomic, val) \
|
||||
(__extension__ ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
|
||||
(void) (0 ? (gpointer) *(atomic) : 0); \
|
||||
(void) (0 ? (val) ^ (val) : 0); \
|
||||
(gsize) __sync_fetch_and_and ((atomic), (val)); \
|
||||
}))
|
||||
#define g_atomic_pointer_or(atomic, val) \
|
||||
(__extension__ ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
|
||||
(void) (0 ? (gpointer) *(atomic) : 0); \
|
||||
(void) (0 ? (val) ^ (val) : 0); \
|
||||
(gsize) __sync_fetch_and_or ((atomic), (val)); \
|
||||
}))
|
||||
#define g_atomic_pointer_xor(atomic, val) \
|
||||
(__extension__ ({ \
|
||||
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
|
||||
(void) (0 ? (gpointer) *(atomic) : 0); \
|
||||
(void) (0 ? (val) ^ (val) : 0); \
|
||||
(gsize) __sync_fetch_and_xor ((atomic), (val)); \
|
||||
}))
|
||||
|
||||
#else /* defined(__GNUC__) && defined(G_ATOMIC_OP_USE_GCC_BUILTINS) */
|
||||
|
||||
#define g_atomic_int_get(atomic) \
|
||||
(g_atomic_int_get ((gint *) (atomic)))
|
||||
#define g_atomic_int_set(atomic, newval) \
|
||||
(g_atomic_int_set ((gint *) (atomic), (gint) (newval)))
|
||||
#define g_atomic_int_compare_and_exchange(atomic, oldval, newval) \
|
||||
(g_atomic_int_compare_and_exchange ((gint *) (atomic), (oldval), (newval)))
|
||||
#define g_atomic_int_add(atomic, val) \
|
||||
(g_atomic_int_add ((gint *) (atomic), (val)))
|
||||
#define g_atomic_int_and(atomic, val) \
|
||||
(g_atomic_int_and ((gint *) (atomic), (val)))
|
||||
#define g_atomic_int_or(atomic, val) \
|
||||
(g_atomic_int_or ((gint *) (atomic), (val)))
|
||||
#define g_atomic_int_xor(atomic, val) \
|
||||
(g_atomic_int_xor ((gint *) (atomic), (val)))
|
||||
#define g_atomic_int_inc(atomic) \
|
||||
(g_atomic_int_inc ((gint *) (atomic)))
|
||||
#define g_atomic_int_dec_and_test(atomic) \
|
||||
(g_atomic_int_dec_and_test ((gint *) (atomic)))
|
||||
|
||||
#define g_atomic_pointer_get(atomic) \
|
||||
(g_atomic_pointer_get (atomic))
|
||||
#define g_atomic_pointer_set(atomic, newval) \
|
||||
(g_atomic_pointer_set ((atomic), (gpointer) (newval)))
|
||||
#define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \
|
||||
(g_atomic_pointer_compare_and_exchange ((atomic), (gpointer) (oldval), (gpointer) (newval)))
|
||||
#define g_atomic_pointer_add(atomic, val) \
|
||||
(g_atomic_pointer_add ((atomic), (gssize) (val)))
|
||||
#define g_atomic_pointer_and(atomic, val) \
|
||||
(g_atomic_pointer_and ((atomic), (gsize) (val)))
|
||||
#define g_atomic_pointer_or(atomic, val) \
|
||||
(g_atomic_pointer_or ((atomic), (gsize) (val)))
|
||||
#define g_atomic_pointer_xor(atomic, val) \
|
||||
(g_atomic_pointer_xor ((atomic), (gsize) (val)))
|
||||
|
||||
#endif /* defined(__GNUC__) && defined(G_ATOMIC_OP_USE_GCC_BUILTINS) */
|
||||
|
||||
#endif /* __G_ATOMIC_H__ */
|
||||
|
@ -69,13 +69,22 @@ g_async_queue_unref
|
||||
g_async_queue_ref_unlocked
|
||||
g_async_queue_unref_and_unlock
|
||||
g_atomic_int_add
|
||||
g_atomic_int_and
|
||||
g_atomic_int_compare_and_exchange
|
||||
g_atomic_int_dec_and_test
|
||||
g_atomic_int_exchange_and_add
|
||||
g_atomic_pointer_compare_and_exchange
|
||||
g_atomic_int_get
|
||||
g_atomic_pointer_get
|
||||
g_atomic_int_inc
|
||||
g_atomic_int_or
|
||||
g_atomic_int_set
|
||||
g_atomic_int_xor
|
||||
g_atomic_pointer_add
|
||||
g_atomic_pointer_and
|
||||
g_atomic_pointer_compare_and_exchange
|
||||
g_atomic_pointer_get
|
||||
g_atomic_pointer_or
|
||||
g_atomic_pointer_set
|
||||
g_atomic_pointer_xor
|
||||
g_on_error_query
|
||||
g_on_error_stack_trace
|
||||
g_base64_encode_step
|
||||
|
@ -945,7 +945,6 @@ g_thread_init_glib (void)
|
||||
_g_messages_thread_init_nomessage ();
|
||||
|
||||
/* we may run full-fledged initializers from here */
|
||||
_g_atomic_thread_init ();
|
||||
_g_convert_thread_init ();
|
||||
_g_rand_thread_init ();
|
||||
_g_main_thread_init ();
|
||||
|
@ -207,7 +207,7 @@ g_thread_pool_wait_for_new_pool (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_atomic_int_exchange_and_add (&kill_unused_threads, -1) > 0)
|
||||
if (g_atomic_int_add (&kill_unused_threads, -1) > 0)
|
||||
{
|
||||
pool = NULL;
|
||||
break;
|
||||
|
@ -12,7 +12,6 @@ main (void)
|
||||
g_atomic_int_set (&u, 5);
|
||||
g_atomic_int_get (&u);
|
||||
g_atomic_int_compare_and_exchange (&u, 6, 7);
|
||||
g_atomic_int_exchange_and_add (&u, 1);
|
||||
g_atomic_int_add (&u, 1);
|
||||
g_atomic_int_inc (&u);
|
||||
(void) g_atomic_int_dec_and_test (&u);
|
||||
@ -20,7 +19,6 @@ main (void)
|
||||
g_atomic_int_set (&s, 5);
|
||||
g_atomic_int_get (&s);
|
||||
g_atomic_int_compare_and_exchange (&s, 6, 7);
|
||||
g_atomic_int_exchange_and_add (&s, 1);
|
||||
g_atomic_int_add (&s, 1);
|
||||
g_atomic_int_inc (&s);
|
||||
(void) g_atomic_int_dec_and_test (&s);
|
||||
|
@ -2654,7 +2654,7 @@ g_object_ref (gpointer _object)
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
|
||||
old_val = g_atomic_int_exchange_and_add ((int *)&object->ref_count, 1);
|
||||
old_val = g_atomic_int_add (&object->ref_count, 1);
|
||||
|
||||
if (old_val == 1 && OBJECT_HAS_TOGGLE_REF (object))
|
||||
toggle_refs_notify (object, FALSE);
|
||||
@ -2735,7 +2735,7 @@ g_object_unref (gpointer _object)
|
||||
g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
|
||||
|
||||
/* decrement the last reference */
|
||||
old_ref = g_atomic_int_exchange_and_add ((int *)&object->ref_count, -1);
|
||||
old_ref = g_atomic_int_add (&object->ref_count, -1);
|
||||
|
||||
TRACE (GOBJECT_OBJECT_UNREF(object,G_TYPE_FROM_INSTANCE(object),old_ref));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user