2 Copyright © 1995-2002, The AROS Development Team. All rights reserved.
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>
18 #include <utility/tagitem.h>
19 #include <oop/server.h>
28 #include <aros/debug.h>
30 #define MYSERVERID "demoserver"
31 #define MYTIMERID "timer"
33 #define SERVERTASK_STACKSIZE 20000
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
);
79 struct ServerParam sp
;
81 #define NUM_INVOCATIONS 10000L
82 #define NUM_IF_INVOCATIONS 10000000L
84 int main (int argc
, char **argv
)
90 OOPBase
= OpenLibrary(AROSOOP_NAME
, 0);
93 D(bug("Got OOPBase\n"));
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
))
106 timercl
= MakeTimerClass();
107 printf("Timercl: %p\n", timercl
);
110 /* Create the server task */
111 struct Task
*servertask
;
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"));
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
},
130 struct TagItem mtags
[] =
132 {aMethod_TargetObject
, (IPTR
)timer
},
133 {aMethod_Message
, (IPTR
)&test_mid
},
134 {aMethod_MethodID
, test_mid
},
138 register OOP_Interface
*iftimer
;
139 m
= (OOP_Method
*)OOP_NewObject(NULL
, CLID_Method
, mtags
);
142 printf("Method object created, output: %ld\n",
145 OOP_DisposeObject((OOP_Object
*)m
);
150 D(bug("Local timer obj created\n"));
152 iftimer
= (OOP_Interface
*)OOP_NewObject(NULL
, CLID_Interface
, iftags
);
157 register OOP_Msg msg
= (OOP_Msg
)&test_mid
;
161 D(bug("iftimer object created\n"));
163 printf("Doing %ld invocations using interface objects\n",
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
);
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
)) )
220 D(bug("Server found: %p\n", server
));
222 if ( (timer
= Server_FindObject(server
, MYTIMERID
)) )
228 printf("Doing %ld invocations using IPC\n",
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
);
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)
281 src
->tv_usec
-= 1000000;
283 while(dest
->tv_usec
> 999999)
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;
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");
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
));
336 VOID
_Timer_PrintElapsed(
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(
354 OOP_Object
*o
, OOP_Msg msg
)
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
},
373 struct OOP_InterfaceDescr ifdescr
[] =
375 { methods
, "Timer", 4},
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
)},
392 tcl
= (OOP_Class
*)OOP_NewObject(NULL
, CLID_MIMeta
, tags
);
397 // OOP_AddClass(tcl);
403 VOID
FreeTimerClass(OOP_Class
*cl
)
405 OOP_DisposeObject((OOP_Object
*)cl
);
411 VOID
TaskEntryPoint(struct ServerParam
*p
)
415 BOOL success
= FALSE
;
418 struct TagItem server_tags
[] =
424 D(bug("Entering servertask...\n"));
426 server
= OOP_NewObject(NULL
, CLID_Server
, server_tags
);
429 D(bug("st: server created\n"));
430 if (OOP_AddServer(server
, MYSERVERID
))
435 struct TagItem timer_tags
[] =
439 D(bug("st: server added\n"));
441 timer
= OOP_NewObject(timercl
, NULL
, timer_tags
);
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
);
453 Server_RemoveObject(server
, MYTIMERID
);
457 OOP_DisposeObject(timer
);
460 OOP_RemoveServer(MYSERVERID
);
462 OOP_DisposeObject(server
);
471 D(bug("st: No success\n"));
472 Signal(p
->Caller
, 1L << p
->SigBit
);
478 struct Task
*CreateServerTask(APTR taskparams
)
483 task
= AllocMem(sizeof (struct Task
), MEMF_PUBLIC
|MEMF_CLEAR
);
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
);
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
;
501 task
->tc_SPReg
=(BYTE
*)task
->tc_SPLower
-SP_OFFSET
+ sizeof(APTR
);
502 *(APTR
*)task
->tc_SPLower
= taskparams
;
505 if(AddTask(task
, TaskEntryPoint
, NULL
) != NULL
)
507 /* Everything went OK */
510 FreeMem(stack
, SERVERTASK_STACKSIZE
);
512 FreeMem(task
,sizeof(struct Task
));