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