Added LogMessage@Test; added siCommonGetMessage function to sicommon interface
[spandex:spandex.git] / sct / iphone / src / iphone_sicommon.c
1 /*\r
2  * Spandex benchmark and test framework.\r
3  *\r
4  * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).\r
5  *\r
6  * Contact: Kari J. Kangas <kari.j.kangas@nokia.com>\r
7  *\r
8  *   This framework is free software; you can redistribute it and/or modify it\r
9  * under the terms of the GNU Lesser General Public License as published by the\r
10  * Free Software Foundation, version 2.1 of the License.\r
11  *\r
12  *   This framework is distributed in the hope that it will be useful, but\r
13  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License\r
15  * for more details.\r
16  *\r
17  *   You should have received a copy of the GNU Lesser General Public License\r
18  * along with this framework; if not, see <http://www.gnu.org/licenses/>.\r
19  *\r
20  */\r
21 \r
22 /* */\r
23 #include <stdio.h>\r
24 #include <stdlib.h>\r
25 #include <time.h>\r
26 #include <sys/time.h>\r
27 #include <assert.h>\r
28 #include <string.h>\r
29 #include <unistd.h>\r
30 #include <stdarg.h>\r
31 \r
32 #include "iphone_globals.h"\r
33 \r
34 /* Includes from Spandex core */\r
35 #include "sct_sicommon.h"\r
36 #include "sct_utils.h"\r
37 #include "sct_module.h"\r
38 \r
39 #if defined( INCLUDE_AGL_MODULE )\r
40 # include "sct_aglmodule.h"\r
41 #endif  /* defined( INCLUDE_AGL_MODULE ) */\r
42 \r
43 #define         SCT_SICOMMON_IPHONE_CONTEXT                             0x1234\r
44 #define         OUTPUT_BUFFER_SIZE                                              1024\r
45 \r
46 SCTLog*         gErrorLog                                                               = NULL;  \r
47 char            gOutputBuffer[ OUTPUT_BUFFER_SIZE ];\r
48 int                     gOutputSize                                                             = 0;\r
49 void*           gSingleton                                                              = NULL;\r
50 \r
51 /* ---------------------------------------------------------------------- */\r
52 /*!\r
53  *\r
54  *\r
55  *\r
56  */\r
57 void* siCommonGetContext( void )\r
58 {\r
59         return ( void* )( SCT_SICOMMON_IPHONE_CONTEXT );\r
60 }\r
61 \r
62 /* ---------------------------------------------------------------------- */\r
63 /*!\r
64  *\r
65  *\r
66  *\r
67  */\r
68 const char* siCommonQuerySystemString( void* context, SCTSystemString id )\r
69 {\r
70         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );    \r
71     \r
72     switch( id )\r
73     {\r
74     case SCT_SYSSTRING_DEVICE_TYPE:\r
75         return "iPhone";\r
76 \r
77     case SCT_SYSSTRING_CPU:\r
78         return "<Unknown>";\r
79         \r
80     case SCT_SYSSTRING_OS:\r
81         return "iOS";\r
82         \r
83     default:\r
84         SCT_ASSERT_ALWAYS( 0 );\r
85         return NULL;\r
86     }\r
87 }\r
88 \r
89 /* ---------------------------------------------------------------------- */\r
90 /*!\r
91  *\r
92  *\r
93  *\r
94  */\r
95 size_t siCommonQueryMemoryAttribute( void* context, SCTMemoryAttribute id )\r
96 {\r
97         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
98     SCT_USE_VARIABLE( id );\r
99     \r
100 #if defined( SCT_DEBUG )\r
101     siCommonDebugPrintf( context, "SPANDEX: siCommonQueryMemoryAttribute not implemented" );\r
102 #endif  /* defined( SCT_DEBUG ) */\r
103     \r
104     return 0;\r
105 }\r
106 \r
107 /* ---------------------------------------------------------------------- */\r
108 /*!\r
109  *\r
110  *\r
111  *\r
112  */\r
113 unsigned long siCommonGetTimerFrequency( void* context )\r
114 {\r
115         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
116 \r
117         return 1000000; /* Microseconds */\r
118 }\r
119 \r
120 /* ---------------------------------------------------------------------- */\r
121 /*!\r
122  *\r
123  *\r
124  *\r
125  */\r
126 unsigned long siCommonGetTimerTick( void* context )\r
127 {\r
128         struct timeval  tv;\r
129         \r
130         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
131 \r
132         gettimeofday( &tv, NULL );\r
133         \r
134         return ( unsigned long )( tv.tv_sec * 1000000 + tv.tv_usec );   /* Microseconds */\r
135 }\r
136 \r
137 /* ---------------------------------------------------------------------- */\r
138 /*!\r
139  *\r
140  *\r
141  *\r
142  */\r
143 void siCommonDebugPrintf( void* context, const char* fmt, ... )\r
144 {\r
145         va_list ap;\r
146 \r
147         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );    \r
148     SCT_ASSERT_ALWAYS( fmt != NULL );\r
149 \r
150         va_start( ap, fmt );\r
151         vprintf( fmt, ap );\r
152         va_end( ap );\r
153 \r
154     printf( "\n" );\r
155 }\r
156 \r
157 /* ---------------------------------------------------------------------- */\r
158 /*!\r
159  *\r
160  *\r
161  *\r
162  */\r
163 void siCommonWarningMessage( void* context, const char* warningMessage )\r
164 {\r
165         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
166     \r
167     if( gOutputFile )\r
168     {\r
169         siCommonFlushOutput( context );\r
170         fprintf( gOutputFile, "#SPANDEX WARNING: %s\n", warningMessage );\r
171         fflush( gOutputFile );     \r
172     }\r
173     \r
174     printf( "SPANDEX WARNING: %s\n", warningMessage );\r
175 }\r
176 \r
177 \r
178 /* ---------------------------------------------------------------------- */\r
179 /*!\r
180  *\r
181  *\r
182  *\r
183  */\r
184 void siCommonErrorMessage( void* context, const char* errorMessage )\r
185 {\r
186         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
187 \r
188         if( gOutputFile )\r
189     {\r
190                 siCommonFlushOutput( context );\r
191         fprintf( gOutputFile, "SPANDEX ERROR: %s\n", errorMessage );\r
192                 fflush( gOutputFile );     \r
193     }\r
194   \r
195         printf( "SPANDEX error: %s.\n", errorMessage );\r
196 }\r
197 \r
198 /* ---------------------------------------------------------------------- */\r
199 /*!\r
200  *\r
201  *\r
202  *\r
203  */\r
204 SCTLog* siCommonGetErrorLog( void* context )\r
205 {\r
206         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
207 \r
208         return gErrorLog;\r
209 }\r
210 \r
211 /* ---------------------------------------------------------------------- */\r
212 /*!\r
213  *\r
214  *\r
215  *\r
216  */\r
217 void siCommonSetErrorLog( void* context, SCTLog* log )\r
218 {\r
219         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
220 \r
221         gErrorLog = log;\r
222 }\r
223 \r
224 /* ---------------------------------------------------------------------- */\r
225 /*!\r
226  *\r
227  *\r
228  *\r
229  */\r
230 void siCommonProgressMessage( void* context, int totalBenchmark, int currentBenchmark, int currentRepeat, const char* benchmarkName )\r
231 {\r
232         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
233   \r
234         printf( "Benchmark %d/%d, %d: %s.\n", currentBenchmark, totalBenchmark, currentRepeat, benchmarkName );\r
235 }\r
236 \r
237 /* ---------------------------------------------------------------------- */\r
238 /*!\r
239  *\r
240  * \r
241  *\r
242  */\r
243 void siCommonAssert( void* context, void* exp, void* file, unsigned int line )\r
244 {\r
245         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
246 \r
247         if( gOutputFile )\r
248     {\r
249                 siCommonFlushOutput( context );\r
250                 fprintf( gOutputFile, \r
251                                  "\nSpandex assert failed.\nExpresion: ( %s )\nFile: %s\nLine: %d\n",\r
252                                  ( char* )exp, ( char* )file, ( int )line ); \r
253                 fflush( gOutputFile );\r
254     }\r
255 \r
256         printf( "\nSpandex assert failed.\nExpresion: ( %s )\nFile: %s\nLine: %d\n",  ( char* )exp, ( char* )file, ( int )line ); \r
257         assert( 0 );\r
258 }\r
259 \r
260 /* ---------------------------------------------------------------------- */\r
261 /*!\r
262  * \r
263  *\r
264  */\r
265 void* siCommonMemoryAlloc( void* context, unsigned int size )\r
266 {\r
267         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
268 \r
269         return malloc( size );\r
270 }\r
271 \r
272 /* ---------------------------------------------------------------------- */\r
273 /*!\r
274  * \r
275  *\r
276  */\r
277 void* siCommonMemoryRealloc( void* context, void* data, unsigned int size )\r
278 {\r
279         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
280 \r
281         return realloc( data, size );\r
282 }\r
283 \r
284 /* ---------------------------------------------------------------------- */\r
285 /*!\r
286  *\r
287  *\r
288  */\r
289 void siCommonMemoryFree( void* context, void* memblock )\r
290 {\r
291         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
292 \r
293         free( memblock );\r
294 }\r
295 \r
296 /* ---------------------------------------------------------------------- */\r
297 /*!\r
298  *\r
299  *\r
300  *\r
301  */\r
302 char siCommonReadChar( void* context )\r
303 {\r
304         char    ch;\r
305 \r
306         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
307         \r
308         if( gInputFile == NULL )\r
309         {\r
310                 SCT_ASSERT( gBenchmarkSuite != NULL );\r
311                 return *gBenchmarkSuite++;\r
312         }\r
313         else\r
314         {\r
315                 SCT_ASSERT( gInputFile != NULL );\r
316 \r
317                 return ( fread( &ch, sizeof( char ), 1, gInputFile ) == 1 ) ? ch : SCT_END_OF_INPUT;\r
318         }\r
319 }\r
320 /* ---------------------------------------------------------------------- */\r
321 /*!\r
322  *\r
323  * \r
324  *\r
325  */\r
326 int siCommonWriteChar( void* context, char aCh )\r
327 {\r
328         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
329 \r
330         gOutputBuffer[ gOutputSize++ ] = aCh;\r
331         if( gOutputSize >= OUTPUT_BUFFER_SIZE )\r
332     {\r
333                 return siCommonFlushOutput( context );\r
334     }\r
335         else\r
336         {\r
337                 return 1;\r
338     }\r
339 }\r
340 \r
341 /* ---------------------------------------------------------------------- */\r
342 /*!\r
343  *\r
344  * \r
345  *\r
346  */\r
347 int siCommonFlushOutput( void* context )\r
348 {\r
349         int     n;\r
350 \r
351         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
352         SCT_ASSERT( gOutputFile != NULL );\r
353 \r
354         if( gOutputSize == 0 ) // Beware empty buffer\r
355         {\r
356                 fflush( gOutputFile );  \r
357                 return 1;\r
358         }\r
359         \r
360         n = fwrite( gOutputBuffer, gOutputSize, 1, gOutputFile );\r
361         gOutputSize = 0;\r
362         fflush( gOutputFile );\r
363 \r
364         return ( n == 1 );\r
365 }\r
366 \r
367 /* ---------------------------------------------------------------------- */\r
368 /*!\r
369  *\r
370  *\r
371  *\r
372  */\r
373 SCTModuleList* siCommonGetModules( void* context )\r
374 {\r
375         SCTModuleList*  modules;\r
376         SCTModule*              module;\r
377 \r
378         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
379 \r
380     modules = sctGetCoreModules();   \r
381     if( modules == NULL )\r
382     {\r
383                 return NULL;\r
384     }\r
385            \r
386 #if defined( INCLUDE_AGL_MODULE )\r
387     module = sctCreateAglModule();\r
388     if( module == NULL || sctAddModuleToList( modules, module ) == SCT_FALSE )\r
389     {\r
390         sctDestroyModuleList( modules );\r
391         return NULL;\r
392     }\r
393 #endif  /* defined( INCLUDE_AGL_MODULE ) */\r
394         \r
395     return modules;\r
396 }\r
397 \r
398 /* ---------------------------------------------------------------------- */\r
399 /*!\r
400  *\r
401  *\r
402  *\r
403  */\r
404 void siCommonSleep( void* context, unsigned long micros )\r
405 {\r
406         struct timespec rqtp;\r
407         \r
408         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
409 \r
410         rqtp.tv_sec             = 0;\r
411         rqtp.tv_nsec    = micros * 1000;\r
412         \r
413         nanosleep( &rqtp, NULL );\r
414 }\r
415 \r
416 /* ---------------------------------------------------------------------- */\r
417 /*!\r
418  *\r
419  *\r
420  *\r
421  */\r
422 void siCommonYield( void* context )\r
423 {\r
424         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
425         // Do nothing\r
426 }\r
427 \r
428 /* ---------------------------------------------------------------------- */\r
429 /*!\r
430  *\r
431  *\r
432  *\r
433  */\r
434 void siCommonGetTime( void* context, char* buffer, int length )\r
435 {\r
436         time_t      ltime;\r
437         struct tm*      today;\r
438 \r
439         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
440         SCT_ASSERT_ALWAYS( length >= 1 );\r
441 \r
442         time( &ltime );\r
443         today = localtime( &ltime );\r
444         if( strftime( buffer, length, "%Y-%m-%d %H:%M:%S", today ) == 0 )\r
445     {\r
446                 buffer[ 0 ] = '\0';\r
447     }\r
448 }\r
449 \r
450 /* ---------------------------------------------------------------------- */\r
451 /*!\r
452  *\r
453  *\r
454  */\r
455 void* siCommonGetSingleton( void* context )\r
456 {\r
457         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
458 \r
459         return gSingleton;\r
460 }\r
461 \r
462 /* ---------------------------------------------------------------------- */\r
463 /*!\r
464  *\r
465  *\r
466  */\r
467 void siCommonSetSingleton( void* context, void* ptr )\r
468 {\r
469         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
470 \r
471         gSingleton = ptr;\r
472 }\r
473 \r
474 /* ---------------------------------------------------------------------- */\r
475 /*!\r
476  *\r
477  *\r
478  */\r
479 SCTExtensionProc siCommonGetProcAddress( void* context, const char* procname )\r
480 {\r
481         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
482 \r
483         return NULL;\r
484 }\r
485 \r
486 /* ---------------------------------------------------------------------- */\r
487 /*!\r
488  *\r
489  *\r
490  */\r
491 int siCommonGetMessage( void* context, SCTMessage* message, long timeoutMillis )\r
492 {\r
493     SCT_USE_VARIABLE( context );\r
494     SCT_ASSERT_ALWAYS( message != NULL );\r
495     SCT_USE_VARIABLE( timeoutMillis );\r
496 \r
497     return -1;\r
498 }\r
499 \r
500 /* Don't support threads in iOS at the moment. */\r
501 void* siCommonCreateThread( void* context, SCTBenchmarkWorkerThreadFunc func, SCTBenchmarkWorkerThreadContext* threadContext )\r
502 {\r
503         SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
504     SCT_USE_VARIABLE( context );\r
505     SCT_USE_VARIABLE( func );\r
506     SCT_USE_VARIABLE( threadContext );\r
507     \r
508     return NULL;\r
509 }\r
510 \r
511 void siCommonThreadCleanup( void* context )\r
512 {\r
513     SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
514     SCT_USE_VARIABLE( context );\r
515 }\r
516 \r
517 void siCommonJoinThread( void* context, void* thread )\r
518 {\r
519     SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
520     SCT_USE_VARIABLE( context );\r
521     SCT_USE_VARIABLE( thread );\r
522 }\r
523 \r
524 SCTBoolean siCommonSetThreadPriority( void* context, SCTThreadPriority priority )\r
525 {\r
526     SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
527     SCT_USE_VARIABLE( context );\r
528     SCT_USE_VARIABLE( priority );\r
529 \r
530     return SCT_FALSE;\r
531 }\r
532 \r
533 void* siCommonCreateMutex( void* context )\r
534 {\r
535     SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
536     SCT_USE_VARIABLE( context );\r
537 \r
538     return ( void* )( 1 );\r
539 }\r
540 \r
541 void siCommonLockMutex( void* context, void* mutex )\r
542 {\r
543     SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
544     SCT_USE_VARIABLE( context );\r
545     SCT_USE_VARIABLE( mutex );\r
546 }\r
547 \r
548 void siCommonUnlockMutex( void* context, void* mutex )\r
549 {\r
550     SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
551     SCT_USE_VARIABLE( context );\r
552     SCT_USE_VARIABLE( mutex );\r
553 }\r
554 \r
555 void siCommonDestroyMutex( void* context, void* mutex )\r
556 {\r
557     SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
558     SCT_USE_VARIABLE( context );\r
559     SCT_USE_VARIABLE( mutex );\r
560 }\r
561 \r
562 void* siCommonCreateSignal( void* context )\r
563 {\r
564     SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
565     SCT_USE_VARIABLE( context );\r
566 \r
567     return ( void* )( 2 );\r
568 }\r
569 \r
570 void siCommonDestroySignal( void* context, void* signal )\r
571 {\r
572     SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
573     SCT_USE_VARIABLE( context );\r
574     SCT_USE_VARIABLE( signal );\r
575 }\r
576 \r
577 int siCommonWaitForSignal( void* context, void* signal, long timeoutMillis )\r
578 {\r
579     SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
580     SCT_USE_VARIABLE( context );\r
581     SCT_USE_VARIABLE( signal );\r
582     SCT_USE_VARIABLE( timeoutMillis );\r
583     \r
584     return -1;\r
585 }\r
586 \r
587 void siCommonTriggerSignal( void* context, void* signal )\r
588 {\r
589     SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
590     SCT_USE_VARIABLE( context );\r
591     SCT_USE_VARIABLE( signal );\r
592 }\r
593 \r
594 void siCommonCancelSignal( void* context, void* signal )\r
595 {\r
596     SCT_ASSERT( context == NULL || context == ( void* )( SCT_SICOMMON_IPHONE_CONTEXT ) );\r
597     SCT_USE_VARIABLE( context );\r
598     SCT_USE_VARIABLE( signal );\r
599 }\r