/*
*/
#include <stdio.h>
#include <unistd.h>
#include <mpi.h>

extern void twosync(int other);
void test1(int my_rank);
void test2(int my_rank);
void test3(int my_rank);
int n1, n2;



int
main(int argc, char *argv[])
{

int my_rank, nproc;


    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &nproc);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

    if (nproc < 3)   {
	if (my_rank == 0)   {
	    fprintf(stderr, "Need at least three nodes!\n");
	}
	MPI_Abort(MPI_COMM_WORLD, -1);
    }

    n1= nproc - 1;
    n2= nproc - 2;

    test1(my_rank);
    test2(my_rank);
    test3(my_rank);

    MPI_Finalize();
    return 0;

}  /* end of main() */


void
test1(int my_rank)
{
    if (my_rank == n1)   {
	twosync(n2);
    } else if (my_rank == n2)   {
	twosync(n1);
    }

    if (my_rank == n1)   {
	printf("[%2d] Test 1: Basic passed.\n", my_rank);
    }
}  /* end of test1() */


void
test2(int my_rank)
{

double t1, t2;


    t1= MPI_Wtime();
    if (my_rank == n1)   {
	sleep(1);
	twosync(n2);
    } else if (my_rank == n2)   {
	twosync(n1);
    }
    t2= MPI_Wtime();

    if ((my_rank == n1) || (my_rank == n2))   {
	if ((t2 - t1) < 0.8)   {
	    printf("[%2d] Test 2: FAILED.\n", my_rank);
	} else if (my_rank == n1)   {
	    printf("[%2d] Test 2: passed.\n", my_rank);
	}
    }
}  /* end of test2() */


void
test3(int my_rank)
{

double t1, t2;


    t1= MPI_Wtime();
    if (my_rank == n1)   {
	twosync(n2);
    } else if (my_rank == n2)   {
	sleep(1);
	twosync(n1);
    }
    t2= MPI_Wtime();

    if ((my_rank == n1) || (my_rank == n2))   {
	if ((t2 - t1) < 0.8)   {
	    printf("[%2d] Test 3: FAILED.\n", my_rank);
	} else if (my_rank == n1)   {
	    printf("[%2d] Test 3: passed.\n", my_rank);
	}
    }
}  /* end of test3() */
