home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
listings
/
v_08_07
/
8n07107a
< prev
next >
Wrap
Text File
|
1990-06-19
|
7KB
|
209 lines
/*
*
* findroot.c : A parallel root finding program
* author: Victor R. Volkman
*
* Based on a problem suggested by: Professor Dave Poplawski
* Department of Computer Science
* Michigan Technological University
* Houghton, Michigan 49931
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dvapi.h"
#include "dvapi2.h"
#include "monitor.h"
#include "monitor.fd"
#ifndef MAKEFD
#include "findroot.fd"
#endif
double f();
static double global_x0, global_x1, global_y0, global_y1;
#define STACKSIZE 1000
int master[NUMPRC];
DESQ_HAN glob_win_han;
static MONITOR *root_mon;
/* The main() program serves a passive role in the root finding
process. The main() program activates node-0 which assumes
temporary control over the other subprocesses. Note that
the lower and upper bounds (global_x0 and global_x1 must be
set prior to activating node-0. */
main()
{
int i;
int version;
DESQ_HAN task_han;
char stacks[NUMPRC][STACKSIZE];
char node_str[40];
double dummy;
global_x0 = 0.0; /* Lower Limit */
global_x1 = 1.0; /* Upper Limit */
version = api_init();
if (version < REQ_DESQVIEW) {
printf("This program requires DESQView %d.%02d or later.\n",
REQ_DESQVIEW >> 8, REQ_DESQVIEW & 0xFF);
exit(1);
}
/* set minimum API function level */
api_level(REQ_DESQVIEW);
if (NUMPRC % 2 != 0) {
printf("NUMPRC is %d, please use an even number of nodes\n",NUMPRC);
exit(-1);
}
glob_win_han = win_new(GLOB_NAME,strlen(GLOB_NAME),
GLOB_HEIGHT,GLOB_WIDTH);
win_move(glob_win_han,0,0); /* Set screen row=0, col=0 */
win_logattr(glob_win_han,TRUE); /* Use logical screen attributes */
win_attr(glob_win_han,1); /* Display text in default color */
win_frame(glob_win_han,FALSE); /* Don't display a box border */
win_unhide(glob_win_han); /* Mark this window as visible */
win_top(glob_win_han); /* Bring to top & redraw window */
win_printf(glob_win_han,
"Root finder activated with %d subprocesses and resolution %f...\n",
NUMPRC, EPSILON);
global_y0 = f(global_x0); /* Establish initial values */
global_y1 = f(global_x1);
open_monitor("rootfinder",&root_mon);
sendv(root_mon,0.0,MASTER); /* Allow MASTER signal to be claimed */
for (i=0; i<NUMPRC; i++) {
master[i] = 0;
task_han = tsk_new(task_findroot, stacks[i], STACKSIZE, "", 0, 0, 0);
win_printf(glob_win_han,"spawned task %d\n",i);
win_top(glob_win_han);
sprintf(node_str,"%d",i);
mal_write(mal_of(task_han), node_str, sizeof(node_str));
}
recvl(root_mon,&dummy,TERMINATE);
win_printf(glob_win_han,"Lower limit X0 is %f,
f(X0) is %f\n",global_x0,global_y0);
win_printf(glob_win_han,"Upper limit X1 is %f, f(X1) is %f\n",
global_x1,global_y1);
win_printf(glob_win_han,"Master status %d, %d, %d, %d\n",
master[0],master[1],master[2],master[3]);
win_printf(glob_win_han,"Press any key to continue...\n");
win_top(glob_win_han);
close_monitor(&root_mon);
getch();
}
task_findroot(void)
{
char *msg_buffer;
char title[30];
DESQ_HAN my_mal_han;
DESQ_HAN win_han;
double interv, y0, y1, dummy;
int lastnode, indx;
int msg_len;
int node;
int term;
my_mal_han = mal_me(); /* Find out and read mail from parent */
mal_read(my_mal_han,&msg_buffer,&msg_len);
sscanf(msg_buffer,"%d",&node);
sprintf(title,"Node %03d",node);
win_han = win_new(title,strlen(title),3,38+(node<4)*40);
win_move(win_han,7+(node%4)*5,1+(node>3)*40);
win_logattr(win_han,1); /* Use logical screen attributes */
win_attr(win_han,1); /* Display text in default color */
win_unhide(win_han); /* Mark this window as visible */
win_top(win_han); /* Bring to top & redraw window */
lastnode = (node==(NUMPRC-1));
do
{
interv = (global_x1-global_x0)/(NUMPRC);
y1 = f(global_x0+interv*(node+1));
/* First, all even nodes send & odd nodes receive, via recv semafore */
if (node % 2 == 0)
sendv(root_mon,y1,node+1);
else /* I'm an odd node */
recvl(root_mon,&y0,node);
/* Second, all odd nodes send & even nodes receive, via recv semafore */
/* Node 0 may not receive, and the lastnode may not send */
if (!lastnode)
{
if (node % 2 == 1)
sendv(root_mon,y1,node+1);
else if (node) /* I'm an even node > 0 */
recvl(root_mon,&y0, node);
else /* I'm node 0, so my left value is already computed */
y0 = global_y0;
}
win_printf(win_han,"y0 = %f, y1 = %f\n",y0,y1); win_top(win_han);
/* Determine which process will be the controller */
if ( (y1*y0) < 0.0)
{
/* MASTER status must be inherited from the ex-controller */
win_fprintf(win_han,"Node %d waiting for MASTER status\n",node);
win_top(win_han);
recvl(root_mon,&dummy,MASTER);
master[node]++;
win_printf(win_han,"Node %d has received MASTER status\n",node);
win_top(win_han);
/* compute new boundary conditions */
global_x0 += interv * node;
global_y0 = y0;
if (!lastnode)
global_x1 = global_x0 + interv;
global_y1 = y1;
term = (interv < EPSILON);
/* synchronize waiting processes below */
for (indx=0; indx<NUMPRC; indx++)
if (indx!=node)
sendv(root_mon, (double)term, indx+NUMPRC);
/* Relinquish MASTER status to the next controller or TERMINATE */
if (term)
sendv(root_mon,0.0,TERMINATE);
else
sendv(root_mon,0.0,MASTER);
}
else /* synchronize */
{
win_printf(win_han,"Node %d suspended until notified \n",node);
win_top(win_han);
recvl(root_mon,&dummy,node+NUMPRC);
term = (int) dummy;
win_printf(win_han,"Node %d restarted by the MASTER \n",node);
win_top(win_han);
}
}
while (!term);
win_printf(win_han,"Leaving...\n");
tsk_free(tsk_me()); /* De-allocate DESQview resources */
}
double f(x)
float x;
{
return(x*x*x - x*x + x - 0.5);
}