]> pd.if.org Git - liblfds/blob - liblfds/liblfds7.1.0/test_and_benchmark/test/src/main.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds7.1.0 / test_and_benchmark / test / src / main.c
1 /***** includes *****/
2 #include "internal.h"
3
4
5
6
7
8 /****************************************************************************/
9 int main( int argc, char **argv )
10 {
11   enum flag
12     determine_erg_flag = LOWERED,
13     run_flag = LOWERED,
14     show_error_flag = LOWERED,
15     show_help_flag = LOWERED,
16     show_version_flag = LOWERED;
17
18   int
19     rv;
20
21   lfds710_pal_uint_t
22     loop,
23     iterations = 1,
24     memory_in_megabytes = TEST_DEFAULT_TEST_MEMORY_IN_MEGABYTES;
25
26   struct util_cmdline_state
27     cs;
28
29   union util_cmdline_arg_data
30     *arg_data;
31
32   assert( argc >= 1 );
33   assert( argv != NULL );
34
35   util_cmdline_init( &cs );
36
37   util_cmdline_add_arg( &cs, 'e', UTIL_CMDLINE_ARG_TYPE_FLAG );
38   util_cmdline_add_arg( &cs, 'h', UTIL_CMDLINE_ARG_TYPE_FLAG );
39   util_cmdline_add_arg( &cs, 'i', UTIL_CMDLINE_ARG_TYPE_INTEGER );
40   util_cmdline_add_arg( &cs, 'm', UTIL_CMDLINE_ARG_TYPE_INTEGER );
41   util_cmdline_add_arg( &cs, 'r', UTIL_CMDLINE_ARG_TYPE_FLAG );
42   util_cmdline_add_arg( &cs, 'v', UTIL_CMDLINE_ARG_TYPE_FLAG );
43
44   rv = util_cmdline_process_args( &cs, argc, argv );
45
46   if( rv == 0 )
47     show_error_flag = RAISED;
48
49   if( rv == 1 )
50   {
51     util_cmdline_get_arg_data( &cs, 'e', &arg_data );
52     if( arg_data != NULL )
53       determine_erg_flag = RAISED;
54
55     util_cmdline_get_arg_data( &cs, 'h', &arg_data );
56     if( arg_data != NULL )
57       show_help_flag = RAISED;
58
59     util_cmdline_get_arg_data( &cs, 'i', &arg_data );
60     if( arg_data != NULL )
61     {
62       if( arg_data->integer.integer < 1 )
63       {
64         puts( "Number of iterations needs to be 1 or greater." );
65         exit( EXIT_FAILURE );
66       }
67
68       iterations = (lfds710_pal_uint_t) arg_data->integer.integer;
69     }
70
71     util_cmdline_get_arg_data( &cs, 'm', &arg_data );
72     if( arg_data != NULL )
73     {
74       if( arg_data->integer.integer < 32 )
75       {
76         puts( "Memory for tests needs to be 32 or greater." );
77         exit( EXIT_FAILURE );
78       }
79
80       memory_in_megabytes = (lfds710_pal_uint_t) arg_data->integer.integer;
81     }
82
83     util_cmdline_get_arg_data( &cs, 'r', &arg_data );
84     if( arg_data != NULL )
85       run_flag = RAISED;
86
87     util_cmdline_get_arg_data( &cs, 'v', &arg_data );
88     if( arg_data != NULL )
89       show_version_flag = RAISED;
90   }
91
92   util_cmdline_cleanup( &cs );
93
94   if( argc == 1 or (run_flag == LOWERED and show_version_flag == LOWERED) )
95     show_help_flag = RAISED;
96
97   if( show_error_flag == RAISED )
98   {
99     printf( "\nInvalid arguments.  Sorry - it's a simple parser, so no clues.\n"
100             "-h or run with no args to see the help text.\n" );
101
102     return EXIT_SUCCESS;
103   }
104
105   if( determine_erg_flag == RAISED )
106   {
107     enum libtest_misc_determine_erg_result
108       der;
109
110     lfds710_pal_uint_t
111       count_array[10],
112       erg_size_in_bytes;
113
114     struct libshared_memory_state
115       ms;
116
117     void
118       *memory;
119
120     memory = malloc( ONE_MEGABYTE_IN_BYTES );
121
122     libshared_memory_init( &ms );
123
124     libshared_memory_add_memory( &ms, memory, ONE_MEGABYTE_IN_BYTES );
125
126     libtest_misc_determine_erg( &ms, &count_array, &der, &erg_size_in_bytes );
127
128     if( der == LIBTEST_MISC_DETERMINE_ERG_RESULT_NOT_SUPPORTED )
129       printf( "Determine ERG not supported on the current platform.\n" );
130     else
131     {
132       printf( "\n"
133               "Results\n"
134               "=======\n"
135               "\n" );
136
137       printf( "  ERG length in bytes : Number successful LL/SC ops\n"
138               "  =================================================\n" );
139
140       for( loop = 0 ; loop < 10 ; loop++ )
141         printf( "  %lu bytes : %llu\n", 1UL << (loop+2), (int long long unsigned) count_array[loop] );
142
143       printf( "\n"
144               "Conclusions\n"
145               "===========\n"
146               "\n" );
147
148       switch( der )
149       {
150         case LIBTEST_MISC_DETERMINE_ERG_RESULT_SUCCESS:
151           printf( "  The smallest ERG size with successful results is %llu bytes, which\n"
152                   "  is therefore hopefully if all has gone well the ERG size.\n"
153                   "  \n"
154                   "  In the file 'lfds710_porting_abstraction_layer_processor.h', in all\n"
155                   "  the sections for ARM, please replace the existing the value of the\n"
156                   "  #define LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES to %llu, like so;\n"
157                   "  \n"
158                   "  #define LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES %llu\n",
159                   (int long long unsigned) erg_size_in_bytes,
160                   (int long long unsigned) erg_size_in_bytes,
161                   (int long long unsigned) erg_size_in_bytes );
162         break;
163
164         case LIBTEST_MISC_DETERMINE_ERG_RESULT_ONE_PHYSICAL_CORE:
165           printf( "  This system has only one physical core, and as such this\n"
166                   "  code cannot determine the ERG.\n" );
167         break;
168
169         case LIBTEST_MISC_DETERMINE_ERG_RESULT_ONE_PHYSICAL_CORE_OR_NO_LLSC:
170           printf( "  The results are indeterminate.  Either this system has only one\n"
171                   "  physical core, and as such this code cannot determine the ERG, or\n"
172                   "  the system has no support for LL/SC.\n" );
173         break;
174
175         case LIBTEST_MISC_DETERMINE_ERG_RESULT_NO_LLSC:
176           printf( "  There appears to be no LL/SC support on the current platform.\n" );
177         break;
178
179         case LIBTEST_MISC_DETERMINE_ERG_RESULT_NOT_SUPPORTED:
180           printf( "  Determine ERG not supported on the current platform.\n" );
181         break;
182       }
183
184       printf( "\n"
185               "Explanations\n"
186               "============\n"
187               "\n"
188               "  This code is for ARM and works to empirically determine the ERG size,\n"
189               "  which is the value which needs to be used for the #define\n"
190               "  LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES in the file\n"
191               "  'lfds710_porting_abstraction_layer_processor.h'.\n"
192               "  \n"
193               "  It is VERY VERY IMPORTANT to set this value because the default on ARM\n"
194               "  is the worst-case, which is 2048 bytes, and this makes all the lfds\n"
195               "  data structure structs HUGE.\n"
196               "  \n"
197               "  If this value is set too small, then absolutely none of the liblfds data\n"
198               "  structures should work *at all*, so getting it wrong should be very obvious.\n"
199               "  \n"
200               "  Each ERG length is tried 1024 times.  All ERG sizes which are smaller than the\n"
201               "  actual ERG size should have 0 successful ops.  All ERG sizes equal to or\n"
202               "  greater than the actual ERG size should have 1024, or maybe a few less,\n"
203               "  successful ops.  A few spurious failures are not unusual, it's the\n"
204               "  nature of LL/SC, so it's normal.  The correct ERG size then is the smallest\n"
205               "  size which has about 1024 successful ops.\n"
206               "  \n"
207               "  This code however can only work if there are at least two physical cores\n"
208               "  in the system.  It's not enough to have one physical core with multiple\n"
209               "  logical cores.  If the ERG size of 4 bytes has any successes, then the\n"
210               "  current systems has only a single physical processor, or it has no\n"
211               "  support for LL/SC (which can happen - there are SO many ARM system\n"
212               "  variants).\n" );
213     }
214
215     return EXIT_SUCCESS;
216   }
217
218   if( show_help_flag == RAISED )
219   {
220     printf( "test -e -h -i [n] -m [n] -r -v\n"
221             "  -e     : empirically determine Exclusive Reservation Granule\n"
222             "           (currently supports only ARM32)\n"
223             "  -h     : help\n"
224             "  -i [n] : number of iterations     (default : 1)\n"
225             "  -m [n] : memory for tests, in mb  (default : %u)\n"
226             "  -r     : run (causes test to run; present so no args gives help)\n"
227             "  -v     : version\n", (int unsigned) TEST_DEFAULT_TEST_MEMORY_IN_MEGABYTES );
228
229     return EXIT_SUCCESS;
230   }
231
232   if( show_version_flag == RAISED )
233   {
234     internal_show_version();
235     return EXIT_SUCCESS;
236   }
237
238   if( run_flag == RAISED )
239   {
240     struct libshared_memory_state
241       ms;
242
243     struct libtest_results_state
244       rs;
245
246     struct libtest_testsuite_state
247       ts;
248
249     void
250       *test_memory;
251
252     test_memory = malloc( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES );
253
254     libshared_memory_init( &ms );
255
256     libshared_memory_add_memory( &ms, test_memory, memory_in_megabytes * ONE_MEGABYTE_IN_BYTES );
257
258     libtest_testsuite_init( &ts, &ms, callback_test_start, callback_test_finish );
259
260     for( loop = 0 ; loop < (lfds710_pal_uint_t) iterations ; loop++ )
261     {
262       libtest_results_init( &rs );
263
264       printf( "\n"
265               "Test Iteration %02llu\n"
266               "=================\n", (int long long unsigned) (loop+1) );
267
268       libtest_testsuite_run( &ts, &rs );
269
270       libtest_results_cleanup( &rs );
271     }
272
273     libtest_testsuite_cleanup( &ts );
274
275     libshared_memory_cleanup( &ms, NULL );
276
277     free( test_memory );
278   }
279
280   return EXIT_SUCCESS;
281 }
282