doc: Add serial to list of ci file reserved words
[charm.git] / src / conv-core / msgmgr.c
1
2 #include <stdlib.h>
3 #include <converse.h>
4
5 #define CmiAlloc  malloc
6 #define CmiFree   free
7
8 typedef struct CmmEntryStruct *CmmEntry;
9
10 struct CmmEntryStruct
11 {
12   CmmEntry next;
13   void    *msg;
14   int      ntags;
15   int      tags[1];
16 };
17
18 struct CmmTableStruct
19 {
20   CmmEntry  first;
21   CmmEntry *lasth;
22 };
23
24
25 CmmTable CmmNew()
26 {
27   CmmTable result = (CmmTable)CmiAlloc(sizeof(struct CmmTableStruct));
28   result->first = 0;
29   result->lasth = &(result->first);
30   return result;
31 }
32
33 void CmmFree(t)
34 CmmTable t;
35 {
36   if (t==NULL) return;
37 #if (!defined(_FAULT_MLOG_) && !defined(_FAULT_CAUSAL_))    
38   if (t->first!=NULL) CmiAbort("Cannot free a non-empty message table!");
39 #endif
40   CmiFree(t);
41 }
42
43 /* free all table entries but not the space pointed by "msg" */
44 void CmmFreeAll(CmmTable t){
45     CmmEntry cur;
46     if(t==NULL) return;
47     cur = t->first;
48     while(cur){
49         CmmEntry toDel = cur;
50         cur = cur->next;
51         CmiFree(toDel);
52     }
53 }
54
55 void CmmPut(t, ntags, tags, msg)
56 CmmTable t;
57 int ntags;
58 int *tags;
59 void *msg;
60 {
61   int i;
62   CmmEntry e=(CmmEntry)CmiAlloc(sizeof(struct CmmEntryStruct)+(ntags*sizeof(int)));
63   e->next = 0;
64   e->msg = msg;
65   e->ntags = ntags;
66   for (i=0; i<ntags; i++) e->tags[i] = tags[i];
67   *(t->lasth) = e;
68   t->lasth = &(e->next);
69 }
70
71 static int CmmTagsMatch(ntags1, tags1, ntags2, tags2)
72 int ntags1; int *tags1; int ntags2; int *tags2;
73 {
74   int ntags = ntags1;
75   if (ntags1 != ntags2) return 0;
76   while (1) {
77     int tag1, tag2;
78     if (ntags == 0) return 1;
79     ntags--;
80     tag1 = *tags1++;
81     tag2 = *tags2++;
82     if (tag1==tag2) continue;
83     if (tag1==CmmWildCard) continue;
84     if (tag2==CmmWildCard) continue;
85     return 0;
86   }
87 }
88
89 void *CmmFind(t, ntags, tags, rtags, del)
90 CmmTable t;
91 int ntags;
92 int *tags;
93 int *rtags;
94 int del;
95 {
96   CmmEntry *enth; CmmEntry ent; void *msg; int i;
97 /* added by Chao Mei in case that t is already freed
98   which happens in ~ampi() when doing out-of-core emulation for AMPI programs */
99   if(t==NULL) return NULL;
100
101   enth = &(t->first);
102   while (1) {
103     ent = (*enth);
104     if (ent==0) return 0;
105     if (CmmTagsMatch(ntags, tags, ent->ntags, ent->tags)) {
106       if (rtags) for (i=0; i<ntags; i++) rtags[i] = ent->tags[i];
107       msg = ent->msg;
108       if (del) {
109         CmmEntry next = ent->next;
110         (*enth) = next;
111         if (next == 0) t->lasth = enth;
112         CmiFree(ent);
113       }
114       return msg;
115     }
116     enth = &(ent->next);
117   }
118 }
119
120 /* match the first ntags tags and return the last tag */
121 int CmmGetLastTag(t,ntags,tags)
122 CmmTable t;
123 int ntags;
124 int* tags;
125 {
126   CmmEntry *enth; CmmEntry ent;
127   enth = &(t->first);
128   while (1) {
129     ent = (*enth);
130     if (ent==0) return -1;
131     if (CmmTagsMatch(ntags, tags, ntags, ent->tags)) {
132       return (ent->tags[ent->ntags-1]);
133     }
134     enth = &(ent->next);
135   }
136   return -1;
137 }
138
139 int CmmEntries(t)
140 CmmTable t;
141 {
142   int n = 0;
143   CmmEntry e = t->first;
144   while (e) {
145     e = e->next;
146     n++;
147   }
148   return n;
149 }
150
151
152 CmmTable CmmPup(pup_er p, CmmTable t, CmmPupMessageFn msgpup)
153 {
154   int nentries;
155
156   if(!pup_isUnpacking(p))
157   {
158     CmmEntry e = t->first, doomed;
159     nentries = CmmEntries(t);
160     pup_int(p, &nentries);
161     while(e) {
162       pup_int(p, &(e->ntags));
163       pup_ints(p, e->tags, e->ntags);
164       msgpup(p,&e->msg);
165       doomed=e;
166       e = e->next;
167       if (pup_isDeleting(p)) 
168         CmiFree(doomed);
169     }
170     if(pup_isDeleting(p)) 
171     { /* We've now deleted all the links */
172       t->first=NULL;
173       CmmFree(t);
174       return 0;
175     } else
176       return t;
177   }
178   if(pup_isUnpacking(p))
179   {
180     int i;
181     t = CmmNew();
182     pup_int(p, &nentries);
183     for(i=0;i<nentries;i++)
184     {
185       int ntags, *tags;
186       void *msg;
187       pup_int(p, &ntags);
188       tags = (int*) malloc(ntags*sizeof(int));
189       pup_ints(p, tags, ntags);
190       msgpup(p,&msg);
191       CmmPut(t, ntags, tags, msg);
192       free(tags);
193     }
194     return t;
195   }
196   return NULL;/*<- never executed*/
197 }
198