mirror of
https://github.com/clearlinux/graphene.git
synced 2026-08-26 01:15:49 +00:00
7f19f62f31
Plenty of bugfixes for Linux kernel later than 3.5 and Ubuntu later than 10.10. More organized code to improve portability. Regression tests for Pal to test completeness of implementation.
111 lines
2.7 KiB
C
111 lines
2.7 KiB
C
/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
|
|
/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
|
|
|
|
#ifndef _SHIM_ATOMIC_H_
|
|
#define _SHIM_ATOMIC_H_
|
|
|
|
#define LOCK_PREFIX "\n\tlock; "
|
|
|
|
#define ATOMIC_INIT(i) { (i) }
|
|
|
|
static inline volatile int atomic_read (const struct atomic_int * v)
|
|
{
|
|
return v->counter;
|
|
}
|
|
|
|
static inline void atomic_set (struct atomic_int * v, int i)
|
|
{
|
|
v->counter = i;
|
|
}
|
|
|
|
static inline void atomic_add (int i, struct atomic_int * v)
|
|
{
|
|
asm volatile(LOCK_PREFIX "addl %1,%0"
|
|
: "+m" (v->counter)
|
|
: "ir" (i));
|
|
}
|
|
|
|
static inline void atomic_sub (int i, struct atomic_int * v)
|
|
{
|
|
asm volatile(LOCK_PREFIX "subl %1,%0"
|
|
: "+m" (v->counter)
|
|
: "ir" (i));
|
|
}
|
|
|
|
static inline int atomic_sub_and_test (int i, struct atomic_int * v)
|
|
{
|
|
unsigned char c;
|
|
asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
|
|
: "+m" (v->counter), "=qm" (c)
|
|
: "ir" (i) : "memory");
|
|
return c;
|
|
}
|
|
|
|
/* Return 0 if the value drops below zero, 1 if >= 0 */
|
|
static inline int atomic_sub_and_test_nonnegative (int i, struct atomic_int * v)
|
|
{
|
|
unsigned char c;
|
|
asm volatile(LOCK_PREFIX "subl %2,%0; setns %1"
|
|
: "+m" (v->counter), "=qm" (c)
|
|
: "ir" (i) : "memory");
|
|
return c;
|
|
}
|
|
|
|
static inline void atomic_inc (struct atomic_int * v)
|
|
{
|
|
asm volatile(LOCK_PREFIX "incl %0"
|
|
: "+m" (v->counter));
|
|
}
|
|
|
|
static inline int atomic_inc_and_test (struct atomic_int * v)
|
|
{
|
|
unsigned char c;
|
|
asm volatile(LOCK_PREFIX "incl %0; sete %1"
|
|
: "+m" (v->counter), "=qm" (c)
|
|
: : "memory");
|
|
return c != 0;
|
|
}
|
|
|
|
static inline void atomic_dec (struct atomic_int * v)
|
|
{
|
|
asm volatile(LOCK_PREFIX "decl %0"
|
|
: "+m" (v->counter));
|
|
}
|
|
|
|
static inline int atomic_dec_and_test (struct atomic_int * v)
|
|
{
|
|
unsigned char c;
|
|
asm volatile(LOCK_PREFIX "decl %0; sete %1"
|
|
: "+m" (v->counter), "=qm" (c)
|
|
: : "memory");
|
|
return c != 0;
|
|
}
|
|
|
|
/* Return 0 if the value drops below zero, 1 if >= 0 */
|
|
static inline int atomic_dec_and_test_nonnegative (struct atomic_int * v)
|
|
{
|
|
unsigned char c;
|
|
asm volatile(LOCK_PREFIX "decl %0; setns %1"
|
|
: "+m" (v->counter), "=qm" (c)
|
|
: : "memory");
|
|
return c;
|
|
}
|
|
|
|
#ifndef __i386__
|
|
# include "cmpxchg_64.h"
|
|
#else
|
|
# include "cmpxchg_32.h"
|
|
#endif
|
|
|
|
static inline int atomic_cmpxchg (struct atomic_int * v, int old, int new)
|
|
{
|
|
return cmpxchg((&v->counter), old, new);
|
|
}
|
|
|
|
static inline int atomic_xchg (struct atomic_int * v, int new)
|
|
{
|
|
return xchg((&v->counter), new);
|
|
}
|
|
|
|
#endif /* _ATOMIC_INT_H_ */
|