Skip to content

Commit

Permalink
Merge pull request #215 from ehein6/full-empty-volatile
Browse files Browse the repository at this point in the history
Fix full/empty bit semantics for architectures with weak memory ordering (POWER8).
  • Loading branch information
davidediger authored Nov 22, 2016
2 parents 19fbb3b + ed250cf commit ac933f2
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 22 deletions.
7 changes: 2 additions & 5 deletions lib/stinger_core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ set(sources
src/stinger_shared.c
src/stinger_vertex.c
src/xmalloc.c
src/x86_full_empty.c
)
set(headers
inc/core_util.h
Expand All @@ -24,9 +25,6 @@ set(headers
inc/x86_full_empty.h
inc/xmalloc.h
)
set(unoptimized_sources
src/x86_full_empty.c
)

set(config
stinger_names.h
Expand All @@ -39,6 +37,5 @@ include_directories("${CMAKE_BINARY_DIR}/include/stinger_core")
include_directories("${CMAKE_BINARY_DIR}/include/stinger_utils")

set_source_files_properties(${config} PROPERTIES GENERATED TRUE)
set_source_files_properties(${unoptimized_sources} PROPERTIES COMPILE_FLAGS -O0)
add_library(stinger_core SHARED ${sources} ${unoptimized_sources} ${headers} ${config})
add_library(stinger_core SHARED ${sources} ${headers} ${config})
target_link_libraries(stinger_core compat)
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
10 changes: 5 additions & 5 deletions lib/stinger_core/inc/x86_full_empty.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,19 @@ extern "C" {
#define MARKER UINT64_MAX

uint64_t
readfe(uint64_t * v);
readfe(volatile uint64_t * v);

uint64_t
writeef(uint64_t * v, uint64_t new_val);
writeef(volatile uint64_t * v, uint64_t new_val);

uint64_t
readff(uint64_t * v);
readff(volatile uint64_t * v);

uint64_t
writeff(uint64_t * v, uint64_t new_val);
writeff(volatile uint64_t * v, uint64_t new_val);

uint64_t
writexf(uint64_t * v, uint64_t new_val);
writexf(volatile uint64_t * v, uint64_t new_val);

#ifdef __cplusplus
}
Expand Down
27 changes: 15 additions & 12 deletions lib/stinger_core/src/x86_full_empty.c
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
/* x86 Emulation of Full Empty Bits Using atomic check-and-swap.
/* 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
* that do not make sense in a serial context. The compiler will
* optimize them out.
* - Improper use of these functions can and will result in deadlock.
*
* author: rmccoll3@gatech.edu
*/

#include "x86_full_empty.h"

uint64_t
readfe(uint64_t * v) {
uint64_t
readfe(volatile uint64_t * v) {
stinger_memory_barrier();
uint64_t val;
while(1) {
val = *v;
Expand All @@ -30,7 +28,8 @@ readfe(uint64_t * v) {
}

uint64_t
writeef(uint64_t * v, uint64_t new_val) {
writeef(volatile uint64_t * v, uint64_t new_val) {
stinger_memory_barrier();
uint64_t val;
while(1) {
val = *v;
Expand All @@ -44,7 +43,8 @@ writeef(uint64_t * v, uint64_t new_val) {
}

uint64_t
readff(uint64_t * v) {
readff(volatile uint64_t * v) {
stinger_memory_barrier();
uint64_t val = *v;
while(val == MARKER) {
val = *v;
Expand All @@ -53,7 +53,8 @@ readff(uint64_t * v) {
}

uint64_t
writeff(uint64_t * v, uint64_t new_val) {
writeff(volatile uint64_t * v, uint64_t new_val) {
stinger_memory_barrier();
uint64_t val;
while(1) {
val = *v;
Expand All @@ -67,7 +68,9 @@ writeff(uint64_t * v, uint64_t new_val) {
}

uint64_t
writexf(uint64_t * v, uint64_t new_val) {
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 ac933f2

Please sign in to comment.