Skip to content

Commit

Permalink
Add memory barriers to full/empty bit manipulations to fix synchroniz…
Browse files Browse the repository at this point in the history
…ation bugs.
  • Loading branch information
ehein6 committed Nov 22, 2016
1 parent 0eb1f54 commit b6f65df
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
18 changes: 18 additions & 0 deletions lib/stinger_core/inc/stinger_atomics.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ extern "C" {

#include "stinger.h"

static inline void stinger_memory_barrier();
static inline int stinger_int_fetch_add (int *, int);
static inline int64_t stinger_int64_fetch_add (int64_t *, int64_t);
static inline uint64_t stinger_uint64_fetch_add (uint64_t *, uint64_t);
Expand All @@ -26,6 +27,12 @@ static inline void *stinger_ptr_cas (void **, void *, void *);

#if defined(__GNUC__)||defined(__INTEL_COMPILER)
/* {{{ GCC / ICC defs */
void
stinger_memory_barrier()
{
__sync_synchronize();
}

int
stinger_int_fetch_add (int *x, int i)
{
Expand Down Expand Up @@ -87,6 +94,12 @@ stinger_int64_cas (int64_t * x, int64_t origx, int64_t newx)
/* }}} */
#elif defined(__xlc__)
/* {{{ XLC defs */
void
stinger_memory_barrier()
{
__sync_synchronize();
}

int
stinger_int_fetch_add (int *x, int i)
{
Expand Down Expand Up @@ -153,6 +166,11 @@ stinger_int64_cas (int64_t * x, int64_t origx, int64_t newx)
#elif !defined(_OPENMP)
#warning "Assuming no parallel / concurrent operations necessary."
/* {{{ Not concurrent */
void
stinger_memory_barrier()
{
}

int
stinger_int_fetch_add (int *v, int x)
{
Expand Down
12 changes: 9 additions & 3 deletions lib/stinger_core/src/x86_full_empty.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/* x86 Emulation of Full Empty Bits Using atomic check-and-swap.
*
* NOTES:
* - Using these functions means that the MARKER value defined
* below must be reserved in your application and CANNOT be
* - Using these functions means that the MARKER value defined
* below must be reserved in your application and CANNOT be
* considered a normal value. Feel free to change the value to
* suit your application.
* - Do not compile this file with optimization. There are loops
Expand All @@ -15,8 +15,9 @@

#include "x86_full_empty.h"

uint64_t
uint64_t
readfe(volatile uint64_t * v) {
stinger_memory_barrier();
uint64_t val;
while(1) {
val = *v;
Expand All @@ -31,6 +32,7 @@ readfe(volatile uint64_t * v) {

uint64_t
writeef(volatile uint64_t * v, uint64_t new_val) {
stinger_memory_barrier();
uint64_t val;
while(1) {
val = *v;
Expand All @@ -45,6 +47,7 @@ writeef(volatile uint64_t * v, uint64_t new_val) {

uint64_t
readff(volatile uint64_t * v) {
stinger_memory_barrier();
uint64_t val = *v;
while(val == MARKER) {
val = *v;
Expand All @@ -54,6 +57,7 @@ readff(volatile uint64_t * v) {

uint64_t
writeff(volatile uint64_t * v, uint64_t new_val) {
stinger_memory_barrier();
uint64_t val;
while(1) {
val = *v;
Expand All @@ -68,6 +72,8 @@ writeff(volatile uint64_t * v, uint64_t new_val) {

uint64_t
writexf(volatile uint64_t * v, uint64_t new_val) {
stinger_memory_barrier();
*v = new_val;
stinger_memory_barrier();
return new_val;
}

0 comments on commit b6f65df

Please sign in to comment.