urcu-bp-static.h | urcu-bp-static.h | |||
---|---|---|---|---|
skipping to change at line 143 | skipping to change at line 143 | |||
* Global quiescent period counter with low-order bits unused. | * Global quiescent period counter with low-order bits unused. | |||
* Using a int rather than a char to eliminate false register dependencies | * Using a int rather than a char to eliminate false register dependencies | |||
* causing stalls on some architectures. | * causing stalls on some architectures. | |||
*/ | */ | |||
extern long rcu_gp_ctr; | extern long rcu_gp_ctr; | |||
struct rcu_reader { | struct rcu_reader { | |||
/* Data used by both reader and synchronize_rcu() */ | /* Data used by both reader and synchronize_rcu() */ | |||
long ctr; | long ctr; | |||
/* Data used for registry */ | /* Data used for registry */ | |||
struct list_head head __attribute__((aligned(CACHE_LINE_SIZE))); | struct list_head node __attribute__((aligned(CACHE_LINE_SIZE))); | |||
pthread_t tid; | pthread_t tid; | |||
int alloc; /* registry entry allocated */ | int alloc; /* registry entry allocated */ | |||
}; | }; | |||
/* | /* | |||
* Bulletproof version keeps a pointer to a registry not part of the TLS. | * Bulletproof version keeps a pointer to a registry not part of the TLS. | |||
* Adds a pointer dereference on the read-side, but won't require to unregi ster | * Adds a pointer dereference on the read-side, but won't require to unregi ster | |||
* the reader thread. | * the reader thread. | |||
*/ | */ | |||
extern struct rcu_reader __thread *rcu_reader; | extern struct rcu_reader __thread *rcu_reader; | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
urcu-qsbr-static.h | urcu-qsbr-static.h | |||
---|---|---|---|---|
skipping to change at line 138 | skipping to change at line 138 | |||
* Global quiescent period counter with low-order bits unused. | * Global quiescent period counter with low-order bits unused. | |||
* Using a int rather than a char to eliminate false register dependencies | * Using a int rather than a char to eliminate false register dependencies | |||
* causing stalls on some architectures. | * causing stalls on some architectures. | |||
*/ | */ | |||
extern unsigned long rcu_gp_ctr; | extern unsigned long rcu_gp_ctr; | |||
struct rcu_reader { | struct rcu_reader { | |||
/* Data used by both reader and synchronize_rcu() */ | /* Data used by both reader and synchronize_rcu() */ | |||
unsigned long ctr; | unsigned long ctr; | |||
/* Data used for registry */ | /* Data used for registry */ | |||
struct list_head head __attribute__((aligned(CACHE_LINE_SIZE))); | struct list_head node __attribute__((aligned(CACHE_LINE_SIZE))); | |||
pthread_t tid; | pthread_t tid; | |||
}; | }; | |||
extern struct rcu_reader __thread rcu_reader; | extern struct rcu_reader __thread rcu_reader; | |||
extern int gp_futex; | extern int gp_futex; | |||
/* | /* | |||
* Wake-up waiting synchronize_rcu(). Called from many concurrent threads. | * Wake-up waiting synchronize_rcu(). Called from many concurrent threads. | |||
*/ | */ | |||
static inline void wake_up_gp(void) | static inline void wake_up_gp(void) | |||
{ | { | |||
if (unlikely(uatomic_read(&gp_futex) == -1)) { | if (unlikely(uatomic_read(&gp_futex) == -1)) { | |||
uatomic_set(&gp_futex, 0); | uatomic_set(&gp_futex, 0); | |||
futex_noasync(&gp_futex, FUTEX_WAKE, 1, | futex_noasync(&gp_futex, FUTEX_WAKE, 1, | |||
NULL, NULL, 0); | NULL, NULL, 0); | |||
} | } | |||
} | } | |||
#if (BITS_PER_LONG < 64) | ||||
static inline int rcu_gp_ongoing(unsigned long *ctr) | static inline int rcu_gp_ongoing(unsigned long *ctr) | |||
{ | { | |||
unsigned long v; | unsigned long v; | |||
v = LOAD_SHARED(*ctr); | v = LOAD_SHARED(*ctr); | |||
return v && ((v ^ rcu_gp_ctr) & RCU_GP_CTR); | return v && (v != rcu_gp_ctr); | |||
} | } | |||
#else /* !(BITS_PER_LONG < 64) */ | ||||
static inline int rcu_gp_ongoing(unsigned long *ctr) | ||||
{ | ||||
unsigned long v; | ||||
v = LOAD_SHARED(*ctr); | ||||
return v && (v - rcu_gp_ctr > ULONG_MAX / 2); | ||||
} | ||||
#endif /* !(BITS_PER_LONG < 64) */ | ||||
static inline void _rcu_read_lock(void) | static inline void _rcu_read_lock(void) | |||
{ | { | |||
rcu_assert(rcu_reader.ctr); | rcu_assert(rcu_reader.ctr); | |||
} | } | |||
static inline void _rcu_read_unlock(void) | static inline void _rcu_read_unlock(void) | |||
{ | { | |||
} | } | |||
End of changes. 4 change blocks. | ||||
12 lines changed or deleted | 2 lines changed or added | |||
urcu-static.h | urcu-static.h | |||
---|---|---|---|---|
skipping to change at line 225 | skipping to change at line 225 | |||
* Using a int rather than a char to eliminate false register dependencies | * Using a int rather than a char to eliminate false register dependencies | |||
* causing stalls on some architectures. | * causing stalls on some architectures. | |||
*/ | */ | |||
extern unsigned long rcu_gp_ctr; | extern unsigned long rcu_gp_ctr; | |||
struct rcu_reader { | struct rcu_reader { | |||
/* Data used by both reader and synchronize_rcu() */ | /* Data used by both reader and synchronize_rcu() */ | |||
unsigned long ctr; | unsigned long ctr; | |||
char need_mb; | char need_mb; | |||
/* Data used for registry */ | /* Data used for registry */ | |||
struct list_head head __attribute__((aligned(CACHE_LINE_SIZE))); | struct list_head node __attribute__((aligned(CACHE_LINE_SIZE))); | |||
pthread_t tid; | pthread_t tid; | |||
}; | }; | |||
extern struct rcu_reader __thread rcu_reader; | extern struct rcu_reader __thread rcu_reader; | |||
extern int gp_futex; | extern int gp_futex; | |||
/* | /* | |||
* Wake-up waiting synchronize_rcu(). Called from many concurrent threads. | * Wake-up waiting synchronize_rcu(). Called from many concurrent threads. | |||
*/ | */ | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||