Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Jens Gustedt
P99 - macros and functions for C99
Commits
78e653f8
Commit
78e653f8
authored
Dec 03, 2012
by
Jens Gustedt
Browse files
rename all "fetch_and_store" to "exchange"
I must have been in some dreams somewhere
parent
4717efe4
Changes
9
Hide whitespace changes
Inline
Side-by-side
p99/p99_atomic.h
View file @
78e653f8
...
...
@@ -700,16 +700,16 @@ P00_DOCUMENT_TYPE_ARGUMENT(P99_ATOMIC_INHERIT, 0)
P00_ATOMIC_TYPES))
p99_inline
uintptr_t
p00_
fet
ch
_
an
d_stor
e_ignore
(
void
*
x
,
...)
{
return
0
;
}
#define P00_
FET
CH
_
AN
D_STOR
E(X) \
P99_GENERIC_SIZE
\
(sizeof(X),
\
p00_
fet
ch
_
an
d_stor
e_ignore, \
(1, p00_atomic_
fet
ch
_
an
d_stor
e_1), \
(2, p00_atomic_
fet
ch
_
an
d_stor
e_2), \
(4, p00_atomic_
fet
ch
_
an
d_stor
e_4) \
P99_IF_EQ_2(ATOMIC_INT64_LOCK_FREE)(,(8, p00_atomic_
fet
ch
_
an
d_stor
e_8))() \
uintptr_t
p00_
ex
chan
g
e_ignore
(
void
*
x
,
...)
{
return
0
;
}
#define P00_
EX
CHAN
G
E(X) \
P99_GENERIC_SIZE \
(sizeof(X), \
p00_
ex
chan
g
e_ignore, \
(1, p00_atomic_
ex
chan
g
e_1), \
(2, p00_atomic_
ex
chan
g
e_2), \
(4, p00_atomic_
ex
chan
g
e_4) \
P99_IF_EQ_2(ATOMIC_INT64_LOCK_FREE)(,(8, p00_atomic_
ex
chan
g
e_8))() \
)
/**
...
...
@@ -1073,9 +1073,9 @@ p99_extension \
**
** @see atomic_int
**/
#define atomic_
fet
ch
_
an
d_stor
e(OBJP, DESIRED)
#define atomic_
ex
chan
g
e(OBJP, DESIRED)
#else
#define atomic_
fet
ch
_
an
d_stor
e(OBJP, DESIRED) \
#define atomic_
ex
chan
g
e(OBJP, DESIRED)
\
p99_extension \
({ \
P99_MACRO_PVAR(p00_objp, (OBJP)); \
...
...
@@ -1095,7 +1095,7 @@ p99_extension
case 2:; \
case 4:; \
case 8:; \
p00_ret.p00_m = P00_
FET
CH
_
AN
D_STOR
E(P00_AT(p00_objp))(&P00_AM(p00_objp), p00_desm.p00_m); \
p00_ret.p00_m = P00_
EX
CHAN
G
E(P00_AT(p00_objp))(&P00_AM(p00_objp), p00_desm.p00_m);
\
break; \
default: \
p00_ret.p00_m = P00_AM(p00_objp); \
...
...
@@ -1207,7 +1207,7 @@ p99_extension
**/
#define atomic_store(OBJP, DES)
#else
#define atomic_store(OBJP, DES) ((void)atomic_
fet
ch
_
an
d_stor
e(OBJP, DES))
#define atomic_store(OBJP, DES) ((void)atomic_
ex
chan
g
e(OBJP, DES))
#endif
#define P00_FETCH_OP(OBJP, OPERAND, BUILTIN, OPERATOR) \
...
...
@@ -1397,7 +1397,7 @@ p99_extension \
({ \
P99_MACRO_VAR(p00_l, (L)); \
P99_MACRO_VAR(p00_el, (EL)); \
p00_el->p99_lifo = atomic_
fet
ch
_
an
d_stor
e(p00_l, p00_el); \
p00_el->p99_lifo = atomic_
ex
chan
g
e(p00_l, p00_el);
\
})
/**
...
...
@@ -1463,7 +1463,7 @@ p99_extension
** @see P99_LIFO_TOP
**/
P00_DOCUMENT_PERMITTED_ARGUMENT
(
P99_LIFO_CLEAR
,
0
)
#define P99_LIFO_CLEAR(L) atomic_
fet
ch
_
an
d_stor
e(L, 0)
#define P99_LIFO_CLEAR(L) atomic_
ex
chan
g
e(L, 0)
P00_DOCUMENT_TYPE_ARGUMENT
(
P99_LIFO_TABULATE
,
0
)
P00_DOCUMENT_IDENTIFIER_ARGUMENT
(
P99_LIFO_TABULATE
,
1
)
...
...
p99/p99_atomic_arm.h
View file @
78e653f8
...
...
@@ -199,7 +199,7 @@ _Bool p00_arm_strexd(uint64_t volatile*p00_ptr, uint64_t p00_val) {
#endif
p99_inline
uint8_t
p00_atomic_
fet
ch
_
an
d_stor
e_1
(
uint8_t
volatile
*
p00_objp
,
uint8_t
p00_des
)
{
uint8_t
p00_atomic_
ex
chan
g
e_1
(
uint8_t
volatile
*
p00_objp
,
uint8_t
p00_des
)
{
for
(;;)
{
uint8_t
p00_ret
=
p00_arm_ldrexb
(
object
);
if
(
!
p00_arm_strexb
(
object
,
p00_des
))
return
p00_ret
;
...
...
@@ -207,7 +207,7 @@ uint8_t p00_atomic_fetch_and_store_1(uint8_t volatile* p00_objp, uint8_t p00_des
}
p99_inline
uint16_t
p00_atomic_
fet
ch
_
an
d_stor
e_2
(
uint16_t
volatile
*
p00_objp
,
uint16_t
p00_des
)
{
uint16_t
p00_atomic_
ex
chan
g
e_2
(
uint16_t
volatile
*
p00_objp
,
uint16_t
p00_des
)
{
for
(;;)
{
uint16_t
p00_ret
=
p00_arm_ldrexh
(
object
);
if
(
!
p00_arm_strexh
(
object
,
p00_des
))
return
p00_ret
;
...
...
@@ -215,7 +215,7 @@ uint16_t p00_atomic_fetch_and_store_2(uint16_t volatile* p00_objp, uint16_t p00_
}
p99_inline
uint32_t
p00_atomic_
fet
ch
_
an
d_stor
e_4
(
uint32_t
volatile
*
p00_objp
,
uint32_t
p00_des
)
{
uint32_t
p00_atomic_
ex
chan
g
e_4
(
uint32_t
volatile
*
p00_objp
,
uint32_t
p00_des
)
{
for
(;;)
{
uint32_t
p00_ret
=
p00_arm_ldrex
(
object
);
if
(
!
p00_arm_strex
(
object
,
p00_des
))
return
p00_ret
;
...
...
@@ -224,7 +224,7 @@ uint32_t p00_atomic_fetch_and_store_4(uint32_t volatile* p00_objp, uint32_t p00_
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) || defined(P00_DOXYGEN)
p99_inline
uint64_t
p00_atomic_
fet
ch
_
an
d_stor
e_8
(
uint64_t
volatile
*
p00_objp
,
uint64_t
p00_des
)
{
uint64_t
p00_atomic_
ex
chan
g
e_8
(
uint64_t
volatile
*
p00_objp
,
uint64_t
p00_des
)
{
for
(;;)
{
uint64_t
p00_ret
=
p00_arm_ldrexd
(
object
);
if
(
!
p00_arm_strexd
(
object
,
p00_des
))
return
p00_ret
;
...
...
p99/p99_atomic_gcc.h
View file @
78e653f8
...
...
@@ -25,23 +25,23 @@
**/
#define P00_ATOMIC_
FET
CH
_
AN
D_STOR
E_DECLARE(T, N) \
p99_inline
\
T P99_PASTE(p00_atomic_
fet
ch
_
an
d_stor
e_, N)(T volatile * p00_p, T p00_des) { \
T p00_ret = *p00_p;
\
for (;;) {
\
T p00_val = __sync_val_compare_and_swap(p00_p, p00_ret, p00_des);
\
if (P99_LIKELY(p00_val == p00_ret)) break;
\
p00_ret = p00_val;
\
}
\
return p00_ret;
\
}
\
P99_MACRO_END(P00_ATOMIC_
FET
CH
_
AN
D_STOR
E_DECLARE)
P00_ATOMIC_
FET
CH
_
AN
D_STOR
E_DECLARE
(
uint8_t
,
1
);
P00_ATOMIC_
FET
CH
_
AN
D_STOR
E_DECLARE
(
uint16_t
,
2
);
P00_ATOMIC_
FET
CH
_
AN
D_STOR
E_DECLARE
(
uint32_t
,
4
);
P00_ATOMIC_
FET
CH
_
AN
D_STOR
E_DECLARE
(
uint64_t
,
8
);
#define P00_ATOMIC_
EX
CHAN
G
E_DECLARE(T, N) \
p99_inline \
T P99_PASTE(p00_atomic_
ex
chan
g
e_, N)(T volatile * p00_p, T p00_des) { \
T p00_ret = *p00_p; \
for (;;) { \
T p00_val = __sync_val_compare_and_swap(p00_p, p00_ret, p00_des); \
if (P99_LIKELY(p00_val == p00_ret)) break; \
p00_ret = p00_val; \
} \
return p00_ret; \
} \
P99_MACRO_END(P00_ATOMIC_
EX
CHAN
G
E_DECLARE)
P00_ATOMIC_
EX
CHAN
G
E_DECLARE
(
uint8_t
,
1
);
P00_ATOMIC_
EX
CHAN
G
E_DECLARE
(
uint16_t
,
2
);
P00_ATOMIC_
EX
CHAN
G
E_DECLARE
(
uint32_t
,
4
);
P00_ATOMIC_
EX
CHAN
G
E_DECLARE
(
uint64_t
,
8
);
p99_inline
void
p00_mfence
(
void
)
{
__sync_synchronize
();
}
...
...
p99/p99_atomic_x86.h
View file @
78e653f8
...
...
@@ -20,7 +20,7 @@
p99_inline
uint8_t
p00_atomic_
fet
ch
_
an
d_stor
e_1
(
uint8_t
volatile
*
p00_objp
,
uint8_t
p00_ret
)
{
uint8_t
p00_atomic_
ex
chan
g
e_1
(
uint8_t
volatile
*
p00_objp
,
uint8_t
p00_ret
)
{
__asm__
__volatile__
(
"xchgb %1, %b0"
:
"=r"
(
p00_ret
)
:
"m"
(
*
p00_objp
),
"0"
(
p00_ret
)
...
...
@@ -29,7 +29,7 @@ uint8_t p00_atomic_fetch_and_store_1(uint8_t volatile* p00_objp, uint8_t p00_ret
}
p99_inline
uint16_t
p00_atomic_
fet
ch
_
an
d_stor
e_2
(
uint16_t
volatile
*
p00_objp
,
uint16_t
p00_ret
)
{
uint16_t
p00_atomic_
ex
chan
g
e_2
(
uint16_t
volatile
*
p00_objp
,
uint16_t
p00_ret
)
{
__asm__
__volatile__
(
"xchgw %1, %w0"
:
"=r"
(
p00_ret
)
:
"m"
(
*
p00_objp
),
"0"
(
p00_ret
)
...
...
@@ -38,7 +38,7 @@ uint16_t p00_atomic_fetch_and_store_2(uint16_t volatile* p00_objp, uint16_t p00_
}
p99_inline
uint32_t
p00_atomic_
fet
ch
_
an
d_stor
e_4
(
uint32_t
volatile
*
p00_objp
,
uint32_t
p00_ret
)
{
uint32_t
p00_atomic_
ex
chan
g
e_4
(
uint32_t
volatile
*
p00_objp
,
uint32_t
p00_ret
)
{
__asm__
__volatile__
(
"xchgl %1, %k0"
:
"=r"
(
p00_ret
)
:
"m"
(
*
p00_objp
),
"0"
(
p00_ret
)
...
...
@@ -48,7 +48,7 @@ uint32_t p00_atomic_fetch_and_store_4(uint32_t volatile* p00_objp, uint32_t p00_
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) || defined(P00_DOXYGEN)
p99_inline
uint64_t
p00_atomic_
fet
ch
_
an
d_stor
e_8
(
uint64_t
volatile
*
p00_objp
,
uint64_t
p00_ret
)
{
uint64_t
p00_atomic_
ex
chan
g
e_8
(
uint64_t
volatile
*
p00_objp
,
uint64_t
p00_ret
)
{
__asm__
__volatile__
(
"xchgq %1, %0"
:
"=r"
(
p00_ret
)
:
"m"
(
*
p00_objp
),
"0"
(
p00_ret
)
...
...
@@ -99,7 +99,7 @@ void p00_mfence(void) {
p99_inline
uint32_t
p00_sync_lock_test_and_set
(
uint32_t
volatile
*
p00_objp
)
{
register
uint32_t
p00_ret
=
1
;
return
p00_atomic_
fet
ch
_
an
d_stor
e_4
(
p00_objp
,
p00_ret
);
return
p00_atomic_
ex
chan
g
e_4
(
p00_objp
,
p00_ret
);
}
p99_inline
...
...
p99/p99_constraint.h
View file @
78e653f8
...
...
@@ -366,7 +366,7 @@ void abort_handler_s(const char * restrict p00_msg,
p99_inline
constraint_handler_t
set_constraint_handler_s
(
constraint_handler_t
handler
)
{
if
(
!
handler
)
handler
=
P99_CONSTRAINT_HANDLER
;
return
atomic_
fet
ch
_
an
d_stor
e
(
&
p00_constraint_handler
,
handler
);
return
atomic_
ex
chan
g
e
(
&
p00_constraint_handler
,
handler
);
}
# endif
...
...
p99/p99_futex.h
View file @
78e653f8
...
...
@@ -108,7 +108,7 @@ typedef p99_futex_c11 p99_futex;
** There are several operations that work on that value similar to
** their atomic analogues:
** - ::p99_futex_load returns the value
** - ::p99_futex_
fet
ch
_
an
d_stor
e atomically exchanges the value with
** - ::p99_futex_
ex
chan
g
e atomically exchanges the value with
** a new one and returns the old one
** - ::p99_futex_add atomically adds a quantity to the value
** - ::P99_FUTEX_COMPARE_EXCHANGE atomically compares the existing
...
...
@@ -128,10 +128,10 @@ typedef p99_futex_c11 p99_futex;
** (or scarcely) using resources. Such a waiting thread will only be
** awoken if another thread wants so. Either by calling an explicit
** ::p99_futex_wakeup, or implicitly by changing the value through
** ::p99_futex_
fet
ch
_
an
d_stor
e, ::p99_futex_add or
** ::p99_futex_
ex
chan
g
e, ::p99_futex_add or
** ::P99_FUTEX_COMPARE_EXCHANGE.
**
** :p99_futex_
fet
ch
_
an
d_stor
e and ::p99_futex_add wake up waiters if
** :p99_futex_
ex
chan
g
e and ::p99_futex_add wake up waiters if
** the value reaches a certain interval. Therefore they have
** additional arguments @c p00_cstart, @c p00_clen and @c p00_wmin @c
** p00_wmax that give two ranges. One of the conditional values and
...
...
@@ -249,16 +249,16 @@ P00_FUTEX_INLINE(p99_futex_load) unsigned p99_futex_load(p99_futex volatile* p00
** @remark @a p00_wmax defaults to ::P99_FUTEX_MAX_WAITERS
** @related p99_futex
**/
P99_DEFARG_DOCU
(
p99_futex_
fet
ch
_
an
d_stor
e
)
P00_FUTEX_INLINE
(
p99_futex_
fet
ch
_
an
d_stor
e
)
unsigned
p99_futex_
fet
ch
_
an
d_stor
e
(
p99_futex
volatile
*
p00_fut
,
unsigned
p00_desired
,
P99_DEFARG_DOCU
(
p99_futex_
ex
chan
g
e
)
P00_FUTEX_INLINE
(
p99_futex_
ex
chan
g
e
)
unsigned
p99_futex_
ex
chan
g
e
(
p99_futex
volatile
*
p00_fut
,
unsigned
p00_desired
,
unsigned
p00_cstart
,
unsigned
p00_clen
,
unsigned
p00_wmin
,
unsigned
p00_wmax
);
#ifndef DOXYGEN
#define p99_futex_
fet
ch
_
an
d_stor
e(...) P99_CALL_DEFARG(p99_futex_
fet
ch
_
an
d_stor
e, 6, __VA_ARGS__)
#define p99_futex_
fet
ch
_
an
d_stor
e_defarg_3() 1u
#define p99_futex_
fet
ch
_
an
d_stor
e_defarg_4() 0u
#define p99_futex_
fet
ch
_
an
d_stor
e_defarg_5() P99_FUTEX_MAX_WAITERS
#define p99_futex_
ex
chan
g
e(...) P99_CALL_DEFARG(p99_futex_
ex
chan
g
e, 6, __VA_ARGS__)
#define p99_futex_
ex
chan
g
e_defarg_3() 1u
#define p99_futex_
ex
chan
g
e_defarg_4() 0u
#define p99_futex_
ex
chan
g
e_defarg_5() P99_FUTEX_MAX_WAITERS
#endif
/**
...
...
p99/p99_futex_c11.h
View file @
78e653f8
...
...
@@ -147,10 +147,10 @@ unsigned p99_futex_add(p99_futex volatile* p00_fut, unsigned p00_hmuch,
return
p00_ret
;
}
P99_WEAK
(
p99_futex_
fet
ch
_
an
d_stor
e
)
unsigned
p99_futex_
fet
ch
_
an
d_stor
e
(
p99_futex
volatile
*
p00_fut
,
unsigned
p00_desired
,
unsigned
p00_cstart
,
unsigned
p00_clen
,
unsigned
p00_wmin
,
unsigned
p00_wmax
)
{
P99_WEAK
(
p99_futex_
ex
chan
g
e
)
unsigned
p99_futex_
ex
chan
g
e
(
p99_futex
volatile
*
p00_fut
,
unsigned
p00_desired
,
unsigned
p00_cstart
,
unsigned
p00_clen
,
unsigned
p00_wmin
,
unsigned
p00_wmax
)
{
volatile
unsigned
p00_act
=
0
;
if
(
p00_wmax
<
p00_wmin
)
p00_wmax
=
p00_wmin
;
P99_MUTUAL_EXCLUDE
(
*
(
mtx_t
*
)
&
p00_fut
->
p99_mut
)
{
...
...
@@ -159,7 +159,7 @@ unsigned p99_futex_fetch_and_store(p99_futex volatile* p00_fut, unsigned p00_des
if
(
p00_clen
&&
P99_IN_RANGE
(
p00_desired
,
p00_cstart
,
p00_clen
))
{
P00_FUTEX_WAKEUP
(
p00_fut
,
p00_wmin
,
p00_wmax
);
}
else
{
p00_wmin
=
0
;
;
p00_wmin
=
0
;
}
}
/* If we haven't woken enough threads, we have to re-acquire the
...
...
p99/p99_futex_linux.h
View file @
78e653f8
...
...
@@ -269,10 +269,10 @@ unsigned p99_futex_add(p99_futex volatile* futex, unsigned p00_hmuch,
}
p99_inline
unsigned
p99_futex_
fet
ch
_
an
d_stor
e
(
p99_futex
volatile
*
futex
,
unsigned
p00_desired
,
unsigned
p00_cstart
,
unsigned
p00_clen
,
unsigned
p00_wmin
,
unsigned
p00_wmax
)
{
unsigned
p00_act
=
atomic_
fet
ch
_
an
d_stor
e
(
futex
,
p00_desired
);
unsigned
p99_futex_
ex
chan
g
e
(
p99_futex
volatile
*
futex
,
unsigned
p00_desired
,
unsigned
p00_cstart
,
unsigned
p00_clen
,
unsigned
p00_wmin
,
unsigned
p00_wmax
)
{
unsigned
p00_act
=
atomic_
ex
chan
g
e
(
futex
,
p00_desired
);
if
(
p00_clen
&&
P99_IN_RANGE
(
p00_desired
,
p00_cstart
,
p00_clen
))
p99_futex_wakeup
(
futex
,
p00_wmin
,
p00_wmax
);
return
p00_act
;
...
...
p99/p99_notifier.h
View file @
78e653f8
...
...
@@ -145,7 +145,7 @@ unsigned p99_notifier_load(p99_notifier volatile* p00_n) {
P99_DEFARG_DOCU
(
p99_notifier_set
)
p99_inline
void
p99_notifier_set
(
p99_notifier
volatile
*
p00_n
,
unsigned
p00_v
)
{
p99_futex_
fet
ch
_
an
d_stor
e
(
p00_n
,
p00_v
,
p00_v
,
1u
,
0u
,
P99_FUTEX_MAX_WAITERS
);
p99_futex_
ex
chan
g
e
(
p00_n
,
p00_v
,
p00_v
,
1u
,
0u
,
P99_FUTEX_MAX_WAITERS
);
}
#ifndef DOXYGEN
...
...
@@ -163,7 +163,7 @@ void p99_notifier_set(p99_notifier volatile* p00_n, unsigned p00_v) {
**/
p99_inline
void
p99_notifier_unset
(
p99_notifier
volatile
*
p00_n
)
{
p99_futex_
fet
ch
_
an
d_stor
e
(
p00_n
,
0u
,
1u
,
0u
,
0u
,
0u
);
p99_futex_
ex
chan
g
e
(
p00_n
,
0u
,
1u
,
0u
,
0u
,
0u
);
}
/**
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment