1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8
9 #include <dxconfig.h>
10
11
12 #include <dx/dx.h>
13 #include "exobject.h"
14 #include "config.h"
15 #include "log.h"
16 #include "graph.h"
17 #include "parse.h"
18
19 /* DXFree lists of GLOBAL objects only */
20 typedef struct {
21 lock_type lock;
22 gvar *gvarHead;
23 gvar *gvarTail;
24 } FreeList;
25 static FreeList *freeList;
26
27 static node *FuncFreeList = NULL;
28
29 #define INIT_GVARS 512 /* Number of gvars to allocate initially */
30
31 PFIP _dxd_EXO_default_methods[] =
32 {
33 _dxf__EXO_delete
34 };
35
36 static lock_type *allocLock;
37
38 #ifdef LEAK_DEBUG
39 EXObj head;
40 #endif
41
42
43 /*
44 * Initialize the executive's object facility.
45 */
46
47 Error
_dxf_EXO_init(void)48 _dxf_EXO_init (void)
49 {
50 #if 0
51 int i;
52 gvar *gvars;
53 #endif
54
55 freeList = (FreeList *)DXAllocateZero (sizeof (FreeList));
56 if (freeList == NULL)
57 return (ERROR);
58 if (DXcreate_lock (&freeList->lock, "exobj freeList") != OK)
59 return (ERROR);
60 allocLock = (lock_type *)DXAllocateZero (sizeof (lock_type));
61 if (DXcreate_lock (allocLock, "exobj freeList allocation") != OK)
62 return (ERROR);
63
64 #if 0
65 gvars = freeList->gvarHead = (gvar *)DXAllocateZero (INIT_GVARS * sizeof (gvar));
66 if (gvars == NULL)
67 return (ERROR);
68 for (i = 0; i < INIT_GVARS - 1; ++i)
69 {
70 if (DXcreate_lock (&gvars[i].object.lock, "exobj gvar") != OK)
71 return (ERROR);
72 gvars[i].next = &gvars[i+1];
73 }
74 freeList->gvarTail = &gvars[INIT_GVARS-1];
75 if (DXcreate_lock (&gvars[i].object.lock, "exobj gvar") != OK)
76 return (ERROR);
77 #endif
78
79 #ifdef LEAK_DEBUG
80 head = (EXObj) DXAllocateZero (sizeof (exo_object));
81 head->DBGnext = head->DBGprev = head;
82 #endif
83
84 return (OK);
85 }
86
87
88 /*
89 * DXFree the executive's object locking structures.
90 */
91
92 Error
_dxf_EXO_cleanup(void)93 _dxf_EXO_cleanup (void)
94 {
95 return (OK);
96 }
97
98 int
_dxf_EXO_compact(void)99 _dxf_EXO_compact (void)
100 {
101 int result;
102 EXO_Object obj;
103
104 DXlock (allocLock, 0);
105 DXlock (&freeList->lock, exJID);
106 result = freeList->gvarHead != NULL;
107 while (freeList->gvarHead)
108 {
109 if (freeList->gvarHead->next == NULL)
110 {
111 if (freeList->gvarHead->next == NULL)
112 freeList->gvarTail = NULL;
113 }
114 obj = (EXO_Object) freeList->gvarHead;
115 freeList->gvarHead = ((gvar *) obj)->next;
116 DXFree((Pointer) obj);
117 }
118 DXunlock (allocLock, 0);
119 DXunlock (&freeList->lock, exJID);
120
121 if (!result && exJID == 1)
122 {
123 result = FuncFreeList != NULL;
124 while (FuncFreeList != NULL)
125 {
126 obj = (EXObj) FuncFreeList;
127 FuncFreeList = FuncFreeList->next;
128 DXFree((Pointer) obj);
129 }
130 }
131 return (result);
132 }
133
134 /*
135 * Check a piece of data to make sure that it has the proper tag to be
136 * an executive object.
137 */
138
_dxf_EXOCheck(EXO_Object obj)139 Error _dxf_EXOCheck (EXO_Object obj)
140 {
141 if (obj && !((long)obj & 0x03) && obj->tag == EXO_TAG)
142 {
143 switch (obj->exclass)
144 {
145 case EXO_CLASS_DELETED:
146 case EXO_CLASS_FUNCTION:
147 case EXO_CLASS_GVAR:
148 case EXO_CLASS_TASK:
149 return (OK);
150
151 default:
152 break;
153 }
154 }
155
156 DXWarning ("#4610", obj);
157
158 DXqflush ();
159 abort(); /* Die here please */
160
161 return (ERROR);
162 }
163
164 /*
165 * Create a new object and use default method vector if new methods
166 * not specified
167 */
168
169 static EXO_Object
EXO_create_object_worker(EXO_Class exclass,int size,PFIP * methods,int local)170 EXO_create_object_worker (EXO_Class exclass, int size, PFIP *methods, int local)
171 {
172 EXO_Object obj;
173 int locked;
174
175 switch (exclass)
176 {
177 case EXO_CLASS_FUNCTION:
178 if (FuncFreeList == NULL)
179 obj = (EXObj) DXAllocateLocal (size);
180 else
181 {
182 obj = (EXObj) FuncFreeList;
183 FuncFreeList = FuncFreeList->next;
184 }
185 break;
186
187 case EXO_CLASS_GVAR:
188 DXlock (allocLock, 0);
189 if (freeList->gvarHead)
190 {
191 locked = freeList->gvarHead->next == NULL;
192 if (locked)
193 {
194 DXlock (&freeList->lock, exJID);
195 if (freeList->gvarHead->next == NULL)
196 freeList->gvarTail = NULL;
197 }
198 obj = (EXO_Object) freeList->gvarHead;
199 freeList->gvarHead = ((gvar *) obj)->next;
200 if (locked)
201 DXunlock (&freeList->lock, exJID);
202 DXunlock (allocLock, 0);
203 }
204 else
205 {
206 DXunlock (allocLock, 0);
207 obj = (EXO_Object) DXAllocate (size);
208 }
209 break;
210
211 default:
212 obj = (EXO_Object) (local ? DXAllocateLocal (size)
213 : DXAllocate (size));
214 break;
215 }
216
217
218 if (obj == NULL)
219 _dxf_ExDie ("_dxf_EXO_create_object: can't DXAllocate");
220
221 if (! local && DXcreate_lock (&obj->lock, "exec object") != OK)
222 _dxf_ExDie ("_dxf_EXO_create_object: can't create lock\n");
223
224 ExZero (obj + 1, size - sizeof (exo_object));
225
226 obj->tag = EXO_TAG;
227 obj->exclass = exclass;
228 obj->local = local;
229 obj->refs = 0;
230 obj->m.copy = FALSE;
231 obj->m.methods = methods ? methods : _dxd_EXO_default_methods;
232 obj->lastref = 0;
233
234 #ifdef LEAK_DEBUG
235 if (!local) {
236 obj->DBGnext = head->DBGnext;
237 obj->DBGprev = head;
238 head->DBGnext->DBGprev = obj;
239 head->DBGnext = obj;
240 }
241 #endif
242
243 return (obj);
244 }
245
246
_dxf_EXO_create_object(EXO_Class exclass,int size,PFIP * methods)247 EXO_Object _dxf_EXO_create_object (EXO_Class exclass, int size, PFIP *methods)
248 {
249 return (EXO_create_object_worker (exclass, size, methods, FALSE));
250 }
251
252
_dxf_EXO_create_object_local(EXO_Class exclass,int size,PFIP * methods)253 EXO_Object _dxf_EXO_create_object_local (EXO_Class exclass, int size, PFIP *methods)
254 {
255 return (EXO_create_object_worker (exclass, size, methods, TRUE));
256 }
257
258
259 /*
260 * DXDelete an object. Note that the delete macro has already decremented the
261 * reference count and decided the object should go away
262 */
_dxf_EXO_delete(EXO_Object obj)263 int _dxf_EXO_delete (EXO_Object obj)
264 {
265 int del = FALSE;
266 if (obj->refs == 0)
267 {
268 #ifdef LEAK_DEBUG
269 if (!obj->local) {
270 obj->DBGnext->DBGprev = obj->DBGprev;
271 obj->DBGprev->DBGnext = obj->DBGnext;
272 }
273 #endif
274 switch (obj->exclass)
275 {
276 case EXO_CLASS_FUNCTION:
277 ((node *) obj)->next = FuncFreeList;
278 FuncFreeList = (node *) obj;
279 break;
280
281 case EXO_CLASS_GVAR:
282 ((gvar *) obj)->next = NULL;
283 DXlock (&freeList->lock, exJID);
284 if (freeList->gvarTail)
285 freeList->gvarTail->next = (gvar *) obj;
286 else
287 freeList->gvarHead = (gvar *) obj;
288 freeList->gvarTail = (gvar *) obj;
289 DXunlock (&freeList->lock, exJID);
290 break;
291
292 default:
293 del = TRUE;
294 break;
295 }
296
297 obj->exclass = EXO_CLASS_DELETED;
298 if (obj->m.copy)
299 DXFree ((Pointer) obj->m.methods);
300 if (! obj->local)
301 DXdestroy_lock (&obj->lock);
302 if (del)
303 DXFree ((Pointer) obj);
304 }
305 else
306 {
307 DXWarning ("#4620", obj, obj->refs);
308 DXqflush ();
309 if (_dxd_exDebug)
310 abort(); /* Die here please */
311 }
312
313 return (0);
314 }
315
316 /*
317 * Default delete routine does nothing
318 */
_dxf__EXO_delete(EXO_Object obj)319 int _dxf__EXO_delete (EXO_Object obj)
320 {
321 return (OK);
322 }
323
324
325 #ifdef LEAK_DEBUG
326 void
PrintEXObj()327 PrintEXObj()
328 {
329 EXObj o;
330
331 for (o = head->DBGnext; o != head; o = o->DBGnext) {
332 switch (o->exclass) {
333 case EXO_CLASS_DELETED:
334 printf ("0x%08x (refs %d) EXO_CLASS_DELETED\n", o, o->refs);
335 break;
336 case EXO_CLASS_FUNCTION:
337 printf ("0x%08x (refs %d) EXO_CLASS_FUNCTION\n", o, o->refs);
338 break;
339 case EXO_CLASS_GVAR:
340 printf ("0x%08x (refs %d) EXO_CLASS_GVAR, type is %d\n",
341 o, o->refs, ((gvar*)o)->type);
342 break;
343 case EXO_CLASS_TASK:
344 printf ("0x%08x (refs %d) EXO_CLASS_TASK\n", o, o->refs);
345 break;
346 case EXO_CLASS_UNKNOWN:
347 printf ("0x%08x (refs %d) EXO_CLASS_UNKNOWN\n", o, o->refs);
348 break;
349 default:
350 printf ("0x%08x (refs %d) of unknown class %d\n", o, o->refs, o->exclass);
351 break;
352 }
353 }
354 }
355 #endif
356