|
Packit Service |
c5cf8c |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* (C) 2001 by Argonne National Laboratory.
|
|
Packit Service |
c5cf8c |
* See COPYRIGHT in top-level directory.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include <stdio.h>
|
|
Packit Service |
c5cf8c |
#include <stdlib.h>
|
|
Packit Service |
c5cf8c |
#include <assert.h>
|
|
Packit Service |
c5cf8c |
#include <strings.h>
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include <mpi.h>
|
|
Packit Service |
c5cf8c |
#include "muteximpl.h"
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* -- Begin Profiling Symbol Block for routine MPIX_Mutex_unlock */
|
|
Packit Service |
c5cf8c |
#if defined(HAVE_PRAGMA_WEAK)
|
|
Packit Service |
c5cf8c |
#pragma weak MPIX_Mutex_unlock = PMPIX_Mutex_unlock
|
|
Packit Service |
c5cf8c |
#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
|
|
Packit Service |
c5cf8c |
#pragma _HP_SECONDARY_DEF PMPIX_Mutex_unlock MPIX_Mutex_unlock
|
|
Packit Service |
c5cf8c |
#elif defined(HAVE_PRAGMA_CRI_DUP)
|
|
Packit Service |
c5cf8c |
#pragma _CRI duplicate MPIX_Mutex_unlock as PMPIX_Mutex_unlock
|
|
Packit Service |
c5cf8c |
#elif defined(HAVE_WEAK_ATTRIBUTE)
|
|
Packit Service |
c5cf8c |
int MPIX_Mutex_unlock(MPIX_Mutex hdl, int mutex, int proc)
|
|
Packit Service |
c5cf8c |
__attribute__ ((weak, alias("PMPIX_Mutex_unlock")));
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
/* -- End Profiling Symbol Block */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
|
|
Packit Service |
c5cf8c |
the MPI routines */
|
|
Packit Service |
c5cf8c |
#ifndef MPICH_MPI_FROM_PMPI
|
|
Packit Service |
c5cf8c |
#undef MPIX_Mutex_unlock
|
|
Packit Service |
c5cf8c |
#define MPIX_Mutex_unlock PMPIX_Mutex_unlock
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#undef FUNCNAME
|
|
Packit Service |
c5cf8c |
#define FUNCNAME MPIX_Mutex_unlock
|
|
Packit Service |
c5cf8c |
#undef FCNAME
|
|
Packit Service |
c5cf8c |
#define FCNAME MPL_QUOTE(FUNCNAME)
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/** Unlock a mutex.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* @param[in] hdl Mutex group that the mutex belongs to.
|
|
Packit Service |
c5cf8c |
* @param[in] mutex Desired mutex number [0..count-1]
|
|
Packit Service |
c5cf8c |
* @param[in] proc Rank of process where the mutex lives
|
|
Packit Service |
c5cf8c |
* @return MPI status
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int MPIX_Mutex_unlock(MPIX_Mutex hdl, int mutex, int proc)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int rank, nproc, i;
|
|
Packit Service |
c5cf8c |
uint8_t *buf;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
assert(mutex >= 0 && mutex < hdl->max_count);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Comm_rank(hdl->comm, &rank;;
|
|
Packit Service |
c5cf8c |
MPI_Comm_size(hdl->comm, &nproc);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
assert(proc >= 0 && proc < nproc);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
buf = malloc(nproc * sizeof(uint8_t));
|
|
Packit Service |
c5cf8c |
assert(buf != NULL);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
buf[rank] = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Get all data from the lock_buf, except the byte belonging to
|
|
Packit Service |
c5cf8c |
* me. Set the byte belonging to me to 0. */
|
|
Packit Service |
c5cf8c |
MPI_Win_lock(MPI_LOCK_EXCLUSIVE, proc, 0, hdl->windows[mutex]);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Put(&buf[rank], 1, MPI_BYTE, proc, rank, 1, MPI_BYTE, hdl->windows[mutex]);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Get data to the left of rank */
|
|
Packit Service |
c5cf8c |
if (rank > 0) {
|
|
Packit Service |
c5cf8c |
MPI_Get(buf, rank, MPI_BYTE, proc, 0, rank, MPI_BYTE, hdl->windows[mutex]);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Get data to the right of rank */
|
|
Packit Service |
c5cf8c |
if (rank < nproc - 1) {
|
|
Packit Service |
c5cf8c |
MPI_Get(&buf[rank + 1], nproc - 1 - rank, MPI_BYTE, proc, rank + 1, nproc - 1 - rank,
|
|
Packit Service |
c5cf8c |
MPI_BYTE, hdl->windows[mutex]);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Win_unlock(proc, hdl->windows[mutex]);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
assert(buf[rank] == 0);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Notify the next waiting process, starting to my right for fairness */
|
|
Packit Service |
c5cf8c |
for (i = 1; i < nproc; i++) {
|
|
Packit Service |
c5cf8c |
int p = (rank + i) % nproc;
|
|
Packit Service |
c5cf8c |
if (buf[p] == 1) {
|
|
Packit Service |
c5cf8c |
debug_print("notifying %d [proc = %d, mutex = %d]\n", p, proc, mutex);
|
|
Packit Service |
c5cf8c |
MPI_Send(NULL, 0, MPI_BYTE, p, MPIX_MUTEX_TAG + mutex, hdl->comm);
|
|
Packit Service |
c5cf8c |
break;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
debug_print("lock released [proc = %d, mutex = %d]\n", proc, mutex);
|
|
Packit Service |
c5cf8c |
free(buf);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return MPI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|