Commit c5aa0057 authored by Jens Gustedt's avatar Jens Gustedt
Browse files

arrays of atomic qualified types aren't allowed by gcc 4.9

I have the impression that they get it partially the wrong way arround, I
don't see anything in the standard that says that the base type of an
array type can't be atomic qualified
parent d461f8a8
......@@ -2,7 +2,7 @@
/* */
/* Except for parts copied from previous work and as explicitly stated below, */
/* the author and copyright holder for this work is */
/* (C) copyright 2012-2013 Jens Gustedt, INRIA, France */
/* (C) copyright 2012-2014 Jens Gustedt, INRIA, France */
/* */
/* This file is free software; it is part of the P99 project. */
/* You can redistribute it and/or modify it under the terms of the QPL as */
......@@ -29,13 +29,17 @@
#if defined(P99_DECLARE_ATOMIC) || P00_DOXYGEN
# define P99_FIFO(T) P99_PASTE2(p00_fifo_, T)
# define P99_FIFO_DECLARE(T) \
typedef T volatile P99_PASTE2(p00_fifo_base_, T); \
P99_DECLARE_ATOMIC(P99_PASTE2(p00_fifo_base_, T)); \
typedef _Atomic(P99_PASTE2(p00_fifo_base_, T)) P99_PASTE2(p00_fifo_, T)[2]
# define P99_FIFO_DECLARE(T) \
typedef T P99_PASTE2(p00_fifo_base_, T); \
P99_DECLARE_ATOMIC(P99_PASTE2(p00_fifo_base_, T)); \
struct P99_PASTE2(p00_fifo_, T) { \
_Atomic(P99_PASTE2(p00_fifo_base_, T)) p00_head; \
_Atomic(P99_PASTE2(p00_fifo_base_, T)) p00_tail; \
}; \
typedef struct P99_PASTE2(p00_fifo_, T) P99_PASTE2(p00_fifo_, T)
# define P99_FIFO_INITIALIZER(HEAD, TAIL) { \
[0] = ATOMIC_VAR_INIT(HEAD), \
[1] = ATOMIC_VAR_INIT(TAIL), \
.p00_head = ATOMIC_VAR_INIT(HEAD), \
.p00_tail = ATOMIC_VAR_INIT(TAIL), \
}
/**
......@@ -46,38 +50,38 @@ typedef _Atomic(P99_PASTE2(p00_fifo_base_, T)) P99_PASTE2(p00_fifo_, T)[2]
**/
P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FIFO_APPEND, 0)
P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FIFO_APPEND, 1)
#define P99_FIFO_APPEND(L, EL) \
do { \
/* first evaluate the macro arguments such that there can't be */ \
/* name conflicts */ \
register const P99_MACRO_VAR(p00_l, (L)); \
register const P99_MACRO_VAR(p00_el, (EL)); \
register const P99_MACRO_VAR(p00_h, &(*p00_l)[0]); \
register const P99_MACRO_VAR(p00_t, &(*p00_l)[1]); \
p00_el->p99_lifo = 0; \
P99_MACRO_VAR(p00_head, atomic_load_explicit(p00_h, memory_order_relaxed)); \
for (;;) { \
if (p00_head) { \
/* spin lock the whole fifo */ \
if (atomic_compare_exchange_weak_explicit(p00_h, &p00_head, 0, memory_order_acq_rel, memory_order_relaxed)) { \
/* make p00_el the last element */ \
atomic_exchange_explicit(p00_t, p00_el, memory_order_acq_rel)->p99_lifo = p00_el; \
/* unlock the fifo */ \
atomic_store_explicit(p00_h, p00_head, memory_order_release); \
break; \
} \
} else { \
P99_MACRO_VAR(p00_tail, atomic_load_explicit(p00_t, memory_order_relaxed)); \
if (!p00_tail \
#define P99_FIFO_APPEND(L, EL) \
do { \
/* first evaluate the macro arguments such that there can't be */ \
/* name conflicts */ \
register const P99_MACRO_VAR(p00_l, (L)); \
register const P99_MACRO_VAR(p00_el, (EL)); \
register const P99_MACRO_VAR(p00_h, &p00_l->p00_head); \
register const P99_MACRO_VAR(p00_t, &p00_l->p00_tail); \
p00_el->p99_lifo = 0; \
P99_MACRO_VAR(p00_head, atomic_load_explicit(p00_h, memory_order_relaxed)); \
for (;;) { \
if (p00_head) { \
/* spin lock the whole fifo */ \
if (atomic_compare_exchange_weak_explicit(p00_h, &p00_head, 0, memory_order_acq_rel, memory_order_relaxed)) { \
/* make p00_el the last element */ \
atomic_exchange_explicit(p00_t, p00_el, memory_order_acq_rel)->p99_lifo = p00_el; \
/* unlock the fifo */ \
atomic_store_explicit(p00_h, p00_head, memory_order_release); \
break; \
} \
} else { \
P99_MACRO_VAR(p00_tail, atomic_load_explicit(p00_t, memory_order_relaxed)); \
if (!p00_tail \
&& atomic_compare_exchange_weak_explicit(p00_t, &p00_tail, p00_el, memory_order_acq_rel, memory_order_relaxed)) { \
/* the fifo was empty, our element is inserted, update the head */ \
atomic_store_explicit(p00_h, p00_el, memory_order_release); \
break; \
} \
/* we were in the middle of an update of another thread */ \
p00_head = atomic_load_explicit(p00_h, memory_order_consume); \
} \
} \
/* the fifo was empty, our element is inserted, update the head */ \
atomic_store_explicit(p00_h, p00_el, memory_order_release); \
break; \
} \
/* we were in the middle of an update of another thread */ \
p00_head = atomic_load_explicit(p00_h, memory_order_consume); \
} \
} \
} while (false)
/**
......@@ -121,39 +125,39 @@ do { \
** @see P99_FIFO_APPEND
**/
P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FIFO_POP, 0)
#define P99_FIFO_POP(L) \
p99_extension \
({ \
/* first evaluate the macro argument such that there can't be */ \
/* a name conflict */ \
register const P99_MACRO_VAR(p00_l, (L)); \
register const P99_MACRO_VAR(p00_h, &(*p00_l)[0]); \
register const P99_MACRO_VAR(p00_t, &(*p00_l)[1]); \
P99_MACRO_VAR(p00_head, atomic_load_explicit(p00_h, memory_order_relaxed)); \
for (;;) { \
if (p00_head) { \
/* spin lock the whole fifo */ \
#define P99_FIFO_POP(L) \
p99_extension \
({ \
/* first evaluate the macro argument such that there can't be */ \
/* a name conflict */ \
register const P99_MACRO_VAR(p00_l, (L)); \
register const P99_MACRO_VAR(p00_h, &p00_l->p00_head); \
register const P99_MACRO_VAR(p00_t, &p00_l->p00_tail); \
P99_MACRO_VAR(p00_head, atomic_load_explicit(p00_h, memory_order_relaxed)); \
for (;;) { \
if (p00_head) { \
/* spin lock the whole fifo */ \
if (atomic_compare_exchange_weak_explicit(p00_h, &p00_head, 0, memory_order_acq_rel, memory_order_consume)) { \
if (p00_head->p99_lifo) \
/* there is still another element to come in the fifo, make it \
the head */ \
atomic_store_explicit(p00_h, p00_head->p99_lifo, memory_order_release); \
else \
/* this was the last element in the fifo, set the tail to 0, \
too */ \
atomic_store_explicit(p00_t, 0, memory_order_release); \
p00_head->p99_lifo = 0; \
break; \
} \
} else { \
register P99_MACRO_VAR(p00_tail, atomic_load_explicit(p00_t, memory_order_consume)); \
if (!p00_tail) break; \
p00_head = atomic_load_explicit(p00_h, memory_order_relaxed); \
} \
} \
/* make sure that the result can not be used as an lvalue */ \
register const __typeof__(p00_head = p00_head) p00_r = p00_head; \
p00_r; \
if (p00_head->p99_lifo) \
/* there is still another element to come in the fifo, make it \
the head */ \
atomic_store_explicit(p00_h, p00_head->p99_lifo, memory_order_release); \
else \
/* this was the last element in the fifo, set the tail to 0, \
too */ \
atomic_store_explicit(p00_t, 0, memory_order_release); \
p00_head->p99_lifo = 0; \
break; \
} \
} else { \
register P99_MACRO_VAR(p00_tail, atomic_load_explicit(p00_t, memory_order_consume)); \
if (!p00_tail) break; \
p00_head = atomic_load_explicit(p00_h, memory_order_relaxed); \
} \
} \
/* make sure that the result can not be used as an lvalue */ \
register const __typeof__(p00_head = p00_head) p00_r = p00_head; \
p00_r; \
})
/**
......@@ -166,31 +170,31 @@ p99_extension \
** @see P00_FIFO_EL
**/
P00_DOCUMENT_PERMITTED_ARGUMENT(P99_FIFO_CLEAR, 0)
#define P99_FIFO_CLEAR(L) \
p99_extension \
({ \
/* first evaluate the macro argument such that there can't be */ \
/* a name conflict */ \
register const P99_MACRO_VAR(p00_l, (L)); \
register const P99_MACRO_VAR(p00_h, &(*p00_l)[0]); \
register const P99_MACRO_VAR(p00_t, &(*p00_l)[1]); \
P99_MACRO_VAR(p00_head, atomic_load_explicit(p00_h, memory_order_relaxed)); \
for (;;) { \
if (p00_head) { \
/* spin lock the whole fifo */ \
#define P99_FIFO_CLEAR(L) \
p99_extension \
({ \
/* first evaluate the macro argument such that there can't be */ \
/* a name conflict */ \
register const P99_MACRO_VAR(p00_l, (L)); \
register const P99_MACRO_VAR(p00_h, &p00_l->p00_head); \
register const P99_MACRO_VAR(p00_t, &p00_l->p00_tail); \
P99_MACRO_VAR(p00_head, atomic_load_explicit(p00_h, memory_order_relaxed)); \
for (;;) { \
if (p00_head) { \
/* spin lock the whole fifo */ \
if (atomic_compare_exchange_weak_explicit(p00_h, &p00_head, 0, memory_order_acq_rel, memory_order_consume)) { \
atomic_store_explicit(p00_t, 0, memory_order_release); \
break; \
} \
} else { \
register const P99_MACRO_VAR(p00_tail, atomic_load_explicit(p00_t, memory_order_consume)); \
if (!p00_tail) break; \
p00_head = atomic_load_explicit(p00_h, memory_order_relaxed);\
} \
} \
/* make sure that the result can not be used as an lvalue */ \
register const __typeof__(p00_head = p00_head) p00_r = p00_head; \
p00_r; \
atomic_store_explicit(p00_t, 0, memory_order_release); \
break; \
} \
} else { \
register const P99_MACRO_VAR(p00_tail, atomic_load_explicit(p00_t, memory_order_consume)); \
if (!p00_tail) break; \
p00_head = atomic_load_explicit(p00_h, memory_order_relaxed); \
} \
} \
/* make sure that the result can not be used as an lvalue */ \
register const __typeof__(p00_head = p00_head) p00_r = p00_head; \
p00_r; \
})
#else
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment