ovs-atomic: New library for atomic operations.
[sliver-openvswitch.git] / lib / ovs-atomic-gcc4+.c
1 /*
2  * Copyright (c) 2013 Nicira, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <config.h>
18
19 #include "ovs-atomic.h"
20 #include "ovs-thread.h"
21
22 #if OVS_ATOMIC_GCC4P_IMPL
23 static pthread_mutex_t mutex = PTHREAD_ADAPTIVE_MUTEX_INITIALIZER;
24
25 #define DEFINE_LOCKED_OP(TYPE, NAME, OPERATOR)                          \
26     TYPE##_t                                                            \
27     locked_##TYPE##_##NAME(struct locked_##TYPE *u, TYPE##_t arg)       \
28     {                                                                   \
29         TYPE##_t old_value;                                             \
30                                                                         \
31         xpthread_mutex_lock(&mutex);                                    \
32         old_value = u->value;                                           \
33         u->value OPERATOR arg;                                          \
34         xpthread_mutex_unlock(&mutex);                                  \
35                                                                         \
36         return old_value;                                               \
37     }
38
39 #define DEFINE_LOCKED_TYPE(TYPE)                                        \
40     TYPE##_t                                                            \
41     locked_##TYPE##_load(const struct locked_##TYPE *u)                 \
42     {                                                                   \
43         TYPE##_t value;                                                 \
44                                                                         \
45         xpthread_mutex_lock(&mutex);                                    \
46         value = u->value;                                               \
47         xpthread_mutex_unlock(&mutex);                                  \
48                                                                         \
49         return value;                                                   \
50     }                                                                   \
51                                                                         \
52     void                                                                \
53     locked_##TYPE##_store(struct locked_##TYPE *u, TYPE##_t value)      \
54     {                                                                   \
55         xpthread_mutex_lock(&mutex);                                    \
56         u->value = value;                                               \
57         xpthread_mutex_unlock(&mutex);                                  \
58     }                                                                   \
59     DEFINE_LOCKED_OP(TYPE, add, +=);                                    \
60     DEFINE_LOCKED_OP(TYPE, sub, -=);                                    \
61     DEFINE_LOCKED_OP(TYPE, or,  |=);                                    \
62     DEFINE_LOCKED_OP(TYPE, xor, ^=);                                    \
63     DEFINE_LOCKED_OP(TYPE, and, &=)
64
65 DEFINE_LOCKED_TYPE(uint64);
66 DEFINE_LOCKED_TYPE(int64);
67
68 #endif  /* OVS_ATOMIC_GCC4P_IMPL */