diff mbox

[v3,8/8] asm-x86/atomic.h: implement missing, add common prototypes

Message ID 1468487697-12705-1-git-send-email-czuzu@bitdefender.com (mailing list archive)
State New, archived
Headers show

Commit Message

Corneliu ZUZU July 14, 2016, 9:14 a.m. UTC
- implement missing functions atomic_{sub,inc,dec}_return(), atomic_add_unless()
  on X86 and also add prototypes for them in common <xen/atomic.h>

- add missing macro atomic_xchg for X86

Signed-off-by: Corneliu ZUZU <czuzu@bitdefender.com>
---
 xen/include/asm-x86/atomic.h | 27 +++++++++++++++++++++++++++
 xen/include/xen/atomic.h     | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

Comments

Andrew Cooper July 14, 2016, 9:29 a.m. UTC | #1
On 14/07/16 10:14, Corneliu ZUZU wrote:
> - implement missing functions atomic_{sub,inc,dec}_return(), atomic_add_unless()
>   on X86 and also add prototypes for them in common <xen/atomic.h>
>
> - add missing macro atomic_xchg for X86
>
> Signed-off-by: Corneliu ZUZU <czuzu@bitdefender.com>

Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Corneliu ZUZU July 14, 2016, 9:39 a.m. UTC | #2
On 7/14/2016 12:29 PM, Andrew Cooper wrote:
> On 14/07/16 10:14, Corneliu ZUZU wrote:
>> - implement missing functions atomic_{sub,inc,dec}_return(), atomic_add_unless()
>>    on X86 and also add prototypes for them in common <xen/atomic.h>
>>
>> - add missing macro atomic_xchg for X86
>>
>> Signed-off-by: Corneliu ZUZU<czuzu@bitdefender.com>
>
> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>

I'm not sure about atomic_sub_return(int i, atomic_t *v) implementation 
- is it ok? (calling arch_fetch_and_add(&v->counter, -i) with 2nd 
argument negative).

Zuzu C.
Andrew Cooper July 14, 2016, 9:44 a.m. UTC | #3
On 14/07/16 10:39, Corneliu ZUZU wrote:
> On 7/14/2016 12:29 PM, Andrew Cooper wrote:
>> On 14/07/16 10:14, Corneliu ZUZU wrote:
>>> - implement missing functions atomic_{sub,inc,dec}_return(), atomic_add_unless()
>>>   on X86 and also add prototypes for them in common <xen/atomic.h>
>>>
>>> - add missing macro atomic_xchg for X86
>>>
>>> Signed-off-by: Corneliu ZUZU <czuzu@bitdefender.com>
>>
>> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
>
> I'm not sure about atomic_sub_return(int i, atomic_t *v)
> implementation - is it ok? (calling arch_fetch_and_add(&v->counter,
> -i) with 2nd argument negative).

Looks ok to me.  Everything is signed integers in the internals.

There is a boundary condition when passing INT_MIN, but those exist
elsewhere as well.

~Andrew
Corneliu ZUZU July 14, 2016, 9:48 a.m. UTC | #4
On 7/14/2016 12:44 PM, Andrew Cooper wrote:
> On 14/07/16 10:39, Corneliu ZUZU wrote:
>> On 7/14/2016 12:29 PM, Andrew Cooper wrote:
>>> On 14/07/16 10:14, Corneliu ZUZU wrote:
>>>> - implement missing functions atomic_{sub,inc,dec}_return(), atomic_add_unless()
>>>>    on X86 and also add prototypes for them in common <xen/atomic.h>
>>>>
>>>> - add missing macro atomic_xchg for X86
>>>>
>>>> Signed-off-by: Corneliu ZUZU<czuzu@bitdefender.com>
>>>
>>> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
>>
>> I'm not sure about atomic_sub_return(int i, atomic_t *v) 
>> implementation - is it ok? (calling arch_fetch_and_add(&v->counter, 
>> -i) with 2nd argument negative).
>
> Looks ok to me.  Everything is signed integers in the internals.
>
> There is a boundary condition when passing INT_MIN, but those exist 
> elsewhere as well.
>
> ~Andrew

Thanks, thought so too - there should be no difference bit-wise when 
adding an unsigned int converted from an int vs adding the int directly.

Zuzu C.
diff mbox

Patch

diff --git a/xen/include/asm-x86/atomic.h b/xen/include/asm-x86/atomic.h
index 1729e29..101eded 100644
--- a/xen/include/asm-x86/atomic.h
+++ b/xen/include/asm-x86/atomic.h
@@ -126,6 +126,11 @@  static inline void atomic_sub(int i, atomic_t *v)
         : "ir" (i), "m" (*(volatile int *)&v->counter) );
 }
 
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+    return arch_fetch_and_add(&v->counter, -i) - i;
+}
+
 static inline int atomic_sub_and_test(int i, atomic_t *v)
 {
     unsigned char c;
@@ -145,6 +150,11 @@  static inline void atomic_inc(atomic_t *v)
         : "m" (*(volatile int *)&v->counter) );
 }
 
+static inline int atomic_inc_return(atomic_t *v)
+{
+    return atomic_add_return(1, v);
+}
+
 static inline int atomic_inc_and_test(atomic_t *v)
 {
     unsigned char c;
@@ -164,6 +174,11 @@  static inline void atomic_dec(atomic_t *v)
         : "m" (*(volatile int *)&v->counter) );
 }
 
+static inline int atomic_dec_return(atomic_t *v)
+{
+    return atomic_sub_return(1, v);
+}
+
 static inline int atomic_dec_and_test(atomic_t *v)
 {
     unsigned char c;
@@ -186,4 +201,16 @@  static inline int atomic_add_negative(int i, atomic_t *v)
     return c;
 }
 
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+    int c, old;
+
+    c = atomic_read(v);
+    while (c != u && (old = atomic_cmpxchg(v, c, c + a)) != c)
+        c = old;
+    return c;
+}
+
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
 #endif /* __ARCH_X86_ATOMIC__ */
diff --git a/xen/include/xen/atomic.h b/xen/include/xen/atomic.h
index 6827468..529213e 100644
--- a/xen/include/xen/atomic.h
+++ b/xen/include/xen/atomic.h
@@ -111,6 +111,15 @@  static inline int atomic_add_return(int i, atomic_t *v);
 static inline void atomic_sub(int i, atomic_t *v);
 
 /**
+ * atomic_sub_return - sub integer and return
+ * @i: integer value to sub
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v and returns @v - @i.
+ */
+static inline int atomic_sub_return(int i, atomic_t *v);
+
+/**
  * atomic_sub_and_test - subtract value from variable and test result
  * @i: integer value to subtract
  * @v: pointer of type atomic_t
@@ -130,6 +139,14 @@  static inline int atomic_sub_and_test(int i, atomic_t *v);
 static inline void atomic_inc(atomic_t *v);
 
 /**
+ * atomic_inc_return - increment atomic variable and return
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1 and returns @v + 1.
+ */
+static inline int atomic_inc_return(atomic_t *v);
+
+/**
  * atomic_inc_and_test - increment and test
  * @v: pointer of type atomic_t
  *
@@ -148,6 +165,14 @@  static inline int atomic_inc_and_test(atomic_t *v);
 static inline void atomic_dec(atomic_t *v);
 
 /**
+ * atomic_dec_return - decrement atomic variable and return
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1 and returns @v - 1.
+ */
+static inline int atomic_dec_return(atomic_t *v);
+
+/**
  * atomic_dec_and_test - decrement and test
  * @v: pointer of type atomic_t
  *
@@ -168,4 +193,15 @@  static inline int atomic_dec_and_test(atomic_t *v);
  */
 static inline int atomic_add_negative(int i, atomic_t *v);
 
+/**
+ * atomic_add_unless - add to atomic variable unless it has a specified value
+ * @v: pointer of type atomic_t
+ * @a: integer value to add
+ * @u: integer value @v must -not- be for the add to be performed
+ *
+ * If @v != @u, adds @a to @v and returns @v + @a.
+ * Otherwise returns @u (== @v).
+ */
+static inline int atomic_add_unless(atomic_t *v, int a, int u);
+
 #endif /* __XEN_ATOMIC_H__ */