extern int MPE_COUNTER_KEYVAL;
extern int MPEi_CounterFree(MPI_Win counter_win, int keyval,
                            void *attr_val, void *extra_state);

void MPE_Counter_create(MPI_Comm comm, int num,
                        MPI_Win *counter_win)
{
  int size, rank, lnum, lleft, i, *counterMem=0;
  MPI_Aint counterSize;

  MPI_Comm_rank(comm, &rank);
  MPI_Comm_size(comm, &size);

  lnum  = num / size;
  lleft = num % size;
  if (rank < lleft) lnum++;
  counterSize = lnum * sizeof(int);
  if (counterSize > 0) {
    MPI_Alloc_mem(counterSize, MPI_INFO_NULL, &counterMem);
    for (i=0; i<lnum; i++) counterMem[i] = 0;
  }
  /* By using MPI_Alloc_mem first, we ensure that the initial
     value of the counters are zero.  See text */
  MPI_Win_create(counterMem, counterSize, sizeof(int),
		 MPI_INFO_NULL, comm, counter_win);

  /* Create key if necessary and store the number of counters */
  if (MPE_COUNTER_KEYVAL == MPI_KEYVAL_INVALID) {
    MPI_Win_create_keyval(MPI_WIN_NULL_COPY_FN,
			  MPEi_CounterFree,
			  &MPE_COUNTER_KEYVAL, NULL);
  }
  MPI_Win_set_attr(*counter_win, MPE_COUNTER_KEYVAL,
		   (void*)(MPI_Aint)num);
}