mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-28 10:30:03 +01:00
Add an implementation for the CRIS and CRISv32 architectures, by Peter
* configure.in: * glib/gatomic.c: Add an implementation for the CRIS and CRISv32 architectures, by Peter Kjellerstedt svn path=/trunk/; revision=7732
This commit is contained in:
parent
bb63c612bf
commit
154fe24134
@ -1,3 +1,11 @@
|
||||
2008-12-07 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
Bug 508021 – Add support for the CRIS and CRISv32 architectures
|
||||
|
||||
* configure.in:
|
||||
* glib/gatomic.c: Add an implementation for the CRIS and CRISv32
|
||||
architectures, by Peter Kjellerstedt
|
||||
|
||||
2008-12-02 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* glib/gkeyfile.c: Some more documentation additions.
|
||||
|
12
configure.in
12
configure.in
@ -2404,6 +2404,18 @@ if test x"$GCC" = xyes; then
|
||||
[arm atomic implementation])
|
||||
glib_memory_barrier_needed=no
|
||||
;;
|
||||
crisv32*|etraxfs*)
|
||||
AC_MSG_RESULT([crisv32])
|
||||
AC_DEFINE_UNQUOTED(G_ATOMIC_CRISV32, 1,
|
||||
[crisv32 atomic implementation])
|
||||
glib_memory_barrier_needed=no
|
||||
;;
|
||||
cris*|etrax*)
|
||||
AC_MSG_RESULT([cris])
|
||||
AC_DEFINE_UNQUOTED(G_ATOMIC_CRIS, 1,
|
||||
[cris atomic implementation])
|
||||
glib_memory_barrier_needed=no
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT([none])
|
||||
glib_memory_barrier_needed=yes
|
||||
|
126
glib/gatomic.c
126
glib/gatomic.c
@ -651,9 +651,131 @@ g_atomic_pointer_compare_and_exchange (volatile gpointer *atomic,
|
||||
|
||||
return result;
|
||||
}
|
||||
# else /* !G_ATOMIC_ARM */
|
||||
# elif defined (G_ATOMIC_CRIS) || defined (G_ATOMIC_CRISV32)
|
||||
# ifdef G_ATOMIC_CRIS
|
||||
# define CRIS_ATOMIC_INT_CMP_XCHG(atomic, oldval, newval) \
|
||||
({ \
|
||||
gboolean __result; \
|
||||
__asm__ __volatile__ ("\n" \
|
||||
"0:\tclearf\n\t" \
|
||||
"cmp.d [%[Atomic]], %[OldVal]\n\t" \
|
||||
"bne 1f\n\t" \
|
||||
"ax\n\t" \
|
||||
"move.d %[NewVal], [%[Atomic]]\n\t" \
|
||||
"bwf 0b\n" \
|
||||
"1:\tseq %[Result]" \
|
||||
: [Result] "=&r" (__result), \
|
||||
"=m" (*(atomic)) \
|
||||
: [Atomic] "r" (atomic), \
|
||||
[OldVal] "r" (oldval), \
|
||||
[NewVal] "r" (newval), \
|
||||
"g" (*(gpointer*) (atomic)) \
|
||||
: "memory"); \
|
||||
__result; \
|
||||
})
|
||||
# else
|
||||
# define CRIS_ATOMIC_INT_CMP_XCHG(atomic, oldval, newval) \
|
||||
({ \
|
||||
gboolean __result; \
|
||||
__asm__ __volatile__ ("\n" \
|
||||
"0:\tclearf p\n\t" \
|
||||
"cmp.d [%[Atomic]], %[OldVal]\n\t" \
|
||||
"bne 1f\n\t" \
|
||||
"ax\n\t" \
|
||||
"move.d %[NewVal], [%[Atomic]]\n\t" \
|
||||
"bcs 0b\n" \
|
||||
"1:\tseq %[Result]" \
|
||||
: [Result] "=&r" (__result), \
|
||||
"=m" (*(atomic)) \
|
||||
: [Atomic] "r" (atomic), \
|
||||
[OldVal] "r" (oldval), \
|
||||
[NewVal] "r" (newval), \
|
||||
"g" (*(gpointer*) (atomic)) \
|
||||
: "memory"); \
|
||||
__result; \
|
||||
})
|
||||
# endif
|
||||
|
||||
#define CRIS_CACHELINE_SIZE 32
|
||||
#define CRIS_ATOMIC_BREAKS_CACHELINE(atomic) \
|
||||
(((gulong)(atomic) & (CRIS_CACHELINE_SIZE - 1)) > (CRIS_CACHELINE_SIZE - sizeof (atomic)))
|
||||
|
||||
gint __g_atomic_int_exchange_and_add (volatile gint *atomic,
|
||||
gint val);
|
||||
void __g_atomic_int_add (volatile gint *atomic,
|
||||
gint val);
|
||||
gboolean __g_atomic_int_compare_and_exchange (volatile gint *atomic,
|
||||
gint oldval,
|
||||
gint newval);
|
||||
gboolean __g_atomic_pointer_compare_and_exchange (volatile gpointer *atomic,
|
||||
gpointer oldval,
|
||||
gpointer newval);
|
||||
|
||||
gboolean
|
||||
g_atomic_pointer_compare_and_exchange (volatile gpointer *atomic,
|
||||
gpointer oldval,
|
||||
gpointer newval)
|
||||
{
|
||||
if (G_UNLIKELY (CRIS_ATOMIC_BREAKS_CACHELINE (atomic)))
|
||||
return __g_atomic_pointer_compare_and_exchange (atomic, oldval, newval);
|
||||
|
||||
return CRIS_ATOMIC_INT_CMP_XCHG (atomic, oldval, newval);
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_atomic_int_compare_and_exchange (volatile gint *atomic,
|
||||
gint oldval,
|
||||
gint newval)
|
||||
{
|
||||
if (G_UNLIKELY (CRIS_ATOMIC_BREAKS_CACHELINE (atomic)))
|
||||
return __g_atomic_int_compare_and_exchange (atomic, oldval, newval);
|
||||
|
||||
return CRIS_ATOMIC_INT_CMP_XCHG (atomic, oldval, newval);
|
||||
}
|
||||
|
||||
gint
|
||||
g_atomic_int_exchange_and_add (volatile gint *atomic,
|
||||
gint val)
|
||||
{
|
||||
gint result;
|
||||
|
||||
if (G_UNLIKELY (CRIS_ATOMIC_BREAKS_CACHELINE (atomic)))
|
||||
return __g_atomic_int_exchange_and_add (atomic, val);
|
||||
|
||||
do
|
||||
result = *atomic;
|
||||
while (!CRIS_ATOMIC_INT_CMP_XCHG (atomic, result, result + val));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
g_atomic_int_add (volatile gint *atomic,
|
||||
gint val)
|
||||
{
|
||||
gint result;
|
||||
|
||||
if (G_UNLIKELY (CRIS_ATOMIC_BREAKS_CACHELINE (atomic)))
|
||||
return __g_atomic_int_add (atomic, val);
|
||||
|
||||
do
|
||||
result = *atomic;
|
||||
while (!CRIS_ATOMIC_INT_CMP_XCHG (atomic, result, result + val));
|
||||
}
|
||||
|
||||
/* We need the atomic mutex for atomic operations where the atomic variable
|
||||
* breaks the 32 byte cache line since the CRIS architecture does not support
|
||||
* atomic operations on such variables. Fortunately this should be rare.
|
||||
*/
|
||||
# define DEFINE_WITH_MUTEXES
|
||||
# endif /* G_ATOMIC_IA64 */
|
||||
# define g_atomic_int_exchange_and_add __g_atomic_int_exchange_and_add
|
||||
# define g_atomic_int_add __g_atomic_int_add
|
||||
# define g_atomic_int_compare_and_exchange __g_atomic_int_compare_and_exchange
|
||||
# define g_atomic_pointer_compare_and_exchange __g_atomic_pointer_compare_and_exchange
|
||||
|
||||
# else /* !G_ATOMIC_* */
|
||||
# define DEFINE_WITH_MUTEXES
|
||||
# endif /* G_ATOMIC_* */
|
||||
#else /* !__GNUC__ */
|
||||
# ifdef G_PLATFORM_WIN32
|
||||
# define DEFINE_WITH_WIN32_INTERLOCKED
|
||||
|
Loading…
x
Reference in New Issue
Block a user