コード例 #1
0
ファイル: mutex_hdl_queue.c プロジェクト: abhinavvishnu/matex
/** Lock a mutex.
  * 
  * @param[in] hdl        Mutex group that the mutex belongs to.
  * @param[in] mutex      Desired mutex number [0..count-1]
  * @param[in] world_proc Absolute ID of process where the mutex lives
  */
void ARMCIX_Lock_hdl(armcix_mutex_hdl_t hdl, int mutex, int world_proc) {
  int       rank, nproc, already_locked, i, proc;
  uint8_t *buf;

  ARMCII_Assert(mutex >= 0 && mutex < hdl->max_count);

  MPI_Comm_rank(hdl->grp.comm, &rank);
  MPI_Comm_size(hdl->grp.comm, &nproc);

  /* User gives us the absolute ID.  Translate to the rank in the mutex's group. */
  proc = ARMCII_Translate_absolute_to_group(&hdl->grp, world_proc);
  ARMCII_Assert(proc >= 0);

  buf = malloc(nproc*sizeof(uint8_t));
  ARMCII_Assert(buf != NULL);

  buf[rank] = 1;

  /* Get all data from the lock_buf, except the byte belonging to
   * me. Set the byte belonging to me to 1. */
  MPI_Win_lock(MPI_LOCK_EXCLUSIVE, proc, 0, hdl->windows[mutex]);
  
  MPI_Put(&buf[rank], 1, MPI_BYTE, proc, rank, 1, MPI_BYTE, hdl->windows[mutex]);

  /* Get data to the left of rank */
  if (rank > 0) {
    MPI_Get(buf, rank, MPI_BYTE, proc, 0, rank, MPI_BYTE, hdl->windows[mutex]);
  }

  /* Get data to the right of rank */
  if (rank < nproc - 1) {
    MPI_Get(&buf[rank+1], nproc-1-rank, MPI_BYTE, proc, rank + 1, nproc-1-rank, MPI_BYTE, hdl->windows[mutex]);
  }
  
  MPI_Win_unlock(proc, hdl->windows[mutex]);

  ARMCII_Assert(buf[rank] == 1);

  for (i = already_locked = 0; i < nproc; i++)
    if (buf[i] && i != rank)
      already_locked = 1;

  /* Wait for notification */
  if (already_locked) {
    MPI_Status status;
    ARMCII_Dbg_print(DEBUG_CAT_MUTEX, "waiting for notification [proc = %d, mutex = %d]\n", proc, mutex);
    MPI_Recv(NULL, 0, MPI_BYTE, MPI_ANY_SOURCE, ARMCI_MUTEX_TAG+mutex, hdl->grp.comm, &status);
  }

  ARMCII_Dbg_print(DEBUG_CAT_MUTEX, "lock acquired [proc = %d, mutex = %d]\n", proc, mutex);
  free(buf);
}
コード例 #2
0
ファイル: vector.c プロジェクト: OngOngoing/219351_homework
/** Check an I/O vector operation's buffers for overlap.
  *
  * @param[in] iov      Vector of transfer information.
  * @return             Logical true when regions overlap, 0 otherwise.
  */
int ARMCII_Iov_check_overlap(void **ptrs, int count, int size) {
#ifndef NO_CHECK_OVERLAP
#ifdef NO_USE_CTREE
  int i, j;

  if (ARMCII_GLOBAL_STATE.iov_checks_disabled) return 0;

  for (i = 0; i < count; i++) {
    for (j = i+1; j < count; j++) {
      const uint8_t *ptr_1_lo = ptrs[i];
      const uint8_t *ptr_1_hi = ((uint8_t*)ptrs[i]) + size - 1;
      const uint8_t *ptr_2_lo = ptrs[j];
      const uint8_t *ptr_2_hi = ((uint8_t*)ptrs[j]) + size - 1;

      if (   (ptr_1_lo >= ptr_2_lo && ptr_1_lo <= ptr_2_hi)
          || (ptr_1_hi >= ptr_2_lo && ptr_1_hi <= ptr_2_hi)
          || (ptr_1_lo <  ptr_2_lo && ptr_1_hi >  ptr_2_hi)) {
        ARMCII_Dbg_print(DEBUG_CAT_IOV, "IOV regions overlap: [%p, %p] - [%p, %p]\n",
            ptr_1_lo, ptr_1_hi, ptr_2_lo, ptr_2_hi);
        return 1;
      }
    }
  }
#else
  int i;
  ctree_t ctree = CTREE_EMPTY;

  if (ARMCII_GLOBAL_STATE.iov_checks_disabled) return 0;

  for (i = 0; i < count; i++) {
    int conflict = ctree_insert(&ctree, ptrs[i], ((uint8_t*)ptrs[i]) + size - 1);

    if (conflict) {
      ctree_t cnode = ctree_locate(ctree, ptrs[i], ((uint8_t*)ptrs[i]) + size - 1);

      ARMCII_Dbg_print(DEBUG_CAT_IOV, "IOV regions overlap: [%p, %p] - [%p, %p]\n",
          ptrs[i], ((uint8_t*)ptrs[i]) + size - 1, cnode->lo, cnode->hi);

      ctree_destroy(&ctree);
      return 1;
    }
  }

  ctree_destroy(&ctree);
#endif /* NO_USE_CTREE */
#endif /* NO_CHECK_OVERLAP */

  return 0;
}
コード例 #3
0
ファイル: mutex_hdl_queue.c プロジェクト: abhinavvishnu/matex
/** Unlock a mutex.
  * 
  * @param[in] hdl   Mutex group that the mutex belongs to.
  * @param[in] mutex Desired mutex number [0..count-1]
  * @param[in] world_proc Absolute ID of process where the mutex lives
  */
void ARMCIX_Unlock_hdl(armcix_mutex_hdl_t hdl, int mutex, int world_proc) {
  int      rank, nproc, i, proc;
  uint8_t *buf;

  ARMCII_Assert(mutex >= 0 && mutex < hdl->max_count);

  MPI_Comm_rank(hdl->grp.comm, &rank);
  MPI_Comm_size(hdl->grp.comm, &nproc);

  proc = ARMCII_Translate_absolute_to_group(&hdl->grp, world_proc);
  ARMCII_Assert(proc >= 0);

  buf = malloc(nproc*sizeof(uint8_t));

  buf[rank] = 0;

  /* Get all data from the lock_buf, except the byte belonging to
   * me. Set the byte belonging to me to 0. */
  MPI_Win_lock(MPI_LOCK_EXCLUSIVE, proc, 0, hdl->windows[mutex]);
  
  MPI_Put(&buf[rank], 1, MPI_BYTE, proc, rank, 1, MPI_BYTE, hdl->windows[mutex]);

  /* Get data to the left of rank */
  if (rank > 0) {
    MPI_Get(buf, rank, MPI_BYTE, proc, 0, rank, MPI_BYTE, hdl->windows[mutex]);
  }

  /* Get data to the right of rank */
  if (rank < nproc - 1) {
    MPI_Get(&buf[rank+1], nproc-1-rank, MPI_BYTE, proc, rank + 1, nproc-1-rank, MPI_BYTE, hdl->windows[mutex]);
  }
  
  MPI_Win_unlock(proc, hdl->windows[mutex]);

  ARMCII_Assert(buf[rank] == 0);

  /* Notify the next waiting process, starting to my right for fairness */
  for (i = 1; i < nproc; i++) {
    int p = (rank + i) % nproc;
    if (buf[p] == 1) {
      ARMCII_Dbg_print(DEBUG_CAT_MUTEX, "notifying %d [proc = %d, mutex = %d]\n", p, proc, mutex);
      MPI_Send(NULL, 0, MPI_BYTE, p, ARMCI_MUTEX_TAG+mutex, hdl->grp.comm);
      break;
    }
  }

  ARMCII_Dbg_print(DEBUG_CAT_MUTEX, "lock released [proc = %d, mutex = %d]\n", proc, mutex);
  free(buf);
}
コード例 #4
0
ファイル: malloc.c プロジェクト: jeffhammond/armci-mpi
/** Allocate a shared memory segment.  Collective.
  *
  * @param[out] base_ptrs Array that will contain pointers to the base address of
  *                       each process' patch of the segment.  Array is of length
  *                       equal to the number of processes in the group.
  * @param[in]       size Number of bytes to allocate on the local process.
  */
int ARMCI_Malloc_group(void **base_ptrs, armci_size_t size, ARMCI_Group *group) {
  int i;
  gmr_t *mreg;

  ARMCII_Assert(PARMCI_Initialized());

  mreg = gmr_create(size, base_ptrs, group);

  if (DEBUG_CAT_ENABLED(DEBUG_CAT_ALLOC)) {
#define BUF_LEN 1000
    char ptr_string[BUF_LEN];
    int  count = 0;

    if (mreg == NULL) {
      strncpy(ptr_string, "NULL", 5);
    } else {
      for (i = 0; i < mreg->nslices && count < BUF_LEN; i++)
        count += snprintf(ptr_string+count, BUF_LEN-count, 
            (i == mreg->nslices-1) ? "%p" : "%p ", base_ptrs[i]);
    }

    ARMCII_Dbg_print(DEBUG_CAT_ALLOC, "base ptrs [%s]\n", ptr_string);
#undef BUF_LEN
  }

  return 0;
}
コード例 #5
0
ファイル: malloc.c プロジェクト: jeffhammond/armci-mpi
/** Free a shared memory allocation.  Collective.
  *
  * @param[in] ptr Pointer to the local patch of the allocation
  */
int ARMCI_Free_group(void *ptr, ARMCI_Group *group) {
  gmr_t *mreg;

  if (ptr != NULL) {
    mreg = gmr_lookup(ptr, ARMCI_GROUP_WORLD.rank);
    ARMCII_Assert_msg(mreg != NULL, "Invalid shared pointer");
  } else {
    ARMCII_Dbg_print(DEBUG_CAT_ALLOC, "given NULL\n");
    mreg = NULL;
  }
  gmr_destroy(mreg, group);

  return 0;
}