3
"$Id: msgbox.c,v 1.17 1997/06/27 17:32:30 pvmsrc Exp $";
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
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.
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
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.
36
* Message mailbox database.
39
* Revision 1.17 1997/06/27 17:32:30 pvmsrc
40
* Updated for WIN32 header files & Authors.
42
* Revision 1.16 1997/05/07 21:23:54 pvmsrc
43
* Fixed manual packing of class name lengths.
44
* - no longer necessary with (pvm)upkstralloc() usage.
46
* - only free pattbuf if !pattglob... D-Oh!
48
* Revision 1.15 1997/05/05 18:17:49 pvmsrc
49
* Added new pvmregex.o targets (part of ./regex stuff).
50
* - extracted mb_names() regex usage to new pvm/regex routines:
51
* void *pvmcompileregex __ProtoGlarp__ (( char * ));
52
* int pvmmatchregex __ProtoGlarp__ (( void *, char * ));
53
* void pvmfreeregex __ProtoGlarp__ (( void ** ));
55
* Revision 1.14 1997/05/02 19:44:38 pvmsrc
56
* Added GNU Regex Stuff:
57
* - Makefile targets for regex.o
58
* - usage in mb_names() / msgbox.c
60
* Revision 1.13 1997/05/02 14:54:18 pvmsrc
61
* Implemented guts of pvm_getmboxinfo():
62
* - user library side sends pattern & receives back / allocs array.
63
* - at pvmd side mb_names() searches class list for matching pattern,
64
* count up # of entries, and pack up struct info.
65
* (Note: does not yet use GNU regex stuff...)
67
* Revision 1.12 1997/04/10 17:53:54 pvmsrc
68
* Externalized me_new()...
69
* - for WT_RECVINFO usage...
71
* Revision 1.11 1997/04/08 20:06:33 pvmsrc
72
* Un-static-ed me_free().
73
* - so ddpro.c can use it... D-Oh.
75
* Revision 1.10 1997/04/08 19:57:52 pvmsrc
76
* Promoted mbox static "classes" to public global "pvmmboxclasses".
77
* - so pvmd can spank mboxes in ddpro.c... :-Q
78
* - renamed everywhere, moved decl / extern to global.[ch].
80
* Revision 1.9 1997/04/08 19:41:11 pvmsrc
81
* Added me_savetid to pvmmentry struct.
82
* - for keeping track of original owner on persistent mboxes.
83
* - allows more careful cleanup in a system reset, set me_tid to 0
84
* but save original tid in me_savetid first... :-)
86
* Revision 1.8 1997/04/08 18:45:20 pvmsrc
87
* Yanked out internal struct defns for mclass & mentry.
88
* - replaced with msgbox.h header, and pvmmclass / pvmmentry structs.
90
* Revision 1.7 1997/04/08 17:53:25 pvmsrc
91
* Added new mb_tidy_reset() routine.
92
* - triggered by task exit during a system reset (when persistent
93
* mbox entries are owned by task).
94
* - clear out any persistent mboxes owned by task, or any others
95
* that have already been cleared.
97
* Revision 1.6 1997/04/01 16:39:39 pvmsrc
98
* Oops... PvmMboxOverwritable -> PvmMboxOverWritable... D-Oh.
100
* Revision 1.5 1997/04/01 16:19:25 pvmsrc
101
* Modified mbox internals to properly handle new flags syntax.
103
* * PvmMboxMultiInstance = if index 0 is in use, stick in
104
* first available higher index.
105
* * PvmMboxOverwritable = allow anyone to overwrite or delete
106
* the given mbox entry.
107
* * PvmMboxPersistent = do not remove mailbox on task exit,
108
* allow only PVMD to delete on reset (after task exit only).
110
* * PvmMboxReadAndDelete = if entry is owned by task or is
111
* overwritable, read entry and atomically delete, else fail.
112
* * PvmMboxFirstAvail = if entry not present at given index,
113
* return next entry by index, else fail.
115
* Revision 1.4 1997/01/28 19:26:54 pvmsrc
116
* New Copyright Notice & Authors.
118
* Revision 1.3 1996/10/24 21:04:48 pvmsrc
119
* Moved #include of "global.h" down below other headers:
120
* - need to have all of the structures / types declared before
121
* the globals can be declared...
123
* Revision 1.2 1996/09/23 23:32:16 pvmsrc
124
* Initial Creation - original msgbox.c.
131
#include <machine/endian.h>
137
#include <sys/endian.h>
140
#include <rpc/types.h>
143
#include "..\xdr\types.h"
144
#include "..\xdr\xdr.h"
153
#include "pvmalloc.h"
159
void *pvmcompileregex __ProtoGlarp__ (( char * ));
160
int pvmmatchregex __ProtoGlarp__ (( void *, char * ));
161
void pvmfreeregex __ProtoGlarp__ (( void ** ));
169
extern int pvmdebmask; /* from pvmd.c */
180
struct pvmmentry *ep;
182
if (ep = TALLOC(1, struct pvmmentry, "pvmmentry")) {
183
ep->me_link = ep->me_rlink = ep;
186
ep->me_flags = PvmMboxDefault;
194
static struct pvmmclass *
198
struct pvmmclass *np;
200
if (np = TALLOC(1, struct pvmmclass, "pvmmclass")) {
202
np->mc_name = STRALLOC(name);
203
np->mc_ent = me_new(-1);
204
LISTPUTBEFORE(pvmmboxclasses, np, mc_link, mc_rlink);
207
np->mc_link = np->mc_rlink = np;
218
struct pvmmclass *np;
219
struct pvmmentry *ep;
221
LISTDELETE(ep, me_link, me_rlink);
222
pmsg_unref(ep->me_msg);
224
if (np->mc_ent->me_link == np->mc_ent) {
225
LISTDELETE(np, mc_link, mc_rlink);
226
PVM_FREE(np->mc_name);
227
PVM_FREE(np->mc_ent);
234
static struct pvmmclass *
238
struct pvmmclass *np;
240
for (np = pvmmboxclasses->mc_link; np != pvmmboxclasses;
242
if (!strcmp(np->mc_name, name))
244
return (struct pvmmclass *)0;
251
pvmmboxclasses = mc_new((char*)0);
257
mb_insert(tid, name, req, flags, mp)
258
int tid; /* owner task */
259
char *name; /* class name */
260
int req; /* index requested or -1 for lowest avail */
262
struct pmsg *mp; /* message to store */
264
struct pvmmclass *np;
265
struct pvmmentry *ep;
266
struct pvmmentry *ep2 = 0;
268
if (!(np = mc_find(name)))
269
if (!(np = mc_new(name)))
272
for (ep = np->mc_ent->me_link; ep != np->mc_ent; ep = ep->me_link)
273
if (ep->me_ind >= req)
276
/* default insert is "locked"... */
278
if (flags & PvmMboxMultiInstance) {
279
for (; ep != np->mc_ent; ep = ep->me_link) {
280
if (ep->me_ind != req)
282
if ( (ep->me_flags & PvmMboxOverWritable)
283
|| tid == ep->me_tid ) {
287
req = ep->me_ind + 1;
290
if (ep->me_ind == req) {
291
if ( !(ep->me_flags & PvmMboxOverWritable)
292
&& tid != ep->me_tid) {
301
LISTDELETE(ep2, me_link, me_rlink);
302
pmsg_unref(ep2->me_msg);
307
ep2->me_flags = flags;
309
LISTPUTBEFORE(ep, ep2, me_link, me_rlink);
316
mb_delete(tid, name, req, flags)
317
int tid; /* owner task */
318
char *name; /* class name */
320
int flags; /* options */
322
struct pvmmclass *np;
323
struct pvmmentry *ep = 0;
325
if (np = mc_find(name)) {
326
for (ep = np->mc_ent->me_link; ep != np->mc_ent;
328
if (ep->me_ind == req)
331
if (ep == np->mc_ent)
338
if ( !(ep->me_flags & PvmMboxOverWritable) && tid != ep->me_tid )
349
mb_lookup(tid, name, req, flags, mpp)
350
int tid; /* owner task */
351
char *name; /* class name */
352
int req; /* index requested or -1 for first avail */
354
struct pmsg **mpp; /* message return */
356
struct pvmmclass *np;
357
struct pvmmentry *ep = 0;
359
if (np = mc_find(name)) {
360
for (ep = np->mc_ent->me_link; ep != np->mc_ent;
362
if (ep->me_ind >= req)
365
if (ep == np->mc_ent)
367
else if (!(flags & PvmMboxFirstAvail) && ep->me_ind != req)
372
if ( flags & PvmMboxReadAndDelete ) {
373
if ( (ep->me_flags & PvmMboxOverWritable)
374
|| tid == ep->me_tid ) {
381
*mpp = (struct pmsg *) NULL;
396
mb_names(tid, pattern, mp)
403
struct pvmmclass *np;
404
struct pvmmentry *ep;
409
/* Check for "*" Global Match Pattern */
411
if ( !strcmp( pattern, "*" ) )
414
/* Compile Regular Expression */
417
pattbuff = pvmcompileregex( pattern );
419
/* Count # of Classes */
423
for ( np = pvmmboxclasses->mc_link; np != pvmmboxclasses;
428
( pvmmatchregex( pattbuff, np->mc_name ) )
429
: ( !strcmp( pattern, np->mc_name ) ) ) )
437
/* Pack Class Info */
439
for ( np = pvmmboxclasses->mc_link; np != pvmmboxclasses;
444
( pvmmatchregex( pattbuff, np->mc_name ) )
445
: ( !strcmp( pattern, np->mc_name ) ) ) )
447
pkstr( mp, np->mc_name );
449
/* Count # of Entries */
453
for ( ep = np->mc_ent->me_link; ep != np->mc_ent;
459
/* Pack Entry Info */
461
for ( ep = np->mc_ent->me_link; ep != np->mc_ent;
464
pkint( mp, ep->me_ind );
465
pkint( mp, ep->me_tid );
466
pkint( mp, ep->me_flags );
471
if ( !pattglob && pattbuff )
472
pvmfreeregex( &pattbuff );
480
struct pvmmclass *np;
482
struct pvmmentry *ep;
484
pvmlogprintf("<%s>\n", np->mc_name);
485
for (ep = np->mc_ent->me_link; ep != np->mc_ent; ep = ep->me_link) {
486
pvmlogprintf("%d (0x%x): owner 0x%x (was 0x%x) flags %d\n",
487
ep->me_ind, ep->me_ind, ep->me_tid, ep->me_savetid,
489
pmsg_dump(ep->me_msg, 2);
498
struct pvmmclass *np;
500
pvmlogerror("mb_dumpall():\n");
501
for (np = pvmmboxclasses->mc_link; np != pvmmboxclasses;
511
* Remove any non-sticky entries owned by it.
512
* Remove its tid as owner for sticky entries and reset Lock.
519
struct pvmmclass *np, *np2;
520
struct pvmmentry *ep, *ep2;
525
if (pvmdebmask & PDMMBOX)
526
pvmlogprintf("mb_tidy() tid 0x%x\n", tid);
528
for (np = pvmmboxclasses->mc_link; np != pvmmboxclasses; np = np2) {
530
for (ep = np->mc_ent->me_link; ep != np->mc_ent; ep = ep2) {
532
if (ep->me_tid == tid) {
533
if (ep->me_flags & PvmMboxPersistent) {
534
ep->me_savetid = ep->me_tid;
538
if (np2->mc_rlink != np)
550
* Task has exited during a system reset.
551
* Remove any persistent entries owned by it, and any other
552
* persistent entries that have already been cleared.
559
struct pvmmclass *np, *np2;
560
struct pvmmentry *ep, *ep2;
565
if (pvmdebmask & PDMMBOX)
566
pvmlogprintf("mb_tidy_reset() tid 0x%x\n", tid);
568
for (np = pvmmboxclasses->mc_link; np != pvmmboxclasses; np = np2) {
570
for (ep = np->mc_ent->me_link; ep != np->mc_ent; ep = ep2) {
572
/* mb_tidy() & mb_tidy_reset() could be in any order... */
573
if ( (ep->me_flags & PvmMboxPersistent)
574
&& ( ep->me_tid == tid
575
|| (!(ep->me_tid) && ep->me_savetid == tid) ) )
578
if (np2->mc_rlink != np)