/*
 * $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred."
 *
 */
/* use Cartesian coordinates to find the city closest to 
   Beaverton, Oregon, and print the name and distance 
   from Beaverton */

#include <stdio.h>
#include <math.h>
#include <parallel/microtask.h> /* microtasking header */
#include <parallel/parallel.h>  /* parallel library 
                                   header */

#define NCITIES 10     /* number of cities */
#define BITE 1         /* bite of work for hungry puppy */

      /* Global shared memory data */

	shared float shortest;    /* distance to 
						nearest city */
	shared int closest;       /* index of 
						nearest city */
	struct location {
		char *name;
		float x, y;
	}; 
	shared struct location cities[NCITIES] = {
		{ "CHICAGO", 2000.0, 100.0 },
		{ "DENVER", 500.0, -550.0 },
		{ "NEW YORK", 150.0, 100.0 },
		{ "SEATTLE", 0.0, 200.0 },
		{ "MIAMI", 3500.0, -2000.0 },
		{ "SAN FRANCISCO", -100.0, -1000.0 },
		{ "RENO", 200.0, -600.0 },
		{ "PORTLAND", -17.0, 0.0  },
		{ "WASHINGTON D.C.", 3000.0, -400.0 },
		{ "TILLAMOOK", -70.0, -50.0 },
	};
	shared struct location beaverton = { "BEAVERTON",
	    0.0, 0.0 };

main ()
{
  void get_cities(), find_dis(), m_fork(); 

  shortest = HUGE;
  m_fork(find_dis, cities);
  printf("%s is closest to Beaverton.\n",
	  cities[closest].name);
  printf("%s is %3.2f miles from Beaverton.\n", 
	  cities[closest].name, shortest);
}
/* find distance to nearest city */

void 
find_dis(cities)
struct location cities[];
{
int i, base, top;  /* local loop index, start & end value */
float xsqdis, ysqdis, dist;

while ((base = BITE*(m_next( )-1)) < NCITIES) {
	top = base + BITE;	/* take a bite of work */
	if (top >= NCITIES)
		top = NCITIES-1;

		/* execute all iterations in bite of work */

		for (i = base; i <= top; i++) {
		    xsqdis = pow(fabs(beaverton.x - cities[i].x),2.);
		    ysqdis = pow(fabs(beaverton.y - cities[i].y),2.);
		    dist   = sqrt(xsqdis + ysqdis);
		    m_lock();
		    if (dist < shortest) {
				closest = i;
				shortest = dist;
				}
			m_unlock();
		}
	}
}
