prevent null pointer access crashes/memory trashing.
[AROS.git] / test / ooplib.c
blobbd9a53861211e64a986c53ea37472e9cad8156b0
1 /*
2 Copyright © 1995-2002, The AROS Development Team. All rights reserved.
3 $Id$
4 */
7 /* Prevent inclusion of <intuition/classes.h>,
8 * which is referenced in the amiga inline macros
9 * imported below by <proto/exec.h>.
11 #define INTUITION_CLASSES_H
13 #include <proto/oop.h>
14 #include <proto/exec.h>
15 #include <exec/libraries.h>
16 #include <exec/memory.h>
17 #include <oop/oop.h>
18 #include <utility/tagitem.h>
19 #include <oop/server.h>
21 #include <stdio.h>
22 #include <sys/time.h>
23 #include <unistd.h>
26 #define SDEBUG 0
27 #define DEBUG 0
28 #include <aros/debug.h>
30 #define MYSERVERID "demoserver"
31 #define MYTIMERID "timer"
33 #define SERVERTASK_STACKSIZE 20000
35 struct ServerParam
37 struct Task *Caller;
38 ULONG SigBit;
40 struct Task *CreateServerTask(APTR taskparams);
43 /* --------------------- */
44 /* Defines below would typically go into the includefile for the class */
45 #define CLID_Timer "timerclass"
47 #define IID_Timer "Timer"
48 #define moTimer_Start 0
49 #define moTimer_Stop 1
50 #define moTimer_PrintElapsed 2
51 #define moTimer_TestMethod 3
53 #define TimerBase (__ITimer)
54 #define M_Timer_Start (TimerBase + moTimer_Start)
55 #define M_Timer_Stop (TimerBase + moTimer_Stop)
56 #define M_Timer_PrintElapsed (TimerBase + moTimer_PrintElapsed)
57 #define M_Timer_TestMethod (TimerBase + moTimer_TestMethod)
60 // #define GLOBAL_CLASS
62 extern ULONG __OOPI_Timer;
64 /* -------------------------- */
66 struct Library *OOPBase;
68 OOP_Class *MakeTimerClass();
69 VOID FreeTimerClass(OOP_Class *cl);
71 ULONG __IMeta;
72 ULONG __ITimer;
73 ULONG __IMethod;
74 ULONG __IServer;
75 ULONG __IInterface;
77 OOP_Class *timercl;
79 struct ServerParam sp;
81 #define NUM_INVOCATIONS 10000L
82 #define NUM_IF_INVOCATIONS 10000000L
84 int main (int argc, char **argv)
86 SDInit();
90 OOPBase = OpenLibrary(AROSOOP_NAME, 0);
91 if (OOPBase)
93 D(bug("Got OOPBase\n"));
94 if (
95 ( __IMeta = OOP_GetAttrBase( IID_Meta ))
96 && ( __ITimer = OOP_GetAttrBase( IID_Timer ))
97 && ( __IMethod = OOP_GetAttrBase( IID_Method ))
98 && ( __IServer = OOP_GetAttrBase( IID_Server ))
99 && ( __IInterface = OOP_GetAttrBase( IID_Interface ))
104 D(bug("Got IDs\n"));
106 timercl = MakeTimerClass();
107 printf("Timercl: %p\n", timercl);
108 if (timercl)
110 /* Create the server task */
111 struct Task *servertask;
112 OOP_Object *timer;
113 struct TagItem tags[] = {{TAG_DONE, 0UL}};
115 D(bug("Creating new timer object\n"));
117 timer = OOP_NewObject(timercl, NULL, tags);
118 D(bug("timer object created\n"));
120 if (timer)
122 OOP_Method *m;
123 ULONG test_mid = OOP_GetMethodID(IID_Timer, moTimer_TestMethod);
124 struct TagItem iftags[] =
126 { aInterface_TargetObject, (IPTR)timer},
127 { aInterface_InterfaceID, (IPTR)IID_Timer},
128 { TAG_DONE, 0UL }
130 struct TagItem mtags[] =
132 {aMethod_TargetObject, (IPTR)timer },
133 {aMethod_Message, (IPTR)&test_mid },
134 {aMethod_MethodID, test_mid },
135 {TAG_DONE,}
138 register OOP_Interface *iftimer;
139 m = (OOP_Method *)OOP_NewObject(NULL, CLID_Method, mtags);
140 if (m)
142 printf("Method object created, output: %ld\n",
143 OOP_CallMethod(m));
145 OOP_DisposeObject((OOP_Object *)m);
150 D(bug("Local timer obj created\n"));
152 iftimer = (OOP_Interface *)OOP_NewObject(NULL, CLID_Interface, iftags);
153 if (iftimer)
155 ULONG test_mid;
157 register OOP_Msg msg = (OOP_Msg)&test_mid;
159 ULONG i;
161 D(bug("iftimer object created\n"));
163 printf("Doing %ld invocations using interface objects\n",
164 NUM_IF_INVOCATIONS);
166 test_mid = M_Timer_Start;
167 iftimer->callMethod(iftimer, (OOP_Msg)&test_mid);
169 test_mid = M_Timer_TestMethod;
171 for (i = 0; i < NUM_IF_INVOCATIONS; i ++)
173 iftimer->callMethod(iftimer, msg);
176 test_mid = M_Timer_Stop;
177 iftimer->callMethod(iftimer, (OOP_Msg)&test_mid);
179 printf("Time elapsed: ");
181 test_mid = M_Timer_PrintElapsed;
182 iftimer->callMethod(iftimer, (OOP_Msg)&test_mid);
184 test_mid = M_Timer_TestMethod;
185 printf ("Result of testmethod: %ld\n", iftimer->callMethod(iftimer, (OOP_Msg)&test_mid));
188 OOP_DisposeObject((OOP_Object *)iftimer);
191 OOP_DisposeObject(timer);
195 sp.Caller = FindTask(NULL);
197 sp.SigBit = AllocSignal(-1L);
201 D(bug("Creating server task\n"));
204 servertask = CreateServerTask(&sp);
205 if (servertask)
208 OOP_Object *server;
210 D(bug("server task created: %p\n", servertask));
212 Wait(1L << sp.SigBit);
213 D(bug("server task has initialized itself: %p\n", servertask));
216 if ( (server = OOP_FindServer(MYSERVERID)) )
218 OOP_Object *timer;
220 D(bug("Server found: %p\n", server));
222 if ( (timer = Server_FindObject(server, MYTIMERID)) )
224 ULONG test_mid;
226 ULONG i;
228 printf("Doing %ld invocations using IPC\n",
229 NUM_INVOCATIONS);
231 test_mid = OOP_GetMethodID(IID_Timer, moTimer_Start);
232 OOP_DoMethod(timer, (OOP_Msg)&test_mid);
234 test_mid = OOP_GetMethodID(IID_Timer, moTimer_TestMethod);
235 for (i = 0; i < NUM_INVOCATIONS; i ++)
237 OOP_DoMethod(timer, (OOP_Msg)&test_mid);
240 test_mid = OOP_GetMethodID(IID_Timer, moTimer_Stop);
241 OOP_DoMethod(timer, (OOP_Msg)&test_mid);
243 printf("Time elapsed: ");
245 test_mid = OOP_GetMethodID(IID_Timer, moTimer_PrintElapsed);
246 OOP_DoMethod(timer, (OOP_Msg)&test_mid);
248 test_mid = OOP_GetMethodID(IID_Timer, moTimer_TestMethod);
249 printf ("Result of testmethod: %ld\n", OOP_DoMethod(timer, (OOP_Msg)&test_mid));
258 FreeTimerClass(timercl);
262 CloseLibrary(OOPBase);
265 return (0);
270 struct TimerData
272 struct timeval start_time;
273 struct timeval elapsed_time;
276 VOID SubTime(struct timeval *dest, struct timeval *src)
278 while(src->tv_usec > 999999)
280 src->tv_sec++;
281 src->tv_usec -= 1000000;
283 while(dest->tv_usec > 999999)
285 dest->tv_sec++;
286 dest->tv_usec -= 1000000;
289 dest->tv_usec -= src->tv_usec;
290 dest->tv_sec -= src->tv_sec;
292 if(dest->tv_usec < 0)
294 dest->tv_usec += 1000000;
295 dest->tv_sec--;
298 return;
301 #ifdef GLOBAL_CLASS
302 Class *tcl;
303 #endif
305 VOID _Timer_Start(
306 #ifndef GLOBAL_CLASS
307 OOP_Class *tcl,
308 #endif
309 OOP_Object *o, OOP_Msg msg)
311 struct TimerData *data;
312 EnterFunc(bug("Timer::Start(o=%p)\n", o));
314 data = OOP_INST_DATA(tcl, o);
315 D(bug("data=%p\n", data));
317 gettimeofday(&(data->start_time), NULL);
319 ReturnVoid("Timer::Start");
322 VOID _Timer_Stop(
323 #ifndef GLOBAL_CLASS
324 OOP_Class *tcl,
325 #endif
326 OOP_Object *o, OOP_Msg msg)
328 struct TimerData *data = OOP_INST_DATA(tcl, o);
329 gettimeofday(&(data->elapsed_time), NULL);
331 SubTime(&(data->elapsed_time), &(data->start_time));
333 return;
336 VOID _Timer_PrintElapsed(
337 #ifndef GLOBAL_CLASS
338 OOP_Class *tcl,
339 #endif
340 OOP_Object *o, OOP_Msg msg)
342 struct TimerData *data = OOP_INST_DATA(tcl, o);
344 kprintf("%ld secs and %ld micros\n"
345 ,data->elapsed_time.tv_sec
346 ,data->elapsed_time.tv_usec);
350 IPTR _Timer_TestMethod(
351 #ifndef GLOBAL_CLASS
352 OOP_Class *tcl,
353 #endif
354 OOP_Object *o, OOP_Msg msg)
356 return (12345678);
360 OOP_Class *MakeTimerClass()
363 struct OOP_MethodDescr methods[] =
365 {(IPTR (*)())_Timer_Start, moTimer_Start},
366 {(IPTR (*)())_Timer_Stop, moTimer_Stop},
367 {(IPTR (*)())_Timer_PrintElapsed, moTimer_PrintElapsed},
368 {(IPTR (*)())_Timer_TestMethod, moTimer_TestMethod},
369 {NULL, 0UL}
373 struct OOP_InterfaceDescr ifdescr[] =
375 { methods, "Timer", 4},
376 { NULL, 0UL, 0UL}
379 struct TagItem tags[] =
381 {aMeta_SuperID, (IPTR)CLID_Root},
382 {aMeta_InterfaceDescr, (IPTR)ifdescr},
383 {aMeta_ID, (IPTR)CLID_Timer},
384 {aMeta_InstSize, (IPTR)sizeof (struct TimerData)},
385 {TAG_DONE, 0UL}
387 #ifndef GLOBAL_CLASS
388 OOP_Class *tcl;
389 #endif
392 tcl = (OOP_Class *)OOP_NewObject(NULL, CLID_MIMeta, tags);
395 if (tcl)
397 // OOP_AddClass(tcl);
400 return (tcl);
403 VOID FreeTimerClass(OOP_Class *cl)
405 OOP_DisposeObject((OOP_Object *)cl);
407 return;
411 VOID TaskEntryPoint(struct ServerParam *p)
413 OOP_Object *server;
415 BOOL success = FALSE;
418 struct TagItem server_tags[] =
420 { TAG_DONE, 0UL}
424 D(bug("Entering servertask...\n"));
426 server = OOP_NewObject(NULL, CLID_Server, server_tags);
427 if (server)
429 D(bug("st: server created\n"));
430 if (OOP_AddServer(server, MYSERVERID))
433 OOP_Object *timer;
435 struct TagItem timer_tags[] =
437 { TAG_DONE, 0UL}
439 D(bug("st: server added\n"));
441 timer = OOP_NewObject(timercl, NULL, timer_tags);
442 if (timer)
444 D(bug("st: timer created\n"));
445 if (Server_AddObject(server, timer, MYTIMERID))
447 D(bug("st: timer added to server\n"));
449 Signal(p->Caller, 1L << p->SigBit);
451 Server_Run(server);
453 Server_RemoveObject(server, MYTIMERID);
454 success = TRUE;
457 OOP_DisposeObject(timer);
460 OOP_RemoveServer(MYSERVERID);
462 OOP_DisposeObject(server);
468 /* Just in case */
469 if (!success)
471 D(bug("st: No success\n"));
472 Signal(p->Caller, 1L << p->SigBit);
474 return;
478 struct Task *CreateServerTask(APTR taskparams)
480 struct Task *task;
481 APTR stack;
483 task = AllocMem(sizeof (struct Task), MEMF_PUBLIC|MEMF_CLEAR);
484 if (task)
486 NEWLIST(&task->tc_MemEntry);
487 task->tc_Node.ln_Type=NT_TASK;
488 task->tc_Node.ln_Name="demoserver";
489 task->tc_Node.ln_Pri = 0;
491 stack=AllocMem(SERVERTASK_STACKSIZE, MEMF_PUBLIC);
492 if(stack != NULL)
494 task->tc_SPLower=stack;
495 task->tc_SPUpper=(BYTE *)stack + SERVERTASK_STACKSIZE;
497 #if AROS_STACK_GROWS_DOWNWARDS
498 task->tc_SPReg = (BYTE *)task->tc_SPUpper-SP_OFFSET - sizeof(APTR);
499 ((APTR *)task->tc_SPUpper)[-1] = taskparams;
500 #else
501 task->tc_SPReg=(BYTE *)task->tc_SPLower-SP_OFFSET + sizeof(APTR);
502 *(APTR *)task->tc_SPLower = taskparams;
503 #endif
505 if(AddTask(task, TaskEntryPoint, NULL) != NULL)
507 /* Everything went OK */
508 return (task);
510 FreeMem(stack, SERVERTASK_STACKSIZE);
512 FreeMem(task,sizeof(struct Task));
514 return (NULL);