1 /*****************************************************************************/
2 /* "NetPIPE" -- Network Protocol Independent Performance Evaluator.          */
3 /* Copyright 1997, 1998 Iowa State University Research Foundation, Inc.      */
4 /*                                                                           */
5 /* This program is free software; you can redistribute it and/or modify      */
6 /* it under the terms of the GNU General Public License as published by      */
7 /* the Free Software Foundation.  You should have received a copy of the     */
8 /* GNU General Public License along with this program; if not, write to the  */
9 /* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.   */
10 /*                                                                           */
11 /*     * PVM.c              ---- PVM calls source                            */
12 /*****************************************************************************/
13 #include    "netpipe.h"
14 #include    <pvm3.h>
15 
16 /**********************************************************************/
17 /* Set up the communcations system.                                   */
18 /*    In pvm, this means to join the parallel machine                 */
19 /**********************************************************************/
Setup(ArgStruct * p)20 int Setup(ArgStruct * p)
21 {
22 	p->prot.mytid = pvm_mytid();
23 #ifdef DEBUG
24 	printf("My task id is %d \n", p->prot.mytid);
25 #endif
26 }
27 
28 /**********************************************************************/
29 /* Establish a link with the other processor                          */
30 /*    In pvm, this means to send a simple message, but to keep the    */
31 /*    communication line open.  Since the assumption is that we are   */
32 /*    starting it by hand on the other machine, we don't know what    */
33 /*    the other task id is.                                           */
34 /**********************************************************************/
Establish(ArgStruct * p)35 int Establish(ArgStruct * p)
36 {
37 	/* Task information for the entire parallel machine (if trans) */
38 	int tasks_status;
39 	struct pvmtaskinfo *taskp;
40 	int ntasks;
41 
42 	/* Received buffer (if receiver)  */
43 	int buffer_id;
44 
45 	/*
46 	   If we are the transmitting side, go find the other one and send
47 	   it a message containing our tid. If we are the receiving side,
48 	   just wait for a message.
49 	 */
50 	if (p->tr) {
51 #ifdef DEBUG
52 		printf("this is the transmitter\n");
53 #endif
54 		tasks_status = pvm_tasks(0, &ntasks, &taskp);
55 		if (ntasks != 2) {
56 			printf
57 			    ("Error, too many processes in parallel machine \n");
58 			printf("Start a clean machine.  n=%d\n", ntasks);
59 			exit(-1);
60 		}
61 
62 		/* Since there are two tasks, one is ours the other is the receiver */
63 		p->prot.othertid = -1;
64 		if (taskp[0].ti_tid == p->prot.mytid) {
65 			p->prot.othertid = taskp[1].ti_tid;
66 		}
67 		if (taskp[1].ti_tid == p->prot.mytid) {
68 			p->prot.othertid = taskp[0].ti_tid;
69 		}
70 		if (p->prot.othertid == -1) {
71 			printf("Error, cannot find other (receiving) task \n");
72 			printf("Id's:  %d %d  \n", taskp[0].ti_tid,
73 			       taskp[1].ti_tid);
74 		}
75 
76 		/* Send the receiver a message.  Tell pvm to keep the channel open */
77 
78 #ifdef DEBUG
79 		printf("The receiver tid is %d \n", p->prot.othertid);
80 #endif
81 		pvm_setopt(PvmRoute, PvmRouteDirect);
82 		pvm_initsend(PVMDATA);
83 		pvm_pkint(&p->prot.mytid, 1, 1);
84 		pvm_send(p->prot.othertid, 1);
85 	} else {
86 #ifdef DEBUG
87 		printf("This is the receiver \n");
88 #endif
89 
90 		/* Receive any message from any task */
91 		buffer_id = pvm_recv(-1, -1);
92 
93 		if (buffer_id < 0) {
94 			printf("Error on receive in receiver\n");
95 			exit(-1);
96 		}
97 		pvm_upkint(&p->prot.othertid, 1, 1);
98 	}
99 }
100 
101 /**********************************************************************/
102 /* Prepare to receive                                                 */
103 /*    In pvm, you cannot set up a reception buffer ahead of time      */
104 /**********************************************************************/
PrepareToReceive(ArgStruct * p)105 void PrepareToReceive(ArgStruct * p)
106 {
107 }
108 
109 /**********************************************************************/
110 /* Synchronize                                                        */
111 /*     In pvm, this is not necessary                                  */
112 /**********************************************************************/
Sync(ArgStruct * p)113 void Sync(ArgStruct * p)
114 {
115 }
116 
117 /**********************************************************************/
118 /* Send a buffer full of information                                  */
119 /*    In pvm, we use pvm_pkbyte and then send it.                     */
120 /**********************************************************************/
SendData(ArgStruct * p)121 void SendData(ArgStruct * p)
122 {
123 #ifdef DEBUG
124 	printf(" In send \n");
125 #endif
126 	pvm_initsend(PVMDATA);
127 	pvm_pkbyte(p->buff, p->bufflen, 1);
128 	pvm_send(p->prot.othertid, 1);
129 #ifdef DEBUG
130 	printf(" message sent.  Size=%d\n", p->bufflen);
131 #endif
132 }
133 
134 /**********************************************************************/
135 /* Receive a buffer full of information                               */
136 /**********************************************************************/
RecvData(ArgStruct * p)137 void RecvData(ArgStruct * p)
138 {
139 #ifdef DEBUG
140 	printf(" In receive \n");
141 #endif
142 	pvm_recv(-1, -1);
143 	pvm_upkbyte(p->buff, p->bufflen, 1);
144 #ifdef DEBUG
145 	printf(" message received .  Size=%d \n", p->bufflen);
146 #endif
147 }
148 
149 /**********************************************************************/
150 /* Send elapsed time to the other process                             */
151 /**********************************************************************/
SendTime(ArgStruct * p,double * t)152 void SendTime(ArgStruct * p, double *t)
153 {
154 	pvm_initsend(PVMDATA);
155 	pvm_pkdouble(t, 1, 1);
156 	pvm_send(p->prot.othertid, 1);
157 }
158 
159 /**********************************************************************/
160 /* Receive elapsed time from the other process                        */
161 /**********************************************************************/
RecvTime(ArgStruct * p,double * t)162 void RecvTime(ArgStruct * p, double *t)
163 {
164 	pvm_recv(-1, -1);
165 	pvm_upkdouble(t, 1, 1);
166 }
167 
168 /**********************************************************************/
169 /* Send repeat count to the other process                             */
170 /**********************************************************************/
SendRepeat(ArgStruct * p,int rpt)171 void SendRepeat(ArgStruct * p, int rpt)
172 {
173 	pvm_initsend(PVMDATA);
174 	pvm_pkint(&rpt, 1, 1);
175 	pvm_send(p->prot.othertid, 1);
176 }
177 
178 /**********************************************************************/
179 /* Receiver repeat count from other process                           */
180 /**********************************************************************/
RecvRepeat(ArgStruct * p,int * rpt)181 void RecvRepeat(ArgStruct * p, int *rpt)
182 {
183 	pvm_recv(-1, -1);
184 	pvm_upkint(rpt, 1, 1);
185 }
186 
187 /**********************************************************************/
188 /* Close down the connection.
189 /**********************************************************************/
CleanUp(ArgStruct * p)190 int CleanUp(ArgStruct * p)
191 {
192 }
193