source: git/MP/MP/MP_PvmTransp.c @ 22b156

fieker-DuValspielwiese
Last change on this file since 22b156 was 341696, checked in by Hans Schönemann <hannes@…>, 15 years ago
Adding Id property to all files git-svn-id: file:///usr/local/Singular/svn/trunk@12231 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 13.0 KB
Line 
1/****************************************************************
2 *                                                                 
3 *                                                                 
4 *                    MP version 1.1.2:  Multi Protocol
5 *                    Kent State University, Kent, OH
6 *                 Authors:  S. Gray, N. Kajler, P. Wang
7 *          (C) 1993, 1994, 1995, 1996, 1997 All Rights Reserved
8 *
9 *                                 NOTICE
10 *
11 *  Permission to use, copy, modify, and distribute this software and
12 *  its documentation for non-commercial purposes and without fee is
13 *  hereby granted provided that the above copyright notice appear in all
14 *  copies and that both the copyright notice and this permission notice
15 *  appear in supporting documentation.
16 * 
17 *  Neither Kent State University nor the Authors make any representations
18 *  about the suitability of this software for any purpose.  The MP Library
19 *  is distributed in the hope that it will be useful, but is provided  "as
20 *  is" and without any warranty of any kind and without even the implied 
21 *  warranty of merchantability or fitness for a particular purpose.
22 *
23 *    IMPORTANT ADDITION: as of September 2006, MP is also licenced under GPL
24 *
25 *   IMPLEMENTATION FILE:  MP_PvmTransp.c
26 *
27 *      Public interface routines to the "pvm" transport device.
28 *      These include read, write, open, close, and get_status routines.
29 *      There are some support routines as well.
30
31 * Note:
32 *       mp_pvm_read() anticipates PvmNoData error from pvm_recv().
33 *       PVM defaults to printing an error message when encounter such
34 *       error. To disable printing of error message, use the following:
35 *
36 *              pvm_setopt(PvmAutoErr, 0);
37 *
38 *       See "PVM 3 User'sGuide and Reference Manual" for detail.
39 *
40 *  Change Log:
41 *       1/25/96   sgray - formal creation of PVM device
42 *       1/30/96   sgray - added (status == PvmNoBuf) test in mp_pvm_read().
43 *                         The original code worked in the past because all
44 *                         the test programs sent data from the master to
45 *                         the slave using pvm_send/recv().  This "primed
46 *                         the pump" I suppose.  Without the test above and
47 *                         sending only MP data, I kept getting a PvmNoBuf
48 *                         error message from the initial attempt to unpack
49 *                         the data. 
50 *       3/3/96    sgray - moved call to pvm_init_transport() inside
51 *                         pvm_open_transport() and removed the init
52 *                         routine from the pvm_ops struct.
53 *
54 ****************************************************************************/
55
56#ifndef lint
57static char vcid[] = "@(#) $Id$";
58#endif /* lint */
59
60#include "MP.h"
61#ifdef MP_HAVE_PVM
62
63/*
64 * We don't make this file with the library.  Instead, users must include
65 * MP_PvmTransp.h, which includes this file and they get compiled and linked
66 * with the MP library together.  This is to avoid having to add in the PVM
67 * library even when it isn't being used.
68 */
69
70#define log_msg_len 128
71static char log_msg[log_msg_len];  /* for event logging */
72
73
74long mp_pvm_write();
75long mp_pvm_read();
76MP_Boolean_t mp_pvm_get_status();
77MP_Status_t mp_pvm_flush();
78MP_Status_t mp_pvm_init_transport();
79MP_Status_t mp_pvm_open_connection();
80MP_Status_t mp_pvm_close_connection();
81
82
83MP_TranspOps_t pvm_ops = {
84  mp_pvm_write,
85  mp_pvm_read,
86  mp_pvm_flush,
87  mp_pvm_get_status,
88  mp_pvm_open_connection,
89  mp_pvm_close_connection,
90  mp_pvm_close_connection
91};
92
93MP_Status_t
94#ifdef __STDC__
95mp_pvm_flush(MP_Link_pt link)
96#else
97mp_pvm_flush(link)
98    MP_Link_pt link;
99#endif
100{
101#ifdef MP_DEBUG
102    fprintf(stderr, "mp_pvm_flush: entering\n");
103    fflush(stderr);
104#endif
105#ifdef MP_DEBUG
106    fprintf(stderr, "mp_pvm_flush: exiting \n");
107    fflush(stderr);
108#endif
109  return MP_ClearError(link);
110}
111
112
113/*********************************************************
114 * mp_pvm_write(link, where, len)
115 * return: 0 if success, -1 if failure.
116 * arguments: link - can be anything, even NULL.
117 *            where - pointer to data to be packed.
118 *            len - number of bytes to be packed.
119 *********************************************************/
120#ifdef __STDC__
121long mp_pvm_write(MP_Link_pt link, char *where, unsigned long len)
122#else
123long mp_pvm_write(link, where, len)
124    MP_Link_pt link;
125    char      *where;
126    unsigned long len;
127#endif
128{
129    int status;
130    MP_PVM_t  *pvm_rec = (MP_PVM_t *)(link->transp.private1);
131
132#ifdef MP_DEBUG
133    fprintf(stderr, "mp_pvm_write: entering, writing %d bytes\n", len); 
134    fflush(stderr);
135#endif
136    /*
137     * Actually I think the test here should be for the link_send_mode.
138     * We really only want to do all three steps (init, pack, send) here
139     * if the user has requested that the link_send_mode is MP_Whole_Tree.
140     * Also, we want to be sure that the user knows that if we are doing the
141     * send here, s/he shouldn't be doing it in the program.  A cleaner
142     * approach is to always do the send here, but provides the programmer with
143     * less flexibility.  BTW: the body of the if could probably be replaced by
144     * a single call using pvm_psend().  But note also that life is much more
145     * complicated if the user is using pvm_mcast() or pvm_bcast().
146     */
147    if (pvm_rec->send_mode == PvmDataInPlace) {
148        pvm_initsend(PvmDataInPlace);
149        status = pvm_pkbyte(where, len, 1);
150        pvm_send(pvm_rec->tids[0], 0);
151    }
152    else
153        status = pvm_pkbyte(where, len, 1);
154#ifdef MP_DEBUG
155    fprintf(stderr, "mp_pvm_write: exiting, status = %d\n", status); 
156    fflush(stderr);
157#endif
158    if (status < 0) 
159        return(-1);
160    else 
161        return(len);
162}
163
164
165
166/**************************************************************************
167 * mp_pvm_read(link, where, len)
168 * return: number of bytes actually unpacked. -1 if failure.
169 * arguments: link - can be anything, even NULL.
170 *            where - pointer to memory location to store unpacked data.
171 *            len - number of bytes to be packed.
172 **************************************************************************/
173#ifdef __STDC__
174long mp_pvm_read(MP_Link_pt link, char *where, unsigned long len)
175#else
176long mp_pvm_read(link, where, len)
177    MP_Link_pt link;
178    char *where;
179    unsigned long len;
180#endif
181{
182    unsigned long status, bufid, actual_len;
183    int msgtag,  lenrecv, tid;
184#ifdef MP_DEBUG
185    fprintf(stderr, "mp_pvm_read: entering - want to read %d bytes\n", len); 
186    fflush(stderr);
187#endif
188    actual_len = len;
189
190    status = pvm_upkbyte(where, actual_len, 1);
191
192    if (status == PvmNoData || status == PvmNoBuf) {
193        bufid = pvm_recv(-1, -1);
194        if (bufid < 0) 
195            return(-1);
196        status = pvm_bufinfo(bufid, &lenrecv, &msgtag, &tid);
197        actual_len = (len < lenrecv) ? len : lenrecv;
198        status = pvm_upkbyte(where, actual_len, 1);
199    }
200
201#ifdef MP_DEBUG
202    fprintf(stderr, "mp_pvm_read: exiting, read %d bytes, status = %d\n", 
203            actual_len, status); 
204    fflush(stderr);
205#endif
206 
207    if (status < 0) return(-1);
208    return(actual_len);
209}
210
211
212 
213/***********************************************************************
214 * FUNCTION:  mp_pvm_init_transport
215 * INPUT:     link - pointer to the link structure for this connection
216 * OUTPUT:    Success:  MP_Success and link structure initialized for the
217 *                      pvm connection. 
218 *            Failure:  MP_Failure
219 * OPERATION: If there are no problems, allocate a pvm structure and
220 *            attach it to the private pointer inside link.
221 ***********************************************************************/
222#ifdef __STDC__
223MP_Status_t mp_pvm_init_transport(MP_Link_pt link)
224#else
225MP_Status_t mp_pvm_init_transport(link)
226  MP_Link_pt link;
227#endif
228{
229#ifdef MP_DEBUG
230    fprintf(stderr, "mp_pvm_init_transport: entering\n");
231    fflush(stderr);
232#endif
233
234    TEST_LINK_NULL(link);
235    link->transp.transp_dev = MP_PvmTransportDev;
236    link->transp.transp_ops = &pvm_ops;
237    link->transp.private1 = (char *)IMP_MemAllocFnc(sizeof(MP_PVM_t));
238    TEST_MEM_ALLOC_ERROR(link, link->transp.private1);
239
240#ifdef MP_DEBUG
241    fprintf(stderr, "mp_pvm_init_transport: exiting\n"); 
242    fflush(stderr);
243#endif
244    RETURN_OK(link);
245}
246
247
248
249/***********************************************************************
250 * FUNCTION:  mp_pvm_close_connection
251 * INPUT:     link  - pointer to the link structure for this connection
252 * OUTPUT:    Success:  MP_Success
253 *                      Release the pvm structure pointed to by private1.
254 *            Failure:  MP_Failure
255 * OPERATION:
256 ***********************************************************************/
257#ifdef __STDC__
258MP_Status_t mp_pvm_close_connection(MP_Link_pt link)
259#else
260MP_Status_t mp_pvm_close_connection(link)
261  MP_Link_pt link;
262#endif
263{ 
264    MP_PVM_t  *pvm_rec;
265
266#ifdef MP_DEBUG
267    fprintf(stderr, "mp_pvm_close_connection: entering\n");
268    fflush(stderr);
269#endif
270
271    TEST_LINK_NULL(link);
272    if (link->transp.private1 == NULL) 
273        return(MP_SetError(link, MP_NullTransport));
274    pvm_rec = (MP_PVM_t *)(link->transp.private1);
275    IMP_MemFreeFnc(pvm_rec->myhost, MP_HOST_NAME_LEN);
276    /*
277     * IMP_RawMemFreeFnc((*(MP_PVM_t *)(link->transp.private1)).tids);
278     */
279    IMP_MemFreeFnc(pvm_rec->tids, pvm_rec->ntids * sizeof(int));
280    IMP_MemFreeFnc(pvm_rec, sizeof(MP_PVM_t));
281    link->transp.private1 = NULL;
282
283#ifdef MP_DEBUG
284    fprintf(stderr, "mp_pvm_close_connection: exiting\n");
285    fflush(stderr);
286#endif
287    RETURN_OK(link);
288}
289
290
291/***********************************************************************
292 * FUNCTION:  mp_pvm_open_connection
293 * INPUT:     link - pointer to link structure for this connection
294 *            argc - number of arguments in argv
295 *            argv - arguments as strings
296 * OUTPUT:    Success:  MP_Success
297 *                      link established as a pvm connection
298 *            Failure:  MP_Failure
299 * OPERATION: Determine the pvm mode we are using and attempt to
300 *            establish a connection accordingly.  We could fail
301 *            for any of a number of reasons.  Bad hostname, bad
302 *            port number, missing arguments....
303 ***********************************************************************/
304#ifdef __STDC__
305MP_Status_t mp_pvm_open_connection(MP_Link_pt link, int argc, char **argv)
306#else
307MP_Status_t mp_pvm_open_connection(link, argc, argv)
308    MP_Link_pt link;
309    int argc;
310    char **argv;
311#endif
312{
313    MP_PVM_t  *pvm_rec = NULL;
314
315#ifdef MP_DEBUG
316    fprintf(stderr, "mp_pvm_open_connection: entering\n");
317    fflush(stderr);
318#endif
319
320    TEST_LINK_NULL(link);
321    if (mp_pvm_init_transport(link) != MP_Success) 
322        return MP_Failure;
323    pvm_rec = (MP_PVM_t *)(link->transp.private1);
324    pvm_rec->myhost = (char *) IMP_MemAllocFnc(MP_HOST_NAME_LEN);
325    TEST_MEM_ALLOC_ERROR(link, pvm_rec->myhost);
326    if (gethostname(pvm_rec->myhost, MP_HOST_NAME_LEN) == -1) {
327        IMP_MemFreeFnc(pvm_rec->myhost, MP_HOST_NAME_LEN);
328        pvm_rec->myhost = NULL;
329    }
330    pvm_rec->nhosts = 0;
331    pvm_rec->ntids = 0;
332    pvm_rec->tids = NULL;
333    pvm_rec->tag = -1;
334    pvm_rec->send_mode = PvmDataRaw;
335#ifdef MP_DEBUG
336    fprintf(stderr, "mp_pvm_open_connection: exiting\n"); 
337    fflush(stderr);
338#endif
339    RETURN_OK(link);
340}
341
342
343#ifdef __STDC__
344MP_Boolean_t mp_pvm_get_status(MP_Link_pt link, MP_LinkStatus_t status_to_check)
345#else
346MP_Boolean_t mp_pvm_get_status(link, status_to_check)
347  MP_Link_pt      link;
348  MP_LinkStatus_t status_to_check;
349#endif
350{   
351
352    TEST_LINK_NULL(link);
353
354#ifdef MP_DEBUG
355    printf("mp_pvm_get_status: entering for link %d\n", link->link_id);
356#endif
357
358    switch (status_to_check) {
359    case MP_LinkReadyReading:
360        return (MP_Boolean_t) (pvm_probe(-1, -1));
361    case MP_LinkReadyWriting:
362        return MP_TRUE;
363    default:
364        sprintf(log_msg,"mp_pvm_get_status: illegal option %d",
365                status_to_check);
366        MP_LogEvent(link, MP_ERROR_EVENT, log_msg);
367        return MP_FALSE;
368    }
369#ifdef MP_DEBUG
370    printf("mp_pvm_get_status: exiting\n");
371#endif
372}
373
374
375
376#ifdef __STDC__
377MP_Status_t MP_PvmSetTids(MP_Link_pt link,
378                          int nhosts,
379                          int *tids)
380#else
381MP_Status_t MP_PvmSetTids(link, nhosts, tids)
382    MP_Link_pt link;
383    int nhosts;
384    int *tids;
385#endif
386{
387    int i;
388    MP_PVM_t  *pvm_rec = NULL;
389
390    TEST_LINK_NULL(link);
391    pvm_rec = (MP_PVM_t *)(link->transp.private1);
392
393    if (nhosts < 0) 
394        return MP_Failure;
395    pvm_rec->nhosts = nhosts;
396    pvm_rec->tids = (int *)IMP_MemAllocFnc(nhosts * sizeof(int));
397    TEST_MEM_ALLOC_ERROR(link, pvm_rec->tids);
398    for (i = 0; i < nhosts; i++)
399        pvm_rec->tids[i] = tids[0];
400
401    return(MP_Success);
402}
403
404
405
406
407#ifdef __STDC__
408MP_Status_t MP_PvmSetSendMode( MP_Link_pt link, int mode)
409#else
410MP_Status_t MP_PvmSetSendMode(link, mode)
411    MP_Link_pt link;
412    int mode;
413#endif
414{
415    MP_PVM_t  *pvm_rec = NULL;
416
417    TEST_LINK_NULL(link);
418    pvm_rec = (MP_PVM_t *)(link->transp.private1);
419    if (mode != PvmDataRaw && mode != PvmDataInPlace && mode != PvmDataDefault)
420        return(MP_Failure);
421
422    pvm_rec->send_mode = mode;
423    return(MP_Success);
424}
425
426#endif /* MP_HAVE_PVM */
Note: See TracBrowser for help on using the repository browser.