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

don't suppose that the state of a p99_tp is always an integer type

parent 6cbb4676
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
# define P99_LIFO(T) P99_PASTE2(p00_lifo_, T) # define P99_LIFO(T) P99_PASTE2(p00_lifo_, T)
# define P99_LIFO_DECLARE(T) \ # define P99_LIFO_DECLARE(T) \
typedef struct P99_PASTE2(p00_lifo_, T) P99_PASTE2(p00_lifo_, T); \ typedef struct P99_PASTE2(p00_lifo_, T) P99_PASTE2(p00_lifo_, T); \
_Alignas(sizeof(p00_tp_uint)) struct P99_PASTE2(p00_lifo_, T) { \ _Alignas(sizeof(p00_tp_state)) struct P99_PASTE2(p00_lifo_, T) { \
p99_tp p00_tp; \ p99_tp p00_tp; \
T p00_dum; /* we only need this for its type */ \ T p00_dum; /* we only need this for its type */ \
} }
......
...@@ -22,19 +22,34 @@ ...@@ -22,19 +22,34 @@
# endif # endif
#if UINTPTR_MAX == UINT32_MAX #if UINTPTR_MAX == UINT32_MAX
typedef uint64_t p00_tp_uint; typedef uint64_t p00_tp_state;
#else #else
# if defined(UINT128_MAX) # if defined(UINT128_MAX)
typedef uint128_t p00_tp_uint; typedef uint128_t p00_tp_state;
# else # else
typedef p99x_uint128 p00_tp_uint; typedef p99x_uint128 p00_tp_state;
# endif # endif
#endif #endif
P99_CONSTANT(int, p00_tp_bits, sizeof(p00_tp_uint)*CHAR_BIT); P99_CONSTANT(int, p00_tp_bits, sizeof(p00_tp_state)*CHAR_BIT);
P99_CONSTANT(int, p00_tp_shift, p00_tp_bits/2); P99_CONSTANT(int, p00_tp_shift, p00_tp_bits/2);
P99_DECLARE_ATOMIC(p00_tp_uint); p99_inline
p00_tp_state p00_tp_p2i(void * p, uintptr_t t) {
return (((p00_tp_state)t)<<p00_tp_shift)|(uintptr_t)p;
}
p99_inline
void * p00_tp_i2p(p00_tp_state v) {
return (void*)(uintptr_t)v;
}
p99_inline
uintptr_t p00_tp_i2i(p00_tp_state v) {
return v >> p00_tp_shift;
}
P99_DECLARE_ATOMIC(p00_tp_state);
P99_DECLARE_STRUCT(p99_tp); P99_DECLARE_STRUCT(p99_tp);
P99_DECLARE_STRUCT(p99_tp_state); P99_DECLARE_STRUCT(p99_tp_state);
...@@ -49,7 +64,7 @@ P99_DECLARE_STRUCT(p99_tp_state); ...@@ -49,7 +64,7 @@ P99_DECLARE_STRUCT(p99_tp_state);
** @see p99_tp_state ** @see p99_tp_state
**/ **/
struct p99_tp { struct p99_tp {
_Atomic(p00_tp_uint) p00_val; _Atomic(p00_tp_state) p00_val;
_Atomic(uintptr_t) p00_tic; _Atomic(uintptr_t) p00_tic;
}; };
...@@ -75,9 +90,8 @@ struct p99_tp { ...@@ -75,9 +90,8 @@ struct p99_tp {
** @see p99_tp_state_initializer ** @see p99_tp_state_initializer
**/ **/
struct p99_tp_state { struct p99_tp_state {
p00_tp_uint p00_val; p00_tp_state p00_val;
p00_tp_uint p00_next; p00_tp_state p00_next;
uintptr_t p00_tic;
p99_tp* p00_tp; p99_tp* p00_tp;
}; };
...@@ -87,15 +101,10 @@ struct p99_tp_state { ...@@ -87,15 +101,10 @@ struct p99_tp_state {
} }
p99_inline p99_inline
p00_tp_uint p00_tp_get(p99_tp* p00_tp) { p00_tp_state p00_tp_get(p99_tp* p00_tp) {
return atomic_load(&p00_tp->p00_val); return atomic_load(&p00_tp->p00_val);
} }
p99_inline
p00_tp_uint p00_tp_p2i(void * p, p00_tp_uint t) {
return (t<<p00_tp_shift)|(uintptr_t)p;
}
/** /**
** @brief Load the value of @a p00_tp into the state variable and ** @brief Load the value of @a p00_tp into the state variable and
** prepare it to commit value @a p00_p later. ** prepare it to commit value @a p00_p later.
...@@ -105,17 +114,11 @@ p99_tp_state p99_tp_state_initializer(p99_tp* p00_tp, void* p00_p) { ...@@ -105,17 +114,11 @@ p99_tp_state p99_tp_state_initializer(p99_tp* p00_tp, void* p00_p) {
uintptr_t p00_tic = atomic_fetch_add(&p00_tp->p00_tic, UINTPTR_C(1)); uintptr_t p00_tic = atomic_fetch_add(&p00_tp->p00_tic, UINTPTR_C(1));
return (p99_tp_state) { return (p99_tp_state) {
.p00_val = p00_tp_get(p00_tp), .p00_val = p00_tp_get(p00_tp),
.p00_next = (p00_p ? p00_tp_p2i(p00_p, p00_tic) : 0), .p00_next = p00_tp_p2i(p00_p, p00_tic),
.p00_tic = p00_tic,
.p00_tp = p00_tp, .p00_tp = p00_tp,
}; };
} }
p99_inline
void * p00_tp_i2p(uintptr_t v) {
return (void*)v;
}
p99_inline p99_inline
void * p99_tp_state_get(p99_tp_state* p00_state) { void * p99_tp_state_get(p99_tp_state* p00_state) {
return p00_tp_i2p(p00_state->p00_val); return p00_tp_i2p(p00_state->p00_val);
...@@ -128,11 +131,11 @@ void * p99_tp_get(p99_tp* p00_tp) { ...@@ -128,11 +131,11 @@ void * p99_tp_get(p99_tp* p00_tp) {
p99_inline p99_inline
void p99_tp_state_set(p99_tp_state* p00_state, void* p00_p) { void p99_tp_state_set(p99_tp_state* p00_state, void* p00_p) {
p00_state->p00_next = p00_tp_p2i(p00_p, p00_state->p00_tic); p00_state->p00_next = p00_tp_p2i(p00_p, p00_tp_i2i(p00_state->p00_next));
} }
p99_inline p99_inline
bool p00_tp_cmpxchg(_Atomic(p00_tp_uint)* p00_p, p00_tp_uint* p00_prev, p00_tp_uint p00_new) { bool p00_tp_cmpxchg(_Atomic(p00_tp_state)* p00_p, p00_tp_state* p00_prev, p00_tp_state p00_new) {
P99_MARK("wide cmpxchg start"); P99_MARK("wide cmpxchg start");
bool ret = atomic_compare_exchange_weak(p00_p, p00_prev, p00_new); bool ret = atomic_compare_exchange_weak(p00_p, p00_prev, p00_new);
P99_MARK("wide cmpxchg end"); P99_MARK("wide cmpxchg end");
......
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