#include "ga.h" /* Instead of using a static variable, we could attach this to a communicator, using a communicator attribute */ static MPI_Win gamutex_win = MPI_WIN_NULL; int ga_create_mutexes(int num) { int rank, i, *counterMem = 0, countersize=0; MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { countersize = num * sizeof(int); MPI_Alloc_mem(countersize, MPI_INFO_NULL, &counterMem); for (i=0; i<num; i++) counterMem[i] = 0; } MPI_Win_create(counterMem, countersize, sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &gamutex_win); return 0; } int ga_lock(int n) { int mone = -1, one=1, oldval; MPI_Win_lock(MPI_LOCK_SHARED, 0, 0, gamutex_win); do { MPI_Fetch_and_op(&one, &oldval, MPI_INT, 0, n, MPI_SUM, gamutex_win); MPI_Win_flush(0, gamutex_win); if (oldval == 0) break; MPI_Accumulate(&mone, 1, MPI_INT, 0, n, 1, MPI_INT, MPI_SUM, gamutex_win); MPI_Win_flush(0, gamutex_win); /* We could wait a little bit, depending on oldval */ } while (1); MPI_Win_unlock(0, gamutex_win); return 0; } int ga_unlock(int n) { int mone = -1; MPI_Win_lock(MPI_LOCK_SHARED, 0, 0, gamutex_win); MPI_Accumulate(&mone, 1, MPI_INT, 0, n, 1, MPI_INT, MPI_SUM, gamutex_win); MPI_Win_unlock(0, gamutex_win); return 0; }