Motr  M0
user_x86_64_atomic.h
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2012-2021 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #pragma once
24 
25 #ifndef __MOTR_LIB_USER_X86_64_ATOMIC_H__
26 #define __MOTR_LIB_USER_X86_64_ATOMIC_H__
27 
28 #include "lib/types.h"
29 #include "lib/assert.h"
30 
40 struct m0_atomic64 {
41  long a_value;
42 };
43 
44 static inline void m0_atomic64_set(struct m0_atomic64 *a, int64_t num)
45 {
46  M0_CASSERT(sizeof a->a_value == sizeof num);
47 
48  a->a_value = num;
49 }
50 
54 static inline int64_t m0_atomic64_get(const struct m0_atomic64 *a)
55 {
56  return a->a_value;
57 }
58 
66 static inline void m0_atomic64_inc(struct m0_atomic64 *a)
67 {
68  asm volatile("lock incq %0"
69  : "=m" (a->a_value)
70  : "m" (a->a_value));
71 }
72 
80 static inline void m0_atomic64_dec(struct m0_atomic64 *a)
81 {
82  asm volatile("lock decq %0"
83  : "=m" (a->a_value)
84  : "m" (a->a_value));
85 }
86 
90 static inline void m0_atomic64_add(struct m0_atomic64 *a, int64_t num)
91 {
92  asm volatile("lock addq %1,%0"
93  : "=m" (a->a_value)
94  : "er" (num), "m" (a->a_value));
95 }
96 
100 static inline void m0_atomic64_sub(struct m0_atomic64 *a, int64_t num)
101 {
102  asm volatile("lock subq %1,%0"
103  : "=m" (a->a_value)
104  : "er" (num), "m" (a->a_value));
105 }
106 
107 
115 static inline int64_t m0_atomic64_add_return(struct m0_atomic64 *a,
116  int64_t delta)
117 {
118  long result;
119 
120  result = delta;
121  asm volatile("lock xaddq %0, %1;"
122  : "+r" (delta), "+m" (a->a_value)
123  : : "memory");
124  return delta + result;
125 }
126 
134 static inline int64_t m0_atomic64_sub_return(struct m0_atomic64 *a,
135  int64_t delta)
136 {
137  return m0_atomic64_add_return(a, -delta);
138 }
139 
140 static inline bool m0_atomic64_inc_and_test(struct m0_atomic64 *a)
141 {
142  unsigned char result;
143 
144  asm volatile("lock incq %0; sete %1"
145  : "=m" (a->a_value), "=qm" (result)
146  : "m" (a->a_value) : "memory");
147  return result != 0;
148 }
149 
150 static inline bool m0_atomic64_dec_and_test(struct m0_atomic64 *a)
151 {
152  unsigned char result;
153 
154  asm volatile("lock decq %0; sete %1"
155  : "=m" (a->a_value), "=qm" (result)
156  : "m" (a->a_value) : "memory");
157  return result != 0;
158 }
159 
160 static inline bool m0_atomic64_cas(int64_t * loc, int64_t oldval, int64_t newval)
161 {
162  int64_t val;
163 
164  M0_CASSERT(8 == sizeof oldval);
165 
166  asm volatile("lock cmpxchgq %2,%1"
167  : "=a" (val), "+m" (*(volatile long *)(loc))
168  : "r" (newval), "0" (oldval)
169  : "memory");
170  return val == oldval;
171 }
172 
173 static inline void m0_mb(void)
174 {
175  asm volatile("mfence":::"memory");
176 }
177 
179 #endif /* __MOTR_LIB_USER_X86_64_ATOMIC_H__ */
180 
181 /*
182  * Local variables:
183  * c-indentation-style: "K&R"
184  * c-basic-offset: 8
185  * tab-width: 8
186  * fill-column: 80
187  * scroll-step: 1
188  * End:
189  */
static void m0_atomic64_dec(struct m0_atomic64 *a)
static bool m0_atomic64_cas(int64_t *loc, int64_t oldval, int64_t newval)
static bool m0_atomic64_dec_and_test(struct m0_atomic64 *a)
Definition: idx_mock.c:52
#define M0_CASSERT(cond)
static void m0_atomic64_set(struct m0_atomic64 *a, int64_t num)
static bool m0_atomic64_inc_and_test(struct m0_atomic64 *a)
static void m0_atomic64_sub(struct m0_atomic64 *a, int64_t num)
static void m0_atomic64_inc(struct m0_atomic64 *a)
static void m0_mb(void)
static int64_t m0_atomic64_get(const struct m0_atomic64 *a)
static int64_t m0_atomic64_add_return(struct m0_atomic64 *a, int64_t delta)
static int64_t m0_atomic64_sub_return(struct m0_atomic64 *a, int64_t delta)
static void m0_atomic64_add(struct m0_atomic64 *a, int64_t num)
atomic64_t a_value
Definition: atomic64.h:38
int num
Definition: bulk_if.c:54