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: cw.c */
6 /* */
7 /* Purpose: define global array with predefined control word entries */
8 /* */
9 /* Author: Peter Bastian */
10 /* Interdisziplinaeres Zentrum fuer Wissenschaftliches Rechnen */
11 /* Universitaet Heidelberg */
12 /* Im Neuenheimer Feld 368 */
13 /* 6900 Heidelberg */
14 /* Internet: bastian@iwr1.iwr.uni-heidelberg.de */
15 /* */
16 /* History: 11.01.95 begin, ug version 3.0 */
17 /* */
18 /* Remarks: */
19 /* */
20 /****************************************************************************/
21
22 #include <config.h>
23 #include <cstring>
24 #include <cstdio>
25
26 /* define this to exclude extern definition of global arrays */
27 #define __COMPILE_CW__
28
29
30 #include <dune/uggrid/ugdevices.h>
31 #include <dune/uggrid/low/architecture.h>
32 #include <dune/uggrid/low/debug.h>
33 #include <dune/uggrid/low/misc.h>
34
35 #include "algebra.h"
36 #include "refine.h"
37 #include "cw.h"
38
39 USING_UG_NAMESPACE
40 USING_UGDIM_NAMESPACE
41 using namespace PPIF;
42
43 /****************************************************************************/
44 /* */
45 /* defines in the following order */
46 /* */
47 /* compile time constants defining static data size (i.e. arrays) */
48 /* other constants */
49 /* macros */
50 /* */
51 /****************************************************************************/
52
53 #define CW_EDOBJ (BITWISE_TYPE(EDOBJ) | BITWISE_TYPE(LIOBJ))
54 /* take both edges and links in one */
55 #define CW_GROBJ BITWISE_TYPE(GROBJ)
56 #define CW_MGOBJ BITWISE_TYPE(MGOBJ)
57 #define CW_NDOBJ BITWISE_TYPE(NDOBJ)
58 #define CW_VEOBJ BITWISE_TYPE(VEOBJ)
59 #define CW_MAOBJ (BITWISE_TYPE(MAOBJ) | BITWISE_TYPE(COOBJ))
60
61 #define CW_VXOBJS (BITWISE_TYPE(IVOBJ) | BITWISE_TYPE(BVOBJ))
62 #define CW_ELOBJS (BITWISE_TYPE(IEOBJ) | BITWISE_TYPE(BEOBJ))
63 #define CW_GEOMOBJS (CW_VXOBJS | CW_ELOBJS | CW_NDOBJ | CW_EDOBJ | CW_GROBJ)
64 /* NOTE: CW_GEOMOBJS and GEOM_OBJECTS differ*/
65
66 /****************************************************************************/
67 /* */
68 /* data structures used in this source file (exported data structures are */
69 /* in the corresponding include file!) */
70 /* */
71 /****************************************************************************/
72
73 /** \brief Description of a control word predefines */
74 typedef struct {
75 INT used; /**< Used this entry */
76 const char *name; /**< Name string */
77 INT control_word_id; /**< Index in control_words */
78 UINT offset_in_object ; /**< Where in object is it ? */
79 INT objt_used; /**< Bitwise object ID */
80 } CONTROL_WORD_PREDEF;
81
82 /** \brief Description of a control entry predefines */
83 typedef struct {
84 INT used; /**< Used this entry */
85 const char *name; /**< Name string */
86 INT control_word; /**< Index of corresp. controlword */
87 INT control_entry_id; /**< Index in control_entries */
88 INT offset_in_word; /**< Shift in control word */
89 INT length; /**< Number of bits used */
90 INT objt_used; /**< Bitwise object ID */
91 } CONTROL_ENTRY_PREDEF;
92
93 typedef struct {
94
95 INT read; /**< Number of accesses to read */
96 INT write; /**< Number of accesses to write */
97 INT max; /**< Max value assigned to ce */
98
99 } CE_USAGE;
100
101 /****************************************************************************/
102 /* */
103 /* definition of exported global variables */
104 /* */
105 /****************************************************************************/
106
107 CONTROL_WORD NS_DIM_PREFIX control_words[MAX_CONTROL_WORDS];
108 CONTROL_ENTRY NS_DIM_PREFIX control_entries[MAX_CONTROL_ENTRIES];
109
110 /****************************************************************************/
111 /* */
112 /* definition of variables global to this source file only (static!) */
113 /* */
114 /****************************************************************************/
115
116 static CONTROL_WORD_PREDEF cw_predefines[MAX_CONTROL_WORDS] = {
117 CW_INIT(CW_USED,VECTOR_, CW_VEOBJ),
118 CW_INIT(CW_USED,MATRIX_, CW_MAOBJ),
119 CW_INIT(CW_USED,VERTEX_, CW_VXOBJS),
120 CW_INIT(CW_USED,NODE_, CW_NDOBJ),
121 CW_INIT(CW_USED,LINK_, CW_EDOBJ),
122 CW_INIT(CW_USED,EDGE_, CW_EDOBJ),
123 CW_INIT(CW_USED,ELEMENT_, CW_ELOBJS),
124 CW_INIT(CW_USED,FLAG_, CW_ELOBJS),
125 CW_INIT(CW_USED,PROPERTY_, CW_ELOBJS),
126 CW_INIT(CW_USED,GRID_, CW_GROBJ),
127 CW_INIT(CW_USED,GRID_STATUS_, CW_GROBJ),
128 CW_INIT(CW_USED,MULTIGRID_STATUS_, CW_MGOBJ),
129 CW_INIT_UNUSED,
130 CW_INIT_UNUSED,
131 CW_INIT_UNUSED,
132 CW_INIT_UNUSED,
133 CW_INIT_UNUSED,
134 CW_INIT_UNUSED,
135 CW_INIT_UNUSED,
136 CW_INIT_UNUSED,
137 };
138
139 static CONTROL_ENTRY_PREDEF ce_predefines[MAX_CONTROL_ENTRIES] = {
140 CE_INIT(CE_LOCKED, VECTOR_, VOTYPE_, CW_VEOBJ),
141 CE_INIT(CE_LOCKED, VECTOR_, VCOUNT_, CW_VEOBJ),
142 CE_INIT(CE_LOCKED, VECTOR_, VECTORSIDE_, CW_VEOBJ),
143 CE_INIT(CE_LOCKED, VECTOR_, VCLASS_, CW_VEOBJ),
144 CE_INIT(CE_LOCKED, VECTOR_, VDATATYPE_, CW_VEOBJ),
145 CE_INIT(CE_LOCKED, VECTOR_, VNCLASS_, CW_VEOBJ),
146 CE_INIT(CE_LOCKED, VECTOR_, VNEW_, CW_VEOBJ),
147 CE_INIT(CE_LOCKED, VECTOR_, VCCUT_, CW_VEOBJ),
148 CE_INIT(CE_LOCKED, VECTOR_, VTYPE_, CW_VEOBJ),
149 CE_INIT(CE_LOCKED, VECTOR_, VPART_, CW_VEOBJ),
150 CE_INIT(CE_LOCKED, VECTOR_, VCCOARSE_, CW_VEOBJ),
151 CE_INIT(CE_LOCKED, VECTOR_, FINE_GRID_DOF_, CW_VEOBJ),
152 CE_INIT(CE_LOCKED, VECTOR_, NEW_DEFECT_, CW_VEOBJ),
153 CE_INIT(CE_LOCKED, VECTOR_, VACTIVE_, CW_VEOBJ),
154
155 CE_INIT(CE_LOCKED, MATRIX_, MOFFSET_, CW_MAOBJ),
156 CE_INIT(CE_LOCKED, MATRIX_, MROOTTYPE_, CW_MAOBJ),
157 CE_INIT(CE_LOCKED, MATRIX_, MDESTTYPE_, CW_MAOBJ),
158 CE_INIT(CE_LOCKED, MATRIX_, MDIAG_, CW_MAOBJ),
159 CE_INIT(CE_LOCKED, MATRIX_, MSIZE_, CW_MAOBJ),
160 CE_INIT(CE_LOCKED, MATRIX_, MNEW_, CW_MAOBJ),
161 CE_INIT(CE_LOCKED, MATRIX_, CEXTRA_, CW_MAOBJ),
162 CE_INIT(CE_LOCKED, MATRIX_, MDOWN_, CW_MAOBJ),
163 CE_INIT(CE_LOCKED, MATRIX_, MUP_, CW_MAOBJ),
164 CE_INIT(CE_LOCKED, MATRIX_, MLOWER_, CW_MAOBJ),
165 CE_INIT(CE_LOCKED, MATRIX_, MUPPER_, CW_MAOBJ),
166 CE_INIT(CE_LOCKED, MATRIX_, MACTIVE_, CW_MAOBJ),
167
168 CE_INIT(CE_LOCKED, GENERAL_, OBJ_, (CW_GEOMOBJS | CW_VEOBJ | CW_MAOBJ)),
169 CE_INIT(CE_LOCKED, GENERAL_, USED_, (CW_GEOMOBJS | CW_VEOBJ | CW_MAOBJ)),
170 CE_INIT(CE_LOCKED, GENERAL_, THEFLAG_, (CW_GEOMOBJS | CW_VEOBJ)),
171 CE_INIT(CE_LOCKED, GENERAL_, LEVEL_, CW_GEOMOBJS),
172
173 CE_INIT(CE_LOCKED, VERTEX_, MOVE_, CW_VXOBJS),
174 CE_INIT(CE_LOCKED, VERTEX_, MOVED_, CW_VXOBJS),
175 CE_INIT(CE_LOCKED, VERTEX_, ONEDGE_, CW_VXOBJS),
176 CE_INIT(CE_LOCKED, VERTEX_, ONSIDE_, CW_VXOBJS),
177 CE_INIT(CE_LOCKED, VERTEX_, ONNBSIDE_, CW_VXOBJS),
178 CE_INIT(CE_LOCKED, VERTEX_, NOOFNODE_, CW_VXOBJS),
179
180 CE_INIT(CE_LOCKED, NODE_, NSUBDOM_, CW_NDOBJ),
181 CE_INIT(CE_LOCKED, NODE_, NPROP_, CW_NDOBJ),
182 CE_INIT(CE_LOCKED, NODE_, NCLASS_, CW_NDOBJ),
183 CE_INIT(CE_LOCKED, NODE_, NNCLASS_, CW_NDOBJ),
184 CE_INIT(CE_LOCKED, NODE_, MODIFIED_, (CW_NDOBJ | CW_GROBJ)),
185 CE_INIT(CE_LOCKED, NODE_, NTYPE_, CW_NDOBJ),
186
187 CE_INIT(CE_USED, LINK_, LOFFSET_, CW_EDOBJ),
188
189 CE_INIT(CE_USED, EDGE_, AUXEDGE_, CW_EDOBJ),
190 CE_INIT(CE_USED, EDGE_, PATTERN_, CW_EDOBJ),
191 CE_INIT(CE_USED, EDGE_, ADDPATTERN_, CW_EDOBJ),
192 CE_INIT(CE_USED, EDGE_, EDGENEW_, CW_EDOBJ),
193 CE_INIT(CE_USED, EDGE_, EDSUBDOM_, CW_EDOBJ),
194 CE_INIT(CE_USED, EDGE_, NO_OF_ELEM_, CW_EDOBJ),
195
196 CE_INIT(CE_USED, ELEMENT_, REFINE_, CW_ELOBJS),
197 CE_INIT(CE_USED, ELEMENT_, ECLASS_, CW_ELOBJS),
198 CE_INIT(CE_USED, ELEMENT_, NSONS_, CW_ELOBJS),
199 CE_INIT(CE_USED, ELEMENT_, REFINECLASS_, CW_ELOBJS),
200 CE_INIT(CE_USED, ELEMENT_, NEWEL_, CW_ELOBJS),
201 CE_INIT(CE_USED, ELEMENT_, TAG_, CW_ELOBJS),
202
203 CE_INIT(CE_USED, FLAG_, MARK_, CW_ELOBJS),
204 CE_INIT(CE_USED, FLAG_, COARSEN_, CW_ELOBJS),
205 CE_INIT(CE_USED, FLAG_, EBUILDCON_, CW_ELOBJS),
206 CE_INIT(CE_USED, FLAG_, DECOUPLED_, CW_ELOBJS),
207 CE_INIT(CE_USED, FLAG_, UPDATE_GREEN_, CW_ELOBJS),
208 CE_INIT(CE_USED, FLAG_, SIDEPATTERN_, CW_ELOBJS),
209 CE_INIT(CE_USED, FLAG_, MARKCLASS_, CW_ELOBJS),
210
211 CE_INIT(CE_USED, PROPERTY_, SUBDOMAIN_, CW_ELOBJS),
212 CE_INIT(CE_USED, PROPERTY_, NODEORD_, CW_ELOBJS),
213 CE_INIT(CE_USED, PROPERTY_, PROP_, CW_ELOBJS),
214
215 #ifdef ModelP
216 CE_INIT(CE_USED, VECTOR_, XFERVECTOR_, CW_VEOBJ),
217 CE_INIT(CE_USED, MATRIX_, XFERMATX_, CW_MAOBJ),
218 #else /* ModelP */
219 CE_INIT_UNUSED,
220 CE_INIT_UNUSED,
221 CE_INIT_UNUSED,
222 CE_INIT_UNUSED,
223 #endif /* ModelP */
224 CE_INIT_UNUSED,
225 CE_INIT_UNUSED,
226 CE_INIT_UNUSED,
227 CE_INIT_UNUSED,
228 };
229
230 static CE_USAGE ce_usage[MAX_CONTROL_ENTRIES];
231
232 /****************************************************************************/
233 /** \brief Print all control entries of an objects control word
234
235 * @param obj - object pointer
236 * @param offset - controlword offset in (UINT) in object
237
238 This function prints the contents of all control entries of an objects control word at a
239 given offset.
240
241 */
242 /****************************************************************************/
243
ListCWofObject(const void * obj,INT offset)244 void NS_DIM_PREFIX ListCWofObject (const void *obj, INT offset)
245 {
246 INT i,n,ce,last_ce,sub,min,cw_objt,oiw;
247
248 ASSERT(obj!=NULL);
249
250 cw_objt = BITWISE_TYPE(OBJT(obj));
251 sub = -1;
252 last_ce = -1;
253
254 /* print control word entries in ascending order of offsets in word */
255 do
256 {
257 min = INT_MAX;
258 for (i=0; i<MAX_CONTROL_ENTRIES; i++)
259 if (control_entries[i].used)
260 if (control_entries[i].objt_used & cw_objt)
261 if (control_entries[i].offset_in_object==offset)
262 {
263 oiw = control_entries[i].offset_in_word;
264 if ((oiw<min) && (oiw>=sub))
265 {
266 if ((oiw==sub) && (i<=last_ce))
267 continue;
268 ce = i;
269 min = oiw;
270 }
271 }
272 if (min==INT_MAX)
273 break;
274
275 n = CW_READ(obj,ce);
276 UserWriteF(" ce %s with offset in cw %3d: %10d\n",control_entries[i].name,min,n);
277 sub = min;
278 last_ce = ce;
279 }
280 while (true);
281
282 ASSERT(sub>=0);
283 }
284
285 /****************************************************************************/
286 /** \brief Print all control entries of all control words of an object
287
288 * @param obj - object pointer
289
290 This function prints the contents of all control entries of all control words
291 of the object. 'ListCWofObject' is called.
292 */
293 /****************************************************************************/
294
ListAllCWsOfObject(const void * obj)295 void NS_DIM_PREFIX ListAllCWsOfObject (const void *obj)
296 {
297 INT i,cw,last_cw,sub,min,cw_objt,offset;
298
299 ASSERT(obj!=NULL);
300
301 cw_objt = BITWISE_TYPE(OBJT(obj));
302 sub = -1;
303 last_cw = -1;
304
305 /* print control word contents in ascending order of offsets */
306 do
307 {
308 min = INT_MAX;
309 for (i=0; i<MAX_CONTROL_WORDS; i++)
310 if (control_words[i].used)
311 if (control_words[i].objt_used & cw_objt)
312 {
313 offset = control_words[i].offset_in_object;
314 if ((offset<min) && (offset>=sub))
315 {
316 if ((offset==sub) && (i<=last_cw))
317 continue;
318 cw = i;
319 min = offset;
320 }
321 }
322 if (min==INT_MAX)
323 break;
324
325 UserWriteF("cw %s with offset %3d:\n",control_words[cw].name,min);
326 ListCWofObject(obj,min);
327 sub = min;
328 last_cw = cw;
329 }
330 while (true);
331
332 ASSERT(sub>=0);
333 }
334
335 /****************************************************************************/
336 /** \brief Print used pattern of all control entries of an object types control word
337
338 * @param obj - object pointer
339 * @param offset - controlword offset in (UINT) in object
340 * @param myprintf - pointer to a printf function (maybe UserWriteF)
341
342 This function prints the used pattern of all control entries of an object types control word at a
343 given offset.
344 */
345 /****************************************************************************/
346
ListCWofObjectType(INT objt,INT offset,PrintfProcPtr myprintf)347 static void ListCWofObjectType (INT objt, INT offset, PrintfProcPtr myprintf)
348 {
349 INT i,ce,last_ce,sub,min,cw_objt,oiw;
350 char bitpat[33];
351
352 cw_objt = BITWISE_TYPE(objt);
353 sub = -1;
354 last_ce = -1;
355
356 /* print control word entries in ascending order of offsets in word */
357 do
358 {
359 min = INT_MAX;
360 for (i=0; i<MAX_CONTROL_ENTRIES; i++)
361 if (control_entries[i].used)
362 if (control_entries[i].objt_used & cw_objt)
363 if (control_entries[i].offset_in_object==offset)
364 {
365 oiw = control_entries[i].offset_in_word;
366 if ((oiw<min) && (oiw>=sub))
367 {
368 if ((oiw==sub) && (i<=last_ce))
369 continue;
370 ce = i;
371 min = oiw;
372 }
373 }
374 if (min==INT_MAX)
375 break;
376
377 INT_2_bitpattern(control_entries[ce].mask,bitpat);
378 myprintf(" ce %-20s offset in cw %3d, len %3d: %s\n",
379 control_entries[ce].name,
380 control_entries[ce].offset_in_word,
381 control_entries[ce].length,
382 bitpat);
383 sub = min;
384 last_ce = ce;
385 }
386 while (true);
387
388 if (sub==-1)
389 myprintf(" --- no ce found with objt %d\n",objt);
390 }
391
392 /****************************************************************************/
393 /** \brief Print used pattern of all control entries of all
394 control words of an object type
395
396 * @param obj - object pointer
397 * @param myprintf - pointer to a printf function (maybe UserWriteF)
398
399 This function prints the used pattern of all control entries of all control words
400 of an object type. 'ListCWofObjectType' is called.
401 */
402 /****************************************************************************/
403
ListAllCWsOfObjectType(INT objt,PrintfProcPtr myprintf)404 static void ListAllCWsOfObjectType (INT objt, PrintfProcPtr myprintf)
405 {
406 INT i,cw,last_cw,sub,min,cw_objt,offset;
407
408 cw_objt = BITWISE_TYPE(objt);
409 sub = -1;
410 last_cw = -1;
411
412 /* print control word contents in ascending order of offsets */
413 do
414 {
415 min = INT_MAX;
416 for (i=0; i<MAX_CONTROL_WORDS; i++)
417 if (control_words[i].used)
418 if (control_words[i].objt_used & cw_objt)
419 {
420 offset = control_words[i].offset_in_object;
421 if ((offset<min) && (offset>=sub))
422 {
423 if ((offset==sub) && (i<=last_cw))
424 continue;
425 cw = i;
426 min = offset;
427 }
428 }
429 if (min==INT_MAX)
430 break;
431
432 myprintf("cw %-20s with offset in object %3d (UINTs):\n",control_words[cw].name,min);
433 ListCWofObjectType(objt,min,myprintf);
434 sub = min;
435 last_cw = cw;
436 }
437 while (true);
438
439 if (sub==-1)
440 printf(" --- no cw found with objt %d\n",objt);
441 }
442
443 /****************************************************************************/
444 /** \brief Print used pattern of all control entries of all
445 control words of all object types
446
447 * @param obj - object pointer
448 * @param myprintf - pointer to a printf function (maybe UserWriteF)
449
450 This function prints the used pattern of all control entries of all control words
451 of all object types. 'ListAllCWsOfObjectType' is called.
452 */
453 /****************************************************************************/
454
ListAllCWsOfAllObjectTypes(PrintfProcPtr myprintf)455 void NS_DIM_PREFIX ListAllCWsOfAllObjectTypes (PrintfProcPtr myprintf)
456 {
457 ListAllCWsOfObjectType(IVOBJ,myprintf);
458 ListAllCWsOfObjectType(IEOBJ,myprintf);
459 ListAllCWsOfObjectType(EDOBJ,myprintf);
460 ListAllCWsOfObjectType(NDOBJ,myprintf);
461 ListAllCWsOfObjectType(VEOBJ,myprintf);
462 ListAllCWsOfObjectType(MAOBJ,myprintf);
463 ListAllCWsOfObjectType(GROBJ,myprintf);
464 ListAllCWsOfObjectType(MGOBJ,myprintf);
465 }
466
467 /****************************************************************************/
468 /** \brief Initialize control words
469
470 This function initializes the predefined control words.
471
472 * @return <ul>
473 * <li> GM_OK if ok </li>
474 * <li> GM_ERROR if error occured </li>
475 * </ul>
476 */
477 /****************************************************************************/
478
InitPredefinedControlWords(void)479 static INT InitPredefinedControlWords (void)
480 {
481 INT i,nused;
482 CONTROL_WORD *cw;
483 CONTROL_WORD_PREDEF *pcw;
484
485 /* clear everything */
486 memset(control_words,0,MAX_CONTROL_WORDS*sizeof(CONTROL_WORD));
487
488 nused = 0;
489 for (i=0; i<MAX_CONTROL_WORDS; i++)
490 if (cw_predefines[i].used)
491 {
492 pcw = cw_predefines+i;
493 ASSERT(pcw->control_word_id<MAX_CONTROL_WORDS);
494
495 nused++;
496 cw = control_words+pcw->control_word_id;
497 if (cw->used)
498 {
499 printf("redefinition of control word '%s'\n",pcw->name);
500 return(__LINE__);
501 }
502 cw->used = pcw->used;
503 cw->name = pcw->name;
504 cw->offset_in_object = pcw->offset_in_object;
505 cw->objt_used = pcw->objt_used;
506 }
507
508 if (nused!=GM_N_CW)
509 {
510 printf("InitPredefinedControlWords: nused=%d != GM_N_CW=%d\n",nused,GM_N_CW);
511 assert(false);
512 }
513
514 return (GM_OK);
515 }
516
517 /****************************************************************************/
518 /** \brief Initialize control word entries
519
520 This function initializes the predefined control word entries. Predefined
521 entries are not checked for overlap.
522
523 * @return <ul>
524 * <li> GM_OK if ok </li>
525 * <li> GM_ERROR if error occured </li>
526 * </ul>
527 */
528 /****************************************************************************/
529
InitPredefinedControlEntries(void)530 static INT InitPredefinedControlEntries (void)
531 {
532 CONTROL_ENTRY *ce,*test_ce;
533 CONTROL_WORD *cw;
534 CONTROL_ENTRY_PREDEF *pce,*test_pce;
535 INT i,j,k,offset,mask,error,nused;
536
537 /* clear everything */
538 memset(control_entries,0,MAX_CONTROL_ENTRIES*sizeof(CONTROL_ENTRY));
539
540 error = 0;
541 nused = 0;
542 for (i=0; i<MAX_CONTROL_ENTRIES; i++)
543 if (ce_predefines[i].used)
544 {
545 pce = ce_predefines+i;
546 ASSERT(pce->control_entry_id<MAX_CONTROL_ENTRIES);
547
548 nused++;
549 ce = control_entries+pce->control_entry_id;
550 if (ce->used)
551 {
552 printf("redefinition of control entry '%s'\n",pce->name);
553 return(__LINE__);
554 }
555 cw = control_words+pce->control_word;
556 ASSERT(cw->used);
557 ce->used = pce->used;
558 ce->name = pce->name;
559 ce->control_word = pce->control_word;
560 ce->offset_in_word = pce->offset_in_word;
561 ce->length = pce->length;
562 ce->objt_used = pce->objt_used;
563 ce->offset_in_object = cw->offset_in_object;
564 ce->mask = (POW2(ce->length)-1)<<ce->offset_in_word;
565 ce->xor_mask = ~ce->mask;
566
567 PRINTDEBUG(gm,1,("ceID %d used %d name %s cw %d\n",
568 i,ce->used,ce->name,ce->control_word));
569
570 ASSERT(ce->objt_used & cw->objt_used); /* ce and cw have! common objects */
571
572 /* set mask in all cws that use some of the ces objects and have the same offset than cw */
573 offset = ce->offset_in_object;
574 mask = ce->mask;
575 for (k=0; k<MAX_CONTROL_WORDS; k++)
576 {
577 cw = control_words+k;
578
579 if (!cw->used)
580 continue;
581 if (!(ce->objt_used & cw->objt_used))
582 continue;
583 if (cw->offset_in_object!=offset)
584 continue;
585
586 /* do other control entries overlap? */
587 if (cw->used_mask & mask)
588 {
589 IFDEBUG(gm,1)
590 printf("predef ctrl entry '%s' has overlapping bits with previous ctrl entries:\n",pce->name);
591 for (j=0; j<i; j++)
592 {
593 test_pce = ce_predefines+j;
594 test_ce = control_entries+test_pce->control_entry_id;
595 if (test_ce->objt_used & ce->objt_used)
596 if (test_ce->offset_in_object==offset)
597 if (test_ce->mask & mask)
598 printf(" '%s'",test_pce->name);
599
600 }
601 printf("\n");
602 ENDDEBUG
603 error++;
604 }
605 cw->used_mask |= mask;
606 }
607 }
608
609 IFDEBUG(gm,1)
610 ListAllCWsOfAllObjectTypes(printf);
611 ENDDEBUG
612
613 /* TODO: enable next lines for error control */
614 IFDEBUG(gm,1)
615 if (error)
616 return (__LINE__);
617 ENDDEBUG
618
619 if (nused!=REFINE_N_CE)
620 {
621 printf("InitPredefinedControlEntries: nused=%d != REFINE_N_CE=%d\n",nused,REFINE_N_CE);
622 assert(false);
623 }
624
625 return (GM_OK);
626 }
627
628
629 /****************************************************************************/
630 /** \brief Function to replace CW_READ macro and does extended error checks
631
632 * @param obj - object pointer
633 * @param ceID - control entry ID
634
635 This function is to replace the CW_READ and CW_READ_STATIC macros of gm.h and does extended
636 error checks:~
637 <ul>
638 <li> obj != NULL </li>
639 <li> HEAPFAULT </li>
640 <li> ceID in valid range </li>
641 <li> control entry used </li>
642 <li> the object type is checked (with the natural exception of the first SETOBJ access) </li>
643 </ul>
644 Additionally the read accesses to a control entry are counted.
645
646 CAUTION:
647 set #define _DEBUG_CW_ to replace CW_READ by ReadCW but be aware of the
648 slowing down of the program in this case (no large problems!).
649
650 @return
651 Number read from the control entry of the object
652 */
653 /****************************************************************************/
654
ReadCW(const void * obj,INT ceID)655 UINT NS_DIM_PREFIX ReadCW (const void *obj, INT ceID)
656 {
657 CONTROL_ENTRY *ce;
658 UINT off_in_obj,mask,i,off_in_wrd,cw,cw_objt;
659
660 ASSERT(obj!=NULL);
661
662 if ((ceID<0) || (ceID>=MAX_CONTROL_ENTRIES))
663 {
664 printf("ReadCW: ceID=%d out of range\n",ceID);
665 assert(false);
666 }
667
668 /* update statistics */
669 ce_usage[ceID].read++;
670
671 ce = control_entries+ceID;
672
673 if (!ce->used)
674 {
675 printf("ReadCW: ceID=%d unused\n",ceID);
676 assert(false);
677 }
678
679 cw_objt = BITWISE_TYPE(OBJT(obj));
680 if (!(cw_objt & ce->objt_used))
681 {
682 if (ce->name!=NULL)
683 printf("ReadCW: invalid objt %d for ce %s\n",OBJT(obj),ce->name);
684 else
685 printf("ReadCW: invalid objt %d for ce %d\n",OBJT(obj),ceID);
686 assert(false);
687 }
688
689 off_in_wrd = ce->offset_in_word;
690 off_in_obj = ce->offset_in_object;
691 mask = ce->mask;
692 cw = ((UINT *)(obj))[off_in_obj];
693 i = cw & mask;
694 i = i>>off_in_wrd;
695
696 return (i);
697 }
698
699 /****************************************************************************/
700 /** \brief Function to replace CW_WRITE macro and does extended error checks
701
702 * @param obj - object pointer
703 * @param ceID - control entry ID
704 * @param n - number to write to the objects control entry
705
706 This function is to replace the CW_WRITE and CW_WRITE_STATIC macros of gm.h and does extended
707 error checks:~
708 <ul>
709 <li> obj != NULL </li>
710 <li> HEAPFAULT </li>
711 <li> ceID in valid range </li>
712 <li> control entry used </li>
713 <li> the object type is checked </li>
714 <li> n small enough for length of control entry </li>
715 </ul>
716 Additionally the write accesses to a control entry are counted.
717
718 CAUTION:
719 set #define _DEBUG_CW_ to replace CW_WRITE by WriteCW but be aware of the
720 slowing down of the program in this case (no large problems!).
721
722 @return
723 Number read from the control entry of the object
724 */
725 /****************************************************************************/
726
WriteCW(void * obj,INT ceID,INT n)727 void NS_DIM_PREFIX WriteCW (void *obj, INT ceID, INT n)
728 {
729 CONTROL_ENTRY *ce;
730 UINT off_in_obj,mask,i,j,off_in_wrd,cw_objt,xmsk;
731 UINT *pcw;
732
733 ASSERT(obj!=NULL);
734
735 if ((ceID<0) || (ceID>=MAX_CONTROL_ENTRIES))
736 {
737 printf("WriteCW: ceID=%d out of range\n",ceID);
738 assert(false);
739 }
740
741 /* update statistics */
742 ce_usage[ceID].write++;
743 ce_usage[ceID].max = MAX(n,ce_usage[ceID].max);
744
745 ce = control_entries+ceID;
746
747 if (!ce->used)
748 {
749 printf("WriteCW: ceID=%d unused\n",ceID);
750 assert(false);
751 }
752
753 cw_objt = BITWISE_TYPE(OBJT(obj));
754
755 /* special: SETOBJT cannot be checked since at this point the OBJT is unknown of course */
756 if (cw_objt==BITWISE_TYPE(0))
757 {
758 if (ceID!=OBJ_CE)
759 if (cw_objt != ce->objt_used)
760 {
761 if (ce->name!=NULL)
762 printf("WriteCW: objt 0 but %s rather than expected SETOBJT access\n",ce->name);
763 else
764 printf("WriteCW: objt 0 but %d rather than expected SETOBJT access\n",ceID);
765 assert(false);
766 }
767 }
768 else if (!(cw_objt & ce->objt_used))
769 {
770 if (ce->name!=NULL)
771 printf("WriteCW: invalid objt %d for ce %s\n",OBJT(obj),ce->name);
772 else
773 printf("WriteCW: invalid objt %d for ce %d\n",OBJT(obj),ceID);
774 assert(false);
775 }
776
777 off_in_wrd = ce->offset_in_word;
778 off_in_obj = ce->offset_in_object;
779 mask = ce->mask;
780 xmsk = ce->xor_mask;
781 pcw = ((UINT *)(obj)) + off_in_obj;
782 i = (*pcw) & xmsk;
783 j = n<<off_in_wrd;
784
785 if (j>mask)
786 {
787 if (ce->name!=NULL)
788 printf("WriteCW: value=%d exceeds max=%d for %s\n",
789 n,POW2(ce->length)-1,ce->name);
790 else
791 printf("WriteCW: value=%d exceeds max=%d for %d\n",
792 n,POW2(ce->length)-1,ceID);
793 assert(false);
794 }
795
796 j = j & mask;
797
798 *pcw = i | j;
799 }
800
801 /****************************************************************************/
802 /** \brief Allocates space in object control words
803
804 * @param cw_id - id of a control word
805 * @param length - number of bits to allocate
806 * @param ce_id - returns identifier of control entry descriptor
807
808 This function allocates 'length' consecutive bits in the control word of an
809 object identified through the `control word id` 'cw_id'.
810 It returns '0' and a valid id in 'ce_id' if space was available.
811 The 'ce_id' can be used to read and write the requested bits with the
812 'CW_READ' and 'CW_WRITE' macros as in the following example.
813
814 The control word ids of all UG objects are defined in 'gm.h' and usually
815 have the name `<object>`'_CW', except e.g. the 'ELEMENT' which has three
816 words that are used bitwise.
817
818 EXAMPLE:
819
820 The following code fragment allocates 'NORDER_LEN' bits in the 'flag' word
821 of the 'ELEMENT' structure.
822
823 \verbatim
824 INT ce_NORDER;
825
826 if (AllocateControlEntry(FLAG_CW,NORDER_LEN,&ce_NORDER) != GM_OK) return (1);
827 \endverbatim
828
829 The following macros then read and write the requested bits
830
831 \verbatim
832 *#define NORDER(p) CW_READ(p,ce_NORDER)
833 *#define SETNORDER(p,n) CW_WRITE(p,ce_NORDER,n)
834 \endverbatim
835
836
837 @return
838 </ul>
839 <li> GM_OK if ok </li>
840 <li> GM_ERROR if error occured. </li>
841 </ul>
842 */
843 /****************************************************************************/
844
AllocateControlEntry(INT cw_id,INT length,INT * ce_id)845 INT NS_DIM_PREFIX AllocateControlEntry (INT cw_id, INT length, INT *ce_id)
846 {
847 INT free, i, offset;
848 CONTROL_ENTRY *ce;
849 CONTROL_WORD *cw;
850 UINT mask;
851
852 /* check input */
853 if ((length<0)||(length>=32)) return(GM_ERROR);
854 if ((cw_id<0)||(cw_id>=MAX_CONTROL_WORDS)) return(GM_ERROR);
855
856 /* it is sufficient to check only the control entries control word
857 multiple object types are only allowed for predefines */
858 cw = control_words+cw_id;
859
860 /* find unused entry */
861 for (i=0; i<MAX_CONTROL_ENTRIES; i++)
862 if (!control_entries[i].used) break;
863 if (i==MAX_CONTROL_ENTRIES) return(GM_ERROR);
864 free = i;
865 ce = control_entries+free;
866
867 /* lets see if enough consecutive bits are available */
868 mask = POW2(length)-1;
869 for (i=0; i<=32-length; i++)
870 {
871 if ((mask&cw->used_mask)==0) break;
872 mask <<= 1;
873 }
874 if (i>32-length) return(GM_ERROR);
875 offset = i;
876
877 /* fill new entry */
878 *ce_id = free;
879 ce->used = 1;
880 ce->control_word = cw_id;
881 ce->offset_in_object = cw->offset_in_object;
882 ce->offset_in_word = offset;
883 ce->length = length;
884 ce->mask = mask;
885 ce->xor_mask = ~mask;
886 ce->name = NULL;
887 ce->objt_used = cw->objt_used;
888
889 /* remember used bits */
890 cw->used_mask |= mask;
891
892 /* ok, exit */
893 return(GM_OK);
894 }
895
896 /****************************************************************************/
897 /** \brief Frees space in object control words
898
899 * @param ce_id - control entry descriptor to free
900
901 This function frees space in object control words that has been allocated
902 with 'AllocateControlEntry'.
903
904 @return <ul>
905 <li> GM_OK if ok </li>
906 <li> GM_ERROR if error occured. </li>
907 </ul>
908 */
909 /****************************************************************************/
910
FreeControlEntry(INT ce_id)911 INT NS_DIM_PREFIX FreeControlEntry (INT ce_id)
912 {
913 CONTROL_ENTRY *ce;
914 CONTROL_WORD *cw;
915
916 /* check parameter */
917 if ((ce_id<0)||(ce_id>=MAX_CONTROL_ENTRIES)) return(GM_ERROR);
918 ce = control_entries+ce_id;
919 cw = control_words+ce->control_word;
920
921 /* check if locked */
922 if (ce->used == 2)
923 return(GM_ERROR);
924
925 /* free used bits */
926 cw->used_mask &= ce->xor_mask;
927
928 /* free control entry */
929 ce->used = 0;
930
931 /* ok, exit */
932 return(GM_OK);
933 }
934
935 /****************************************************************************/
936 /** \brief Init cw.c file
937
938 This function initializes the control word manager.
939
940 @return <ul>
941 <li> GM_OK if ok </li>
942 <li> > 0 line in which error occured. </li>
943 </ul>
944 */
945 /****************************************************************************/
946
InitCW(void)947 INT NS_DIM_PREFIX InitCW (void)
948 {
949 if (InitPredefinedControlWords())
950 return (__LINE__);
951 if (InitPredefinedControlEntries())
952 return (__LINE__);
953
954 #ifdef _DEBUG_CW_
955 ResetCEstatistics();
956 #endif
957
958 return (GM_OK);
959 }
960