1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 /****************************************************************************/
4 /* */
5 /* File: supp.c */
6 /* */
7 /* Purpose: support routines for Transfer Module */
8 /* */
9 /* Author: Klaus Birken */
10 /* Rechenzentrum Uni Stuttgart */
11 /* Universitaet Stuttgart */
12 /* Allmandring 30 */
13 /* 70550 Stuttgart */
14 /* internet: birken@rus.uni-stuttgart.de */
15 /* */
16 /* History: 93/11/30 kb begin (xfer.c) */
17 /* 95/03/21 kb added variable sized objects (XferCopyObjX) */
18 /* 95/04/05 kb V1.3: extracted from xfer.c */
19 /* */
20 /* Remarks: */
21 /* */
22 /****************************************************************************/
23
24 /****************************************************************************/
25 /* */
26 /* include files */
27 /* system include files */
28 /* application include files */
29 /* */
30 /****************************************************************************/
31
32 /* standard C library */
33 #include <config.h>
34 #include <cstdlib>
35 #include <cstdio>
36 #include <cassert>
37
38 #include <new>
39
40 #include <dune/uggrid/parallel/ddd/dddi.h>
41
42 USING_UG_NAMESPACE
43
44 /*
45 NOTE: all container-classes from ooppcc.h are implemented in this
46 source file by setting the following define.
47 */
48 #define ContainerImplementation
49 /* this is the hardliner version, for debugging only
50 #define _CHECKALLOC(ptr) assert(ptr!=NULL)
51 */
52 #define _CHECKALLOC(ptr) if (ptr==NULL) return (NULL)
53
54 #include "xfer.h"
55
56 /****************************************************************************/
57 /* */
58 /* definition of constants, macros */
59 /* */
60 /****************************************************************************/
61
62 #define ADDDATASEGM_SIZE 256
63 #define SIZESSEGM_SIZE 2048
64
65
66
67
68 /****************************************************************************/
69 /* */
70 /* data types */
71 /* */
72 /****************************************************************************/
73
74 namespace DDD {
75 namespace Xfer {
76
77 /* segment of AddDatas */
78 struct AddDataSegm
79 {
80 AddDataSegm *next;
81 int nItems;
82
83 XFERADDDATA item[ADDDATASEGM_SIZE];
84 };
85
86
87 /* segment of AddData-Sizes */
88 struct SizesSegm
89 {
90 SizesSegm *next;
91 int current;
92
93 int data[SIZESSEGM_SIZE];
94 };
95
96 } /* namespace Xfer */
97 } /* namespace DDD */
98 START_UGDIM_NAMESPACE
99
100 using namespace DDD::Xfer;
101
102 /****************************************************************************/
103 /* */
104 /* class member function implementations */
105 /* */
106 /****************************************************************************/
107
108 #define ClassName XICopyObj
109
110 /*
111 compare-method in order to eliminate double XICopyObj-items.
112 merge priorities from similar XICopyObj-items.
113
114 the items are sorted according to key (dest,gid),
115 all in ascending order. if dest and gid are equal,
116 we merge priorities and get a new priority together with
117 the information whether first item wins over second.
118 in both cases, we use the new priority for next comparison.
119
120 this implements rule XFER-C1.
121 */
Method(Compare)122 int Method(Compare) (ClassPtr item1, ClassPtr item2, const DDD::DDDContext* context)
123 {
124 DDD_PRIO newprio;
125 int ret;
126
127 if (item1->dest < item2->dest) return(-1);
128 if (item1->dest > item2->dest) return(1);
129
130 if (item1->gid < item2->gid) return(-1);
131 if (item1->gid > item2->gid) return(1);
132
133
134 /* items have equal gid and dest, so they are considered as equal. */
135 /* however, we must check priority, and patch both items with
136 the new priority after merge. */
137 ret = PriorityMerge(&context->typeDefs()[OBJ_TYPE(item1->hdr)],
138 item1->prio, item2->prio, &newprio);
139
140 item1->prio = newprio;
141
142 if (ret==PRIO_FIRST || ret==PRIO_UNKNOWN)
143 {
144 /* tell XferInitCopyInfo() that item is rejected */
145 item2->prio = PRIO_INVALID;
146 }
147 else
148 {
149 /* communicate new priority to XferInitCopyInfo() */
150 item2->prio = newprio;
151 }
152
153 return(0);
154 }
155
156
Method(Print)157 void Method(Print) (ParamThis _PRINTPARAMS)
158 {
159 fprintf(fp, "XICopyObj dest=%d gid=" DDD_GID_FMT " prio=%d\n",
160 This->dest, This->gid, This->prio);
161 }
162
163 #undef ClassName
164
165
166
167 /****************************************************************************/
168
169 #define ClassName XISetPrio
170
171 /*
172 compare-method in order to eliminate double XISetPrio-items.
173 merge priorities from similar XISetPrio-items.
174
175 the items are sorted according to key (gid),
176 all in ascending order. if both gids are equal,
177 we merge priorities and get a new priority together with
178 the information whether first item wins over second.
179 in both cases, we use the new priority for next comparison.
180
181 this implements rule XFER-P1.
182 */
Method(Compare)183 int Method(Compare) (ClassPtr item1, ClassPtr item2, const DDD::DDDContext* context)
184 {
185 DDD_PRIO newprio;
186 int ret;
187
188 /* ascending GID is needed for ExecLocalXI___ */
189 if (item1->gid < item2->gid) return(-1);
190 if (item1->gid > item2->gid) return(1);
191
192
193 /* items have equal gid and dest, so they are considered as equal. */
194 /* however, we must check priority, and patch both items with
195 the new priority after merge. */
196 ret = PriorityMerge(&context->typeDefs()[OBJ_TYPE(item1->hdr)],
197 item1->prio, item2->prio, &newprio);
198
199 item1->prio = item2->prio = newprio;
200
201
202 if (ret==PRIO_FIRST || ret==PRIO_UNKNOWN)
203 {
204 /* tell XferInitCopyInfo() that item is rejected */
205 item2->prio = PRIO_INVALID;
206 }
207 else
208 {
209 /* communicate new priority to XferInitCopyInfo() */
210 item2->prio = newprio;
211 }
212
213 return(0);
214 }
215
216
Method(Print)217 void Method(Print) (ParamThis _PRINTPARAMS)
218 {
219 fprintf(fp, "XISetPrio gid=" DDD_GID_FMT " prio=%d\n", This->gid, This->prio);
220 }
221
222 #undef ClassName
223
224
225 /****************************************************************************/
226
227
228 /*
229 include templates
230 */
231 #define T XIDelCmd
232 #define SLL_WithOrigOrder
233 #include "sll.ct"
234 #undef T
235
236 #define T XIDelObj
237 #include "sll.ct"
238 #undef T
239
240 #define T XINewCpl
241 #include "sll.ct"
242 #undef T
243
244 #define T XIOldCpl
245 #include "sll.ct"
246 #undef T
247
248
249
250 #define T XIAddCpl
251 #include "sll.ct"
252 #undef T
253
254 #define T XIDelCpl
255 #include "sll.ct"
256 #undef T
257
258 #define T XIModCpl
259 #include "sll.ct"
260 #undef T
261
262
263
264 /****************************************************************************/
265
266
NewAddDataSegm(DDD::DDDContext & context)267 static AddDataSegm *NewAddDataSegm(DDD::DDDContext& context)
268 {
269 auto& ctx = context.xferContext();
270 AddDataSegm *segm;
271
272 segm = (AddDataSegm *) OO_Allocate(sizeof(AddDataSegm));
273 if (segm==NULL)
274 throw std::bad_alloc();
275
276 segm->next = ctx.segmAddData;
277 ctx.segmAddData = segm;
278 segm->nItems = 0;
279
280 return(segm);
281 }
282
283
FreeAddDataSegms(DDD::DDDContext & context)284 static void FreeAddDataSegms(DDD::DDDContext& context)
285 {
286 auto& ctx = context.xferContext();
287 AddDataSegm *segm = ctx.segmAddData;
288 AddDataSegm *next = NULL;
289
290 while (segm!=NULL)
291 {
292 next = segm->next;
293 OO_Free (segm /*,sizeof(AddDataSegm)*/);
294
295 segm = next;
296 }
297
298 ctx.segmAddData = nullptr;
299 }
300
301
302 /****************************************************************************/
303
304
NewSizesSegm(DDD::DDDContext & context)305 static SizesSegm *NewSizesSegm(DDD::DDDContext& context)
306 {
307 auto& ctx = context.xferContext();
308 SizesSegm *segm;
309
310 segm = (SizesSegm *) OO_Allocate (sizeof(SizesSegm));
311 if (segm==NULL)
312 throw std::bad_alloc();
313
314 segm->next = ctx.segmSizes;
315 ctx.segmSizes = segm;
316 segm->current = 0;
317
318 return(segm);
319 }
320
321
FreeSizesSegms(DDD::DDDContext & context)322 static void FreeSizesSegms(DDD::DDDContext& context)
323 {
324 auto& ctx = context.xferContext();
325 SizesSegm *segm = ctx.segmSizes;
326 SizesSegm *next = NULL;
327
328 while (segm!=NULL)
329 {
330 next = segm->next;
331 OO_Free (segm /*,sizeof(SizesSegm)*/);
332
333 segm = next;
334 }
335
336 ctx.segmSizes = nullptr;
337 }
338
339
340 /****************************************************************************/
341
342
NewXIAddData(DDD::DDDContext & context)343 XFERADDDATA *NewXIAddData(DDD::DDDContext& context)
344 {
345 auto& ctx = context.xferContext();
346 AddDataSegm *segm = ctx.segmAddData;
347 XFERADDDATA *xa;
348
349 if (segm==NULL || segm->nItems==ADDDATASEGM_SIZE)
350 {
351 segm = NewAddDataSegm(context);
352 }
353
354 xa = &(segm->item[segm->nItems++]);
355 xa->next = ctx.theXIAddData->add;
356 ctx.theXIAddData->add = xa;
357
358 return(xa);
359 }
360
361
362
FreeAllXIAddData(DDD::DDDContext & context)363 void FreeAllXIAddData(DDD::DDDContext& context)
364 {
365 FreeAddDataSegms(context);
366 FreeSizesSegms(context);
367 }
368
369
370 /****************************************************************************/
371
AddDataAllocSizes(DDD::DDDContext & context,int cnt)372 int *AddDataAllocSizes (DDD::DDDContext& context, int cnt)
373 {
374 auto& ctx = context.xferContext();
375 SizesSegm *segm = ctx.segmSizes;
376 int *pos;
377
378 if (segm==NULL || segm->current+cnt>=SIZESSEGM_SIZE)
379 {
380 segm = NewSizesSegm(context);
381 }
382
383 pos = segm->data + segm->current;
384 segm->current += cnt;
385
386 return(pos);
387 }
388
389
390 /****************************************************************************/
391
392
393 /*
394 get quantitative resource usage
395 */
GetSizesXIAddData(const DDD::DDDContext & context,int * nSegms,int * nItems,size_t * alloc_mem,size_t * used_mem)396 void GetSizesXIAddData(const DDD::DDDContext& context, int *nSegms, int *nItems, size_t *alloc_mem, size_t *used_mem)
397 {
398 const auto& ctx = context.xferContext();
399 size_t allocated=0, used=0;
400 int ns=0, ni=0;
401
402 {
403 for (const AddDataSegm* segm=ctx.segmAddData; segm!=NULL; segm=segm->next)
404 {
405 /* count number of segments and number of items */
406 ns++;
407 ni+=segm->nItems;
408
409 /* compute memory usage */
410 allocated += sizeof(AddDataSegm);
411 used += (sizeof(AddDataSegm) -
412 (sizeof(XFERADDDATA)*(ADDDATASEGM_SIZE-segm->nItems)));
413 }
414 }
415
416 /* TODO: add resources for SizesSegm */
417
418
419 *nSegms = ns;
420 *nItems = ni;
421 *alloc_mem = allocated;
422 *used_mem = used;
423 }
424
425
426 /****************************************************************************/
427
428 END_UGDIM_NAMESPACE
429