/* Copyright 1995 Jonathan C. Hardwick */

#include <assert.h>
#include <mpi.h>
#include "globals.h"
#include "main.h"
#include "leader.h"

/* Tell the manager that a split has happened.  Note that we get the
 * absolute (world) rank of the new leader by taking the number of
 * processors in the less/old group, which is the relative rank of the
 * greater/new leader in the current group, and translating this rank
 * into an absolute rank. */

void
tell_mgr_about_split (int nprocOld, int neltOld, 
		      int nprocNew, int neltNew) 
{
  team_split_msg_t msg;

  assert (grnkCur == 0);

  msg.rnkLdrOld = grnkWorld;	/* Our absolute rank */
  msg.nprocOld  = nprocOld;
  msg.neltOld   = neltOld;
  MPI_Group_translate_ranks (ggrpCur, 1, &nprocOld, ggrpWorld,
			     &msg.rnkLdrNew);
  msg.nprocNew  = nprocNew;
  msg.neltNew   = neltNew;

  MPI_Send (&msg, sizeof(team_split_msg_t) / sizeof(int), MPI_INT, 0,
	    LDR_MGR_SPLIT_TAG, gcomWorld);
}


/* Synchronize with the manager, getting back a list (possibly empty) of
 * new processors to add to the team. */ 

int
recv_msg_from_mgr (int abuf [MAXPROCS])
{
  MPI_Status status;
  int nprocNew;
  int dummy;

  MPI_Send (&dummy, 0, MPI_INT, 0, LDR_MGR_SYNC_TAG, gcomWorld);
  
  /* Wait for it to send us a list of processors. */
  MPI_Recv (abuf, MAXPROCS, MPI_INT, 0, MGR_LDR_SYNC_TAG, gcomWorld,
	    &status);

  MPI_Get_count (&status, MPI_INT, &nprocNew);

  return nprocNew;
}
