~ubuntu-branches/ubuntu/karmic/scilab/karmic

« back to all changes in this revision

Viewing changes to pvm3/pvmgs/pvmgsu_core.c

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2002-03-21 16:57:43 UTC
  • Revision ID: james.westby@ubuntu.com-20020321165743-e9mv12c1tb1plztg
Tags: upstream-2.6
ImportĀ upstreamĀ versionĀ 2.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
static char rcsid[] =
 
3
        "$Id: pvmgsu_core.c,v 1.14 1997/10/22 22:14:17 pvmsrc Exp $";
 
4
 
 
5
/*
 
6
 *         PVM version 3.4:  Parallel Virtual Machine System
 
7
 *               University of Tennessee, Knoxville TN.
 
8
 *           Oak Ridge National Laboratory, Oak Ridge TN.
 
9
 *                   Emory University, Atlanta GA.
 
10
 *      Authors:  J. J. Dongarra, G. E. Fagg, M. Fischer
 
11
 *          G. A. Geist, J. A. Kohl, R. J. Manchek, P. Mucci,
 
12
 *         P. M. Papadopoulos, S. L. Scott, and V. S. Sunderam
 
13
 *                   (C) 1997 All Rights Reserved
 
14
 *
 
15
 *                              NOTICE
 
16
 *
 
17
 * Permission to use, copy, modify, and distribute this software and
 
18
 * its documentation for any purpose and without fee is hereby granted
 
19
 * provided that the above copyright notice appear in all copies and
 
20
 * that both the copyright notice and this permission notice appear in
 
21
 * supporting documentation.
 
22
 *
 
23
 * Neither the Institutions (Emory University, Oak Ridge National
 
24
 * Laboratory, and University of Tennessee) nor the Authors make any
 
25
 * representations about the suitability of this software for any
 
26
 * purpose.  This software is provided ``as is'' without express or
 
27
 * implied warranty.
 
28
 *
 
29
 * PVM version 3 was funded in part by the U.S. Department of Energy,
 
30
 * the National Science Foundation and the State of Tennessee.
 
31
 */
 
32
 
 
33
/*
 
34
*       pvmgsu_core.c - Core group library routines  
 
35
* Revision 1.4  1994/11/07  21:09:38  manchek
 
36
* include stdlib if available.
 
37
* function prototypes for SCO.
 
38
* remove spurious breaks after returns
 
39
*
 
40
* Revision 1.3  1994/10/15  21:57:34  manchek
 
41
* disable output collection and tracing while spawning group server
 
42
*
 
43
* Revision 1.2  1994/10/15  18:53:48  manchek
 
44
* added tids to BCAST1 trace message
 
45
*
 
46
*
 
47
*       05 Mar 1993     Adam Beguelin adamb@cs.cmu.edu
 
48
*       05 Mar 1993     Fixed malloc() in pvm_bcast()
 
49
*       05 Mar 1993     pvm_barrier now returns 0 or an error
 
50
*       20 Mar 1993     pvm_bcast does not send to itself, beguelin
 
51
*      01 Jun 1993     Fixed saving and restoring of mbufs, beguelin
 
52
*       30 Nov 1993     Fixed gs_getgstid() to check spawn return correctly,
 
53
*                      manchek
 
54
*       8 Mar 1994     optimized gs_getgstid(). 
 
55
*       8 Mar 1994     Added reduce & assoc routines. Donato & P.Papadopoulos
 
56
*      24 Apr 1994     Added scatter, gather, gs_get_datasize routines. Donato
 
57
*      15 Jun 1995     Add static groups, clear local tables if tid changes
 
58
 
59
*/
 
60
        
 
61
        
 
62
#ifdef HASSTDLIB
 
63
#include <stdlib.h>
 
64
#endif
 
65
 
 
66
#include <stdio.h>
 
67
#include <pvm3.h>
 
68
#include "pvmalloc.h"
 
69
#include "bfunc.h"
 
70
#include "lpvm.h"
 
71
#include <pvmtev.h>
 
72
#include "tevmac.h"
 
73
#include "pvmgsd.h"
 
74
#include "pvmproto.h"
 
75
 
 
76
#if defined(IMA_PGON)
 
77
#include <nx.h>
 
78
#endif
 
79
 
 
80
int gstid = -1;
 
81
static int myoldtid = -1;
 
82
 
 
83
extern int pvm_errno;
 
84
extern int pvmmytid;
 
85
extern int pvmtoplvl;
 
86
extern struct Pvmtracer pvmtrc;
 
87
 
 
88
/* Declarations for static group information                               */
 
89
        
 
90
static GROUP_LIST sgroup_list[HASHSIZE];
 
91
static int ngroups = -1;
 
92
/* ================ gs_getgstid() ====================================     */
 
93
/* int info = getgstid()                                                   */
 
94
/*   gs_getgstid returns the tid of the group server, starts the server    */
 
95
/*   if it is not running                                                  */
 
96
 
 
97
int
 
98
gs_getgstid()
 
99
{
 
100
        int info;
 
101
        int mytid;
 
102
        int otid; 
 
103
        int rbuf;
 
104
        int srbuf;
 
105
        int ttid;
 
106
 
 
107
        mytid = pvm_mytid();
 
108
        
 
109
        if (gstid >= 0 && mytid == myoldtid) 
 
110
                return (gstid);
 
111
        
 
112
        srbuf = pvm_setrbuf(0);
 
113
 
 
114
        if ( pvm_recvinfo(GSNAME, 0, PvmMboxDefault) == PvmNotFound )
 
115
        {
 
116
                /* Don't trace output from the spawned group server */
 
117
 
 
118
                otid = pvm_setopt(PvmOutputTid, 0);
 
119
                ttid = pvm_setopt(PvmTraceTid, 0);
 
120
 
 
121
                info = pvm_spawn("pvmgs", (char **)0, PvmMppFront,
 
122
                                (char *)0, 1, &gstid);
 
123
 
 
124
                pvm_setopt(PvmOutputTid, otid);
 
125
                pvm_setopt(PvmTraceTid, ttid);
 
126
 
 
127
                if (info != 1) 
 
128
                {
 
129
                        if (info == 0 && gstid < 0) 
 
130
                        {
 
131
                                pvm_errno = gstid;
 
132
                                pvm_perror("gs_getgstid() failed to start group server");
 
133
                        }
 
134
                        return pvm_errno;
 
135
                }
 
136
 
 
137
                while( pvm_recvinfo(GSNAME, 0, PvmMboxDefault) == PvmNotFound )
 
138
                        /* wait for it to register */ ;
 
139
        }
 
140
        
 
141
        /* unpack the group server tid */ 
 
142
        pvm_upkint(&gstid,1,1);
 
143
        pvm_setrbuf(srbuf);
 
144
        
 
145
        /* initialize storage for static group information */
 
146
 
 
147
        if (myoldtid == -1)
 
148
        {
 
149
                ngroups = 0;
 
150
                gs_hash_init(sgroup_list);
 
151
        }
 
152
        else
 
153
                gs_hash_clear(sgroup_list, &ngroups, HASHSIZE);
 
154
 
 
155
        myoldtid = mytid;
 
156
 
 
157
        return(gstid);
 
158
}
 
159
 
 
160
/* ================ pvm_joingroup()===================================     */
 
161
/*
 
162
        int inum = pvm_joingroup(char* group)
 
163
 
 
164
        Adds the calling tid to the named group and returns its instance number.
 
165
        Always adds the task in the first available slot such that
 
166
        if one task leaves a group and another later joins, then the later
 
167
        task will get the instance number freed by the earlier task.
 
168
        This allows users to keep a contiguous block of instance numbers [0,p-1].
 
169
*/
 
170
 
 
171
int
 
172
pvm_joingroup(group)
 
173
char *group;
 
174
{
 
175
        int gid;
 
176
        int x;
 
177
 
 
178
        TEV_DECLS;
 
179
        
 
180
        BGN_TRACE( TEV_JOINGROUP, group, 0, (int *) NULL );
 
181
 
 
182
        int_query_server(group, JOIN, "pvm_joingroup", &gid, 0);
 
183
 
 
184
        END_TRACE( TEV_JOINGROUP, TEV_DID_CC, &gid );
 
185
 
 
186
        if (gid < 0)
 
187
                pvm_errno = gid;
 
188
 
 
189
        return gid;
 
190
}
 
191
        
 
192
/* ================ pvm_lvgroup()===================================     */
 
193
/*
 
194
        int info = pvm_lvgroup(char* group)
 
195
        Removes the calling tid from the named group.
 
196
        Returns only after getting confirmation from server.
 
197
        This allows users to coordinate leaving and joining.
 
198
*/
 
199
        
 
200
int
 
201
pvm_lvgroup(group)
 
202
char *group;
 
203
{
 
204
        int rc;
 
205
        int x; 
 
206
 
 
207
        GROUP_STRUCT_PTR sgroup;
 
208
 
 
209
        TEV_DECLS;
 
210
        
 
211
        BGN_TRACE( TEV_LVGROUP, group, 0, (int *) NULL );
 
212
 
 
213
        /* delete any statically held group information */
 
214
        gs_delete_group(group, sgroup_list, &ngroups); 
 
215
 
 
216
        int_query_server(group, LEAVE, "pvm_lvgroup", &rc, 0);
 
217
 
 
218
        END_TRACE( TEV_LVGROUP, TEV_DID_CC, &rc );
 
219
 
 
220
        if (rc < 0)
 
221
                pvm_errno = rc;
 
222
 
 
223
        return(rc);
 
224
}
 
225
        
 
226
 
 
227
        
 
228
/* ================ pvm_getinst() ====================================     */
 
229
/* int inum = pvm_getinst(char* group, int tid)
 
230
        Returns the instance number of the specified tid in the named group.
 
231
        Can be called by any task.
 
232
*/
 
233
int
 
234
pvm_getinst(group, tid)
 
235
char *group;
 
236
int tid;
 
237
{
 
238
        int foo;
 
239
        int inst;
 
240
        int x;
 
241
 
 
242
        TEV_DECLS;
 
243
        
 
244
        BGN_TRACE( TEV_GETINST, group, TEV_DID_GT, &tid );
 
245
 
 
246
        inst = gs_getinst(group, tid, sgroup_list, &ngroups, &foo); 
 
247
 
 
248
        if (inst < 0)    /* didn't find the info in local memory */ 
 
249
                int_query_server(group, GETINST, "pvm_getinst", &inst, tid);
 
250
 
 
251
        END_TRACE( TEV_GETINST, TEV_DID_GI, &inst );
 
252
 
 
253
        if (inst < 0)
 
254
                pvm_errno = inst;
 
255
 
 
256
        return(inst);
 
257
}
 
258
        
 
259
/* ================ pvm_gettid() =====================================     */
 
260
/*
 
261
int tid = pvm_gettid(char * group, int inum)
 
262
        Returns the tid of the task defined by the group/inum pair.
 
263
        Can be called by any task.
 
264
*/
 
265
int
 
266
pvm_gettid(group, inst)
 
267
char *group;
 
268
int inst;
 
269
{
 
270
        int foo;
 
271
        int tid;
 
272
        int x;
 
273
 
 
274
        TEV_DECLS;
 
275
        
 
276
        BGN_TRACE( TEV_GETTID, group, TEV_DID_GI, &inst );
 
277
 
 
278
        tid = gs_gettid(group, inst, sgroup_list, &ngroups, &foo); 
 
279
 
 
280
        if (tid < 0)     /* didn't find the info in local memory */
 
281
                int_query_server(group, GETTID, "pvm_gettid", &tid, inst);
 
282
 
 
283
        END_TRACE( TEV_GETTID, TEV_DID_GT, &tid );
 
284
 
 
285
        if (tid < 0)
 
286
                pvm_errno = tid;
 
287
 
 
288
        return(tid);
 
289
}
 
290
        
 
291
/* ================ pvm_gsize() ======================================     */
 
292
/*
 
293
        int gsize = pvm_gsize(char* group)
 
294
        Returns the present size of the named group.
 
295
*/
 
296
 
 
297
int
 
298
pvm_gsize(group)
 
299
char *group;
 
300
{
 
301
        int foo;
 
302
        int size;
 
303
        int x; 
 
304
 
 
305
        TEV_DECLS;
 
306
        
 
307
        BGN_TRACE( TEV_GSIZE, group, 0, (int *) NULL );
 
308
 
 
309
        size= gs_gsize(group, sgroup_list, &ngroups, &foo); 
 
310
 
 
311
        if (size < 0)    /* didn't find the info in local memory */
 
312
                int_query_server(group, GSIZE, "pvm_gsize", &size, 0);
 
313
 
 
314
        END_TRACE( TEV_GSIZE, TEV_DID_GS, &size );
 
315
 
 
316
        if (size < 0)
 
317
                pvm_errno = size;
 
318
        return(size);
 
319
}
 
320
        
 
321
/* ================ pvm_bcast() =====================================     */
 
322
/*
 
323
int info = pvm_bcast(char* group, int msgtag)
 
324
        Broadcast message to all members presently in the named group
 
325
        (excluding yourself if you are in the group).
 
326
        Calling tid need not be in the group.
 
327
        */
 
328
int
 
329
pvm_bcast(group, msgtag)
 
330
char *group;
 
331
int msgtag;
 
332
{
 
333
        int bailout=0;
 
334
        int cc;
 
335
        int i;
 
336
        int mytid;
 
337
        int ntids; 
 
338
        int rbuf;
 
339
        int sbuf;
 
340
        int *tids = (int *) NULL;
 
341
        int x; 
 
342
 
 
343
        TEV_DECLS;
 
344
        
 
345
        BGN_TRACE( TEV_BCAST, group, TEV_DID_MC, &msgtag );
 
346
 
 
347
        if ((cc = gs_get_tidlist(group, msgtag, &ntids, &tids, 0)) < 0)
 
348
                bailout = 1; 
 
349
 
 
350
        if ((mytid = pvm_mytid()) < 0 && ! bailout) 
 
351
        {
 
352
                pvm_perror("pvm_bcast");
 
353
                cc = PvmSysErr;
 
354
                bailout = 1;
 
355
        }
 
356
        
 
357
        /* if I'm the only one in the group */
 
358
        if ((ntids == 1) && (tids[0] == mytid ) && ! bailout) 
 
359
        {
 
360
                cc = PvmNoInst;
 
361
                bailout = 1;
 
362
        }
 
363
        
 
364
        if (! bailout ) 
 
365
        {
 
366
                for (i = 0; i < ntids; i++) /* remove my tid                   */
 
367
                {
 
368
                        if (tids[i] == mytid) 
 
369
                        {
 
370
                                /* move the last tid to here and shorten the list          */
 
371
                                tids[i] = tids[--ntids];
 
372
                                break;
 
373
                        }
 
374
                }
 
375
 
 
376
                if ((cc = pvm_mcast(tids, ntids, msgtag)) > 0)
 
377
                        cc = 0;
 
378
        }
 
379
 
 
380
        if (cc < 0)
 
381
                pvm_errno = cc;
 
382
        
 
383
        if ( TEV_AMEXCL )     /* Special handling of tracing for bcast */
 
384
        {
 
385
                if (TEV_DO_TRACE(TEV_BCAST,TEV_EVENT_EXIT)) 
 
386
                {
 
387
                        TEV_PACK_INT( TEV_DID_CC, TEV_DATA_SCALAR, &cc, 1, 1 );
 
388
                        if (cc < 0) 
 
389
                        {
 
390
                                TEV_PACK_INT( TEV_DID_MDL, TEV_DATA_ARRAY,
 
391
                                        (int *) NULL, 0, 1 );
 
392
                        } 
 
393
                        else 
 
394
                        {
 
395
                                TEV_PACK_INT( TEV_DID_MDL, TEV_DATA_ARRAY,
 
396
                                        tids, ntids, 1 );
 
397
                        }
 
398
                        TEV_FIN;
 
399
                }
 
400
                TEV_ENDEXCL;
 
401
        }
 
402
 
 
403
        if (tids)
 
404
                PVM_FREE(tids);
 
405
 
 
406
        return(cc);
 
407
}
 
408
        
 
409
/* ================ pvm_barrier() ====================================     */
 
410
/*
 
411
        int info = pvm_barrier(char* group, int count)
 
412
 
 
413
        Calling task waits until count members of named group also
 
414
        call pvm_barrier. If user places -1 for count then the present
 
415
        size of the group is used. Note this option is not useful if
 
416
        the size of the group is changing.
 
417
        A process must be a member of a group to call pvm_barrier on
 
418
        that group
 
419
*/
 
420
 
 
421
int
 
422
pvm_barrier(group, cnt)
 
423
char  *group;
 
424
int cnt;
 
425
{
 
426
        int rc;
 
427
        int x; 
 
428
        
 
429
#if defined(IMA_PGON)
 
430
 
 
431
        int gstate;
 
432
        int mytid;
 
433
        int nhosts;
 
434
        int nmem;
 
435
        int pcoord;
 
436
 
 
437
        extern int pvmpgonpartsize;
 
438
 
 
439
#endif
 
440
 
 
441
        TEV_DECLS;
 
442
        
 
443
        BGN_TRACE( TEV_BARRIER, group, TEV_DID_GBC, &cnt);
 
444
        
 
445
/* use gsync when possible on the PGON. 
 
446
        1) The group must be static
 
447
        2) The size of the PGON partition must equal number pgon nodes in group
 
448
        3) If group has other hosts besides pgon, then 1 node from pgon 
 
449
        represents all the nodes to the group server. 
 
450
*/
 
451
#if defined(IMA_PGON)
 
452
        mytid = pvm_mytid();
 
453
 
 
454
        rc = gs_host_char(group,sgroup_list, &ngroups, 
 
455
 
 
456
        gs_tidtohost(mytid), &pcoord, &nmem, &nhosts, &gstate);
 
457
 
 
458
        if (rc == 0 && nmem == pvmpgonpartsize ) /*use gsync */
 
459
        {
 
460
                rc = _gsync();
 
461
 
 
462
                if ( rc >= 0 && nhosts > 1) /* sync'ed pgon, now sync w/others */
 
463
                {
 
464
                        if (pcoord == mytid)
 
465
                                int_query_server(group, BARRIERV, "pvm_barrier", &rc, cnt);
 
466
 
 
467
                        _gsync();  
 
468
                }
 
469
        }
 
470
        else
 
471
#endif
 
472
 
 
473
        int_query_server(group, BARRIER,  "pvm_barrier", &rc, cnt);
 
474
 
 
475
        if (rc > 0) 
 
476
                rc = 0;
 
477
 
 
478
        END_TRACE( TEV_BARRIER, TEV_DID_CC, &rc );
 
479
 
 
480
        if (rc < 0)
 
481
                pvm_errno = rc;
 
482
 
 
483
        return(rc);
 
484
}
 
485
        
 
486
/* ================ pvm_freezegroup() ===============================     */
 
487
/*
 
488
        int info = pvm_freezegroup(char *group, int size)
 
489
        The named dynamic group is frozen.  Group information is cached by
 
490
        the local process.
 
491
*/   
 
492
 
 
493
int
 
494
pvm_freezegroup(group, size)
 
495
char *group;
 
496
int size;
 
497
{
 
498
        int rc;
 
499
        int x;
 
500
 
 
501
        /* BGN_TRACE( TEV_FREEZE, group, TEV_DID_GS, &size ); */
 
502
 
 
503
        int_query_server(group, STATICGROUP,  "pvm_freezegroup", &rc, size);
 
504
 
 
505
        /* END_TRACE( TEV_FREEZE, TEV_DID_CC, &rc ); */
 
506
 
 
507
        return(rc);
 
508
}
 
509
        
 
510
        
 
511
/* **************** ROUTINES THAT DIRECTLY CONTACT THE SERVER  ************/
 
512
 
 
513
/* ================ pvm_gsdump() ====================================     */
 
514
/*
 
515
*       void pvm_gsdump()
 
516
*       ask pvmgs to dump it's state. Assumes pvmgs is running
 
517
*/
 
518
void
 
519
pvm_gsdump()
 
520
{
 
521
        int savectx;
 
522
        int sbuf;
 
523
 
 
524
        savectx = pvm_setcontext( SYSCTX_DG );
 
525
 
 
526
        sbuf = pvm_mkbuf(PvmDataDefault);
 
527
 
 
528
        sbuf = pvm_setsbuf(sbuf);
 
529
 
 
530
        pvm_send(gstid, DUMP);
 
531
 
 
532
        pvm_freebuf(pvm_setsbuf(sbuf));
 
533
 
 
534
        pvm_setcontext( savectx );
 
535
}
 
536
        
 
537
/* ================ int_query_server() ===============================     */
 
538
/* Query server to get a single integer of information. Single integer     */
 
539
/* int info = int_query_server(char *group, int request, char *caller, 
 
540
*       int *rvalue, int optarg)
 
541
*       group    - string to identify the group
 
542
*       request  - integer ID of request
 
543
*       requests are: JOIN, LEAVE, GETTID, GETINST, BARRIER, GSIZE  
 
544
*       STATICGROUP
 
545
*       caller   - string to use in error reporting
 
546
*       rvalue   - value returned by server
 
547
*       optarg   - optional argument used by some requests (e.g., barrier,
 
548
*       freezegroup)
 
549
*       
 
550
*       The request is made of the group server for group. It is possible
 
551
*       for the server to not only return the information, but to tack on
 
552
*       the instance map of the group. If this happens, then a new entry
 
553
*       is kept locally to cache the info for this group.
 
554
*/
 
555
 
 
556
int
 
557
int_query_server(group, request, caller, rvalue, optarg)
 
558
char *group;
 
559
int request;
 
560
char *caller;
 
561
int *rvalue;
 
562
int optarg;
 
563
{
 
564
        int len;
 
565
        int mytid;
 
566
        int rbuf;
 
567
        int sbuf,stid;
 
568
        int state;
 
569
        int savectx;
 
570
 
 
571
        GROUP_STRUCT_PTR sgroup;
 
572
 
 
573
        mytid = pvm_mytid();
 
574
 
 
575
        if (group == (char*)0)
 
576
                return  (*rvalue = PvmNullGroup);
 
577
 
 
578
        if ( (stid = gs_getgstid()) < 0)  /* find the server's tid         */
 
579
                return  (*rvalue = PvmSysErr);
 
580
 
 
581
        /* set context for dynamic groups */
 
582
        savectx = pvm_setcontext( SYSCTX_DG );
 
583
 
 
584
        /* send the request to the group server.                           */
 
585
        if ((sbuf = pvm_mkbuf(PvmDataDefault)) < 0)
 
586
                pvm_perror(caller);
 
587
 
 
588
        if ((sbuf = pvm_setsbuf(sbuf)) < 0)
 
589
                pvm_perror(caller);
 
590
 
 
591
        if (pvm_pkstr(group) < 0)
 
592
                pvm_perror(caller);
 
593
 
 
594
        if (request == GETINST 
 
595
                        || request == GETTID 
 
596
                        || request == BARRIER 
 
597
                        ||  request == BARRIERV 
 
598
                        || request == STATICGROUP) 
 
599
        {
 
600
                /* pack optarg                                                 */
 
601
                if (pvm_pkint(&optarg, 1, 1 ) < 0)
 
602
                        pvm_perror(caller);
 
603
        }
 
604
        
 
605
        if (pvm_send(stid, request) < 0)
 
606
                pvm_perror(caller);
 
607
 
 
608
        if ((rbuf = pvm_setrbuf(0)) < 0) /* get return value from  server  */
 
609
                pvm_perror(caller);
 
610
        
 
611
        if (request == BARRIERV) request = BARRIER; 
 
612
        {
 
613
                if (pvm_recv(stid, request) < 0)
 
614
                        pvm_perror(caller);
 
615
        }
 
616
 
 
617
        if (pvm_upkint(rvalue, 1, 1) < 0)
 
618
                pvm_perror(caller);
 
619
 
 
620
        if (request == JOIN || request == LEAVE || request == BARRIER 
 
621
                        || *rvalue < 0 )
 
622
                state = DYNAMIC; /* no state data will be returned            */
 
623
        else
 
624
                pvm_upkint(&state,1,1);
 
625
 
 
626
        if (state == STATIC)            /* we've got new static group info */
 
627
                gs_cachegroup(sgroup_list, &ngroups, &sgroup);
 
628
 
 
629
        pvm_freebuf(pvm_setsbuf(sbuf)); /* restore the users mbufs */
 
630
 
 
631
        pvm_freebuf(pvm_setrbuf(rbuf));
 
632
 
 
633
        /* restore user context */
 
634
        pvm_setcontext( savectx );
 
635
 
 
636
        return (PvmOk);
 
637
}
 
638
        
 
639
/* ================ gs_get_tidlist() =================================     */
 
640
/*
 
641
int info = gs_get_tidlist(char *group, int msgtag, int *ntids, int **tids,
 
642
        int holes_not_allowed)
 
643
        group - groupname
 
644
        msgtag - msgtag to use for querying server
 
645
        ntids  - number of tids in the tidlist
 
646
        tids   - the tidlist itself. Malloc'ed
 
647
        holes_not_allowed - flag to indicate tid list must not have holes.
 
648
*/
 
649
 
 
650
int 
 
651
gs_get_tidlist(group, msgtag, ntids, tids, holes_not_allowed)
 
652
char *group;
 
653
int msgtag;
 
654
int *ntids; 
 
655
int **tids; 
 
656
int holes_not_allowed;
 
657
{
 
658
        int i;
 
659
        int len;
 
660
        int mytid;
 
661
        int rbuf;
 
662
        int sbuf, state, stid;
 
663
        int savectx;
 
664
 
 
665
        GROUP_STRUCT_PTR sgroup;
 
666
 
 
667
        if ( group == (char*)0 ) 
 
668
                return(PvmNullGroup);
 
669
 
 
670
        /* look up to see if the information is held locally               */
 
671
 
 
672
        sgroup = gs_group(group, sgroup_list, &ngroups, NOCREATE);
 
673
 
 
674
        if (sgroup != (GROUP_STRUCT_PTR) NULL) 
 
675
        {
 
676
                if (holes_not_allowed)  
 
677
                {
 
678
                        for (i=0; i < sgroup->ntids; i++)
 
679
                                if (sgroup->tids[i] == NOTID)
 
680
                                {
 
681
                                        *ntids = -1;
 
682
                                        return (*ntids);
 
683
                                }
 
684
                }
 
685
 
 
686
                *tids = (int *) PVM_ALLOC(sgroup->maxntids*sizeof(int),"tidlist"); 
 
687
 
 
688
                for (i = 0; i < sgroup->maxntids; i++)
 
689
                        (*tids)[i] = sgroup->tids[i];
 
690
        
 
691
                *ntids = sgroup->ntids;
 
692
 
 
693
                return (PvmOk);
 
694
        } 
 
695
        
 
696
        /* find out the server's tid, start the server if need be          */
 
697
        if ( (stid = gs_getgstid()) < 0 ) 
 
698
                return(PvmSysErr);
 
699
        
 
700
        sbuf = pvm_mkbuf(PvmDataDefault);  /* send rqst to server          */
 
701
 
 
702
        sbuf = pvm_setsbuf(sbuf);
 
703
 
 
704
        rbuf = pvm_setrbuf(0); 
 
705
 
 
706
        pvm_pkstr(group);
 
707
 
 
708
        /* set context for dynamic groups */
 
709
        savectx = pvm_setcontext( SYSCTX_DG );
 
710
 
 
711
        if (holes_not_allowed)  
 
712
        {
 
713
                pvm_send(stid, TIDLIST);       /* e.g. scatter, gather         */
 
714
                pvm_recv(stid, TIDLIST); 
 
715
        }
 
716
        else 
 
717
        {
 
718
                pvm_send(stid, BCAST);         /* e.g. bcast                   */
 
719
                pvm_recv(stid, BCAST); 
 
720
        } 
 
721
 
 
722
        /* restore user context */
 
723
        pvm_setcontext( savectx );
 
724
 
 
725
        pvm_upkint(ntids, 1, 1);
 
726
        
 
727
        if (*ntids < 0) /* check for number of tids in group               */
 
728
        {
 
729
                pvm_freebuf(pvm_setsbuf(sbuf));
 
730
                pvm_freebuf(pvm_setrbuf(rbuf));
 
731
 
 
732
                return(*ntids);
 
733
        }
 
734
        
 
735
        if (*ntids == 0) /* if there is no one in the group */
 
736
        {
 
737
                pvm_freebuf(pvm_setsbuf(sbuf));
 
738
                pvm_freebuf(pvm_setrbuf(rbuf));
 
739
        
 
740
                return(PvmNoInst);
 
741
        }
 
742
        
 
743
        /* make room for the tids */
 
744
        *tids = (int *)PVM_ALLOC((*ntids) * sizeof(int), "gs_get_tidlist");
 
745
 
 
746
        if ((*tids) == (int *) NULL)
 
747
        {
 
748
                pvm_freebuf(pvm_setsbuf(sbuf));
 
749
                pvm_freebuf(pvm_setrbuf(rbuf));
 
750
        
 
751
                return(PvmSysErr);
 
752
        }
 
753
 
 
754
        pvm_upkint(*tids, *ntids, 1);
 
755
 
 
756
        pvm_upkint(&state,1,1);
 
757
 
 
758
        if (state == STATIC)            /* we've got new static group info */
 
759
                gs_cachegroup(sgroup_list, &ngroups, &sgroup);
 
760
 
 
761
        pvm_freebuf(pvm_setsbuf(sbuf)); /* restore the users mbufs         */
 
762
 
 
763
        pvm_freebuf(pvm_setrbuf(rbuf));
 
764
        
 
765
        return(PvmOk);
 
766
 
767
        
 
768
/* ================ gs_cachegroup() ==================================     */
 
769
/* int info = gs_cachegroup(GROUP_LIST_PTR sgroup_list, int *ngroups,
 
770
        GROUP_STRUCT_PTR *rsgroup);
 
771
        
 
772
        sgroup_list - hash table that holds any static group information
 
773
        ngroups     - number of groups in the hash table
 
774
        *rsgroup    - pointer to structure that holds static info
 
775
        
 
776
        unpack group information from a message and then create the group in   
 
777
        the group list;                                                       
 
778
*/ 
 
779
int
 
780
gs_cachegroup(sgroup_list, ngroups, rsgroup)
 
781
GROUP_LIST_PTR sgroup_list;
 
782
int *ngroups;
 
783
GROUP_STRUCT_PTR *rsgroup;
 
784
{
 
785
        char *newname = (char *) NULL; 
 
786
 
 
787
        int info;
 
788
        int len;
 
789
 
 
790
        GROUP_STRUCT_PTR sgroup; 
 
791
 
 
792
        *rsgroup = (GROUP_STRUCT_PTR) NULL;
 
793
 
 
794
        if ( (info = pvm_upkint(&len,1,1))  < 0 )
 
795
                DO_ERROR_RTN( info, "gs_cachegroup" );
 
796
 
 
797
        if (len < 0)                  /* didn't get a valid groupname     */
 
798
                return(-1);
 
799
 
 
800
        if ( (newname = (char *) PVM_ALLOC(sizeof(char)*(len + 1),
 
801
                        "gs_cachegroup") ) == (char *) NULL) 
 
802
                DO_ERROR_RTN( PvmNoMem, "gs_cachegroup" );
 
803
 
 
804
        if ( (info = pvm_upkstr(newname))  < 0  )
 
805
        {
 
806
                PVM_FREE(newname);
 
807
                DO_ERROR_RTN( info, "gs_cachegroup" );
 
808
        }
 
809
 
 
810
        sgroup = gs_group(newname, sgroup_list, ngroups, CREATE);
 
811
 
 
812
        if (sgroup != (GROUP_STRUCT_PTR) NULL)
 
813
        {
 
814
                if ( (info = pvm_upkint(&(sgroup->ntids),1,1) ) < 0 )
 
815
                {
 
816
                        PVM_FREE(newname);
 
817
                        DO_ERROR_RTN( info, "gs_cachegroup" );
 
818
                }
 
819
 
 
820
                if ( (info = pvm_upkint(&(sgroup->maxntids),1,1) ) < 0 )
 
821
                {
 
822
                        PVM_FREE(newname);
 
823
                        DO_ERROR_RTN( info, "gs_cachegroup" );
 
824
                }
 
825
 
 
826
                sgroup->tids = (int *) PVM_ALLOC(sgroup->maxntids*sizeof(int),
 
827
                                "gs_cachegroup");
 
828
 
 
829
                if (sgroup->tids == (int *) NULL)
 
830
                        gs_delete_group(newname, sgroup_list, ngroups);
 
831
                else
 
832
                {
 
833
                        if ( (info = pvm_upkint(sgroup->tids,sgroup->maxntids,1) ) < 0)
 
834
                        {
 
835
                                gs_delete_group(newname, sgroup_list, ngroups);
 
836
                                PVM_FREE(newname);
 
837
                                DO_ERROR_RTN( info, "gs_cachegroup" );
 
838
                        }
 
839
 
 
840
                        info = pvm_upkint(&(sgroup->nhosts),1,1);
 
841
 
 
842
                        sgroup->np_onhost = (int *) PVM_ALLOC(sizeof(int) * 
 
843
                                        sgroup->nhosts,"gs_cachegroup");
 
844
        
 
845
                        sgroup->pcoord = (int *) PVM_ALLOC(sizeof(int) * 
 
846
                                        sgroup->nhosts,"gs_cachegroup");
 
847
 
 
848
                        pvm_upkint(sgroup->np_onhost,sgroup->nhosts,1);
 
849
 
 
850
                        info = pvm_upkint(sgroup->pcoord,sgroup->nhosts,1);
 
851
 
 
852
                        if (info < 0)
 
853
                        { 
 
854
                                gs_delete_group(newname, sgroup_list, ngroups);
 
855
                                PVM_FREE(newname);
 
856
                                DO_ERROR_RTN( info, "gs_cachegroup" );
 
857
                        }
 
858
 
 
859
                        sgroup->maxhosts = sgroup->nhosts;
 
860
                }
 
861
 
 
862
                sgroup->staticgroup = STATIC;
 
863
                *rsgroup = sgroup;  /* set the pointer to the group struct     */
 
864
        }
 
865
 
 
866
        PVM_FREE(newname); /* free the malloc'ed memory */
 
867
 
 
868
        return (PvmOk);
 
869
}
 
870
 
 
871
/* ================ pvm_grphostinfo() ===============================     */
 
872
/* int info = pvm_grphostinfo(char *group, int hosttid, int *coord,
 
873
        int *nmem_onhost, int *nhosts)
 
874
        * return information about how many hosts are represented in the group and
 
875
        * which tid should be used to coordinate local (on-host) group operations
 
876
*/
 
877
 
 
878
int 
 
879
pvm_grphostinfo(group, hosttid, coord, nmem_onhost, nhosts) 
 
880
char *group;
 
881
int hosttid, *coord, *nmem_onhost, *nhosts;
 
882
{
 
883
        GROUP_STRUCT_PTR sgroup;
 
884
        int foo;
 
885
        int info;
 
886
        int mytid;
 
887
        int rbuf, rc;
 
888
        int sbuf, state, stid;
 
889
        int x;
 
890
        int savectx;
 
891
        
 
892
        /* BGN_TRACE( TEV_GRPHOST, group, TEV_DID_HPT, &hosttid ); */
 
893
 
 
894
        info = gs_host_char(group, sgroup_list, &ngroups, hosttid,
 
895
                        coord, nmem_onhost, nhosts, &foo); 
 
896
 
 
897
        if (info  != PvmOk )   /* info not local */
 
898
        {
 
899
                if ( (stid = gs_getgstid()) < 0) { /* find the server's ti */
 
900
                        info = PvmSysErr;
 
901
                        /* END_TRACE( TEV_GRPHOST, TEV_DID_CC, &info ); */
 
902
                        return( info );
 
903
                }
 
904
 
 
905
                /* set context for dynamic groups */
 
906
                savectx = pvm_setcontext( SYSCTX_DG );
 
907
 
 
908
                sbuf = pvm_mkbuf(PvmDataDefault);
 
909
 
 
910
                rbuf = pvm_setrbuf(0);
 
911
 
 
912
                sbuf = pvm_setsbuf(sbuf); 
 
913
 
 
914
                if ((info =  pvm_pkstr(group)) < 0 )
 
915
                        goto cleanup;
 
916
                
 
917
                if ((info = pvm_pkint(&hosttid,1,1)) < 0)
 
918
                        goto cleanup;
 
919
 
 
920
                if ((info = pvm_send(stid,HOSTCHAR)) < 0)
 
921
                        goto cleanup;
 
922
 
 
923
                if ((info = pvm_recv(stid,HOSTCHAR)) < 0)
 
924
                        goto cleanup;
 
925
 
 
926
                if ((info = pvm_upkint(nhosts,1,1)) < 0) 
 
927
                        goto cleanup;
 
928
 
 
929
                if ((info = pvm_upkint(nmem_onhost,1,1)) < 0) 
 
930
                        goto cleanup;
 
931
 
 
932
                if ((info = pvm_upkint(coord,1,1)) < 0) 
 
933
                        goto cleanup;
 
934
        
 
935
                if (( info = pvm_upkint(&state,1,1)) < 0) 
 
936
                        goto cleanup;
 
937
 
 
938
                if (state == STATIC)       /* we've got new static group info */
 
939
                        gs_cachegroup(sgroup_list, &ngroups, &sgroup);
 
940
 
 
941
cleanup:     
 
942
 
 
943
                sbuf = pvm_setsbuf(sbuf);
 
944
 
 
945
                rbuf = pvm_setrbuf(rbuf);
 
946
 
 
947
                pvm_freebuf(sbuf);
 
948
 
 
949
                pvm_freebuf(rbuf);
 
950
 
 
951
                /* restore user context */
 
952
                pvm_setcontext( savectx );
 
953
        }
 
954
        
 
955
        /* END_TRACE( TEV_GRPHOST, TEV_DID_CC, &info ); */
 
956
 
 
957
        return(info);
 
958
}
 
959
 
 
960
/* ================ pvm_grpvhostinfo() ===============================     */
 
961
/* int info = pvm_grpvhostinfo(char *group, int **coord,
 
962
int **nmem_onhost, int *nhosts)
 
963
* return #vectors# of information about how may hosts are represented in
 
964
* a group, the local coordinating tid for each host, and #procs on each host
 
965
*
 
966
* NOTE: for efficiency, the data in the vectors *nmem_host and 
 
967
*coord are valid only until the next call to pvm_grpvhostinfo 
 
968
*/
 
969
 
 
970
static int *gsu_coordv = (int *) NULL;
 
971
static int *gsu_onhostv = (int *) NULL;
 
972
static int gsu_maxhosts = 0;
 
973
 
 
974
int 
 
975
pvm_grpvhostinfo(group, coordv, nmem_onhostv, nhosts) 
 
976
char *group;
 
977
int **coordv, **nmem_onhostv, *nhosts;
 
978
{
 
979
        int foo;
 
980
        int info;
 
981
        int mytid;
 
982
        int rbuf, rc;
 
983
        int sbuf, state, stid;
 
984
        int x;
 
985
        int savectx;
 
986
 
 
987
        GROUP_STRUCT_PTR sgroup;
 
988
 
 
989
        /* BGN_TRACE( TEV_GRPVHOST, group, TEV_DID_HPT, &hosttid ); */
 
990
 
 
991
        info = gs_host_all(group, sgroup_list, &ngroups, 
 
992
                        coordv, nmem_onhostv, nhosts, &foo); 
 
993
 
 
994
        if (info  != PvmOk )   /* info not local */
 
995
        {
 
996
                if ( (stid = gs_getgstid()) < 0) { /* find the server's ti */
 
997
                        info = PvmSysErr;
 
998
                        /* END_TRACE( TEV_GRPHOST, TEV_DID_CC, &info ); */
 
999
                        return( info );
 
1000
                }
 
1001
 
 
1002
                /* set context for dynamic groups */
 
1003
                savectx = pvm_setcontext( SYSCTX_DG );
 
1004
 
 
1005
                sbuf = pvm_mkbuf(PvmDataDefault);
 
1006
 
 
1007
                rbuf = pvm_setrbuf(0);
 
1008
 
 
1009
                sbuf = pvm_setsbuf(sbuf); 
 
1010
 
 
1011
                if ((info = pvm_pkstr(group)) < 0) 
 
1012
                        goto cleanup;
 
1013
 
 
1014
                if ((info = pvm_send(stid,HOSTCHARV)) < 0) 
 
1015
                        goto cleanup;
 
1016
 
 
1017
                if ((info = pvm_recv(stid,HOSTCHARV)) < 0) 
 
1018
                        goto cleanup;
 
1019
 
 
1020
                if ((info = pvm_upkint(nhosts,1,1)) < 0) 
 
1021
                        goto cleanup;
 
1022
 
 
1023
                if (*nhosts >  gsu_maxhosts)
 
1024
                {
 
1025
                        if (gsu_coordv) 
 
1026
                                PVM_FREE(gsu_coordv);
 
1027
 
 
1028
                        if (gsu_onhostv) 
 
1029
                                PVM_FREE(gsu_onhostv);
 
1030
 
 
1031
                        gsu_coordv = (int *) PVM_ALLOC(*nhosts*sizeof(int), 
 
1032
                                        "pvm_grp_hostv");
 
1033
 
 
1034
                        gsu_onhostv = (int *) PVM_ALLOC(*nhosts*sizeof(int), 
 
1035
                                        "pvm_grp_hostv");
 
1036
 
 
1037
                        gsu_maxhosts = *nhosts;
 
1038
                }
 
1039
 
 
1040
                if (gsu_onhostv == (int *) NULL || gsu_coordv == (int *) NULL)
 
1041
                {
 
1042
                        info = PvmOutOfRes;
 
1043
                        goto cleanup;
 
1044
                }
 
1045
 
 
1046
                if ((info =  pvm_upkint(gsu_onhostv,*nhosts,1)) < 0) 
 
1047
                        goto cleanup;
 
1048
 
 
1049
                if ((info =  pvm_upkint(gsu_coordv,*nhosts,1)) < 0) 
 
1050
                        goto cleanup;
 
1051
 
 
1052
                if ((info =  pvm_upkint(&state,1,1)) < 0) 
 
1053
                        goto cleanup;
 
1054
 
 
1055
                if (state == STATIC)       /* we've got new static group info */
 
1056
                        gs_cachegroup(sgroup_list, &ngroups, &sgroup);
 
1057
cleanup:
 
1058
        
 
1059
                sbuf = pvm_setsbuf(sbuf);
 
1060
 
 
1061
                rbuf = pvm_setrbuf(rbuf);
 
1062
 
 
1063
                pvm_freebuf(sbuf);
 
1064
 
 
1065
                pvm_freebuf(rbuf);
 
1066
 
 
1067
                /* restore user context */
 
1068
                pvm_setcontext( savectx );
 
1069
 
 
1070
                *nmem_onhostv = gsu_onhostv;
 
1071
 
 
1072
                *coordv = gsu_coordv;
 
1073
        }
 
1074
        
 
1075
        /* END_TRACE( TEV_GRPVHOST, TEV_DID_CC, &info ); */
 
1076
 
 
1077
        return(info);
 
1078
}