fb11e647
vrobic
reseau statique a...
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
/*
* Copyright (C) 2014 Freie Universität Berlin
* Copyright (C) 2015 Eistec AB
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @addtogroup core_util
* @{
*
* @file
* @brief Functions for atomic handling of variables
*
* @author Kaspar Schleiser <kaspar@schleiser.de>
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
*/
#ifndef ATOMIC_H_
#define ATOMIC_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Integer variable for use in atomic counters.
*
* @note This type is a struct for hard type checking (let the compiler warn
* if int is assigned regularly).
*/
typedef struct {
volatile int value; /**< the actual value */
} atomic_int_t;
/**
* @brief Initializer for atomic variables
*
* @param[in] val initial value for the atomic integer
*/
#define ATOMIC_INIT(val) {(val)}
/**
* @brief Atomic Compare and Swap
*
* Updates the value in var iff the current value of var is equal to old.
*
* @param[inout] var Atomic variable to update
* @param[in] old The old value to compare against
* @param[in] now The new value to write to var
*
* @return 1 if the write completed successfully
* @return 0 if the write failed.
*/
int atomic_cas(atomic_int_t *var, int old, int now);
/**
* @brief Increment a counter variable by one atomically and return the old value.
*
* @param[inout] var Pointer to a counter variable.
*
* @return The value of *val* before the increment.
*/
static inline int atomic_inc(atomic_int_t *var)
{
int old;
do {
old = var->value;
} while (!atomic_cas(var, old, old + 1));
return old;
}
/**
* @brief Decrement a counter variable by one atomically and return the old value.
*
* @param[inout] var Pointer to a counter variable.
*
* @return The value of *val* before the decrement.
*/
static inline int atomic_dec(atomic_int_t *var)
{
int old;
do {
old = var->value;
} while (!atomic_cas(var, old, old - 1));
return old;
}
/**
* @brief Set an atomic variable to 1.
*
* @param[inout] var Pointer to an atomic variable to update
*
* @return 1 if the old value was 0 and the variable was successfully updated
* @return 0 if the variable was already set
*/
static inline int atomic_set_to_one(atomic_int_t *var)
{
do {
if (var->value != 0) {
return 0;
}
} while (!atomic_cas(var, 0, 1));
return 1;
}
/**
* @brief Set an atomic variable to 0.
*
* @param[inout] var Pointer to an atomic variable to update
*
* @return 1 if the old value was not 0 and the variable was successfully updated
* @return 0 if the variable was already cleared
*/
static inline int atomic_set_to_zero(atomic_int_t *var)
{
int old;
do {
old = var->value;
if (old == 0) {
return 0;
}
} while (!atomic_cas(var, old, 0));
return 1;
}
/**
* @brief Get the value of an atomic int
*
* @param[in] var Atomic variable
*
* @return the value of the atomic integer
*
* @note This can be used for non-thread-safe assignment of the atomic integer
*/
#define ATOMIC_VALUE(var) ((var).value)
#ifdef __cplusplus
}
#endif
#endif /* ATOMIC_H_ */
/** @} */
|