00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <vlc/vlc.h>
00028
00029 #include <stdlib.h>
00030 #include <signal.h>
00031
00032
00033
00034
00035 #define MAXVAR 50
00036 #define MAXSET 2000
00037 #define MAXOBJ 1000
00038 #define MAXLOOK 10000
00039 #define MAXTH 4
00040
00041
00042
00043
00044 static int Foo ( vlc_object_t *, char const *,
00045 vlc_value_t, vlc_value_t, void * );
00046 static int Callback ( vlc_object_t *, char const *,
00047 vlc_value_t, vlc_value_t, void * );
00048 static int MyCallback( vlc_object_t *, char const *,
00049 vlc_value_t, vlc_value_t, void * );
00050 static void * MyThread ( vlc_object_t * );
00051
00052 static int Stress ( vlc_object_t *, char const *,
00053 vlc_value_t, vlc_value_t, void * );
00054 static void * Dummy ( vlc_object_t * );
00055
00056 static int Signal ( vlc_object_t *, char const *,
00057 vlc_value_t, vlc_value_t, void * );
00058
00059
00060
00061
00062 vlc_module_begin();
00063 set_description( _("Miscellaneous stress tests") );
00064 var_Create( p_module->p_libvlc, "foo-test",
00065 VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
00066 var_AddCallback( p_module->p_libvlc, "foo-test", Foo, NULL );
00067 var_Create( p_module->p_libvlc, "callback-test",
00068 VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
00069 var_AddCallback( p_module->p_libvlc, "callback-test", Callback, NULL );
00070 var_Create( p_module->p_libvlc, "stress-test",
00071 VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
00072 var_AddCallback( p_module->p_libvlc, "stress-test", Stress, NULL );
00073 var_Create( p_module->p_libvlc, "signal",
00074 VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
00075 var_AddCallback( p_module->p_libvlc, "signal", Signal, NULL );
00076 vlc_module_end();
00077
00078
00079
00080
00081 static int Foo( vlc_object_t *p_this, char const *psz_cmd,
00082 vlc_value_t oldval, vlc_value_t newval, void *p_data )
00083 {
00084 vlc_value_t val;
00085 int i;
00086
00087 var_Create( p_this, "honk", VLC_VAR_STRING | VLC_VAR_HASCHOICE );
00088
00089 val.psz_string = "foo";
00090 var_Change( p_this, "honk", VLC_VAR_ADDCHOICE, &val, NULL );
00091 val.psz_string = "bar";
00092 var_Change( p_this, "honk", VLC_VAR_ADDCHOICE, &val, NULL );
00093 val.psz_string = "baz";
00094 var_Change( p_this, "honk", VLC_VAR_ADDCHOICE, &val, NULL );
00095 var_Change( p_this, "honk", VLC_VAR_SETDEFAULT, &val, NULL );
00096
00097 var_Get( p_this, "honk", &val ); printf( "value: %s\n", val.psz_string );
00098
00099 val.psz_string = "foo";
00100 var_Set( p_this, "honk", val );
00101
00102 var_Get( p_this, "honk", &val ); printf( "value: %s\n", val.psz_string );
00103
00104 val.psz_string = "blork";
00105 var_Set( p_this, "honk", val );
00106
00107 var_Get( p_this, "honk", &val ); printf( "value: %s\n", val.psz_string );
00108
00109 val.psz_string = "baz";
00110 var_Change( p_this, "honk", VLC_VAR_DELCHOICE, &val, NULL );
00111
00112 var_Get( p_this, "honk", &val ); printf( "value: %s\n", val.psz_string );
00113
00114 var_Change( p_this, "honk", VLC_VAR_GETLIST, &val, NULL );
00115 for( i = 0 ; i < val.p_list->i_count ; i++ )
00116 {
00117 printf( "value %i: %s\n", i, val.p_list->p_values[i].psz_string );
00118 }
00119 var_Change( p_this, "honk", VLC_VAR_FREELIST, &val, NULL );
00120
00121 var_Destroy( p_this, "honk" );
00122
00123 return VLC_SUCCESS;
00124 }
00125
00126
00127
00128
00129 static int Callback( vlc_object_t *p_this, char const *psz_cmd,
00130 vlc_value_t oldval, vlc_value_t newval, void *p_data )
00131 {
00132 int i;
00133 char psz_var[20];
00134 vlc_object_t *pp_objects[10];
00135 vlc_value_t val;
00136
00137
00138 for( i = 0; i < 1000; i++ )
00139 {
00140 sprintf( psz_var, "blork-%i", i );
00141 var_Create( p_this, psz_var, VLC_VAR_INTEGER );
00142 var_AddCallback( p_this, psz_var, MyCallback, NULL );
00143 }
00144
00145
00146
00147
00148 printf( "Test #1: callback loop detection\n" );
00149
00150 printf( " - without boundary check (vlc should print an error)\n" );
00151 val.i_int = 1234567;
00152 var_Set( p_this, "blork-12", val );
00153
00154 printf( " - with boundary check\n" );
00155 val.i_int = 12;
00156 var_Set( p_this, "blork-12", val );
00157
00158
00159
00160
00161 printf( "Test #2: concurrent access\n" );
00162
00163 printf( " - launch worker threads\n" );
00164
00165 for( i = 0; i < 10; i++ )
00166 {
00167 pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
00168 vlc_object_attach( pp_objects[i], p_this );
00169 vlc_thread_create( pp_objects[i], "foo", MyThread, 0, VLC_TRUE );
00170 }
00171
00172 msleep( 3000000 );
00173
00174 printf( " - kill worker threads\n" );
00175
00176 for( i = 0; i < 10; i++ )
00177 {
00178 pp_objects[i]->b_die = VLC_TRUE;
00179 vlc_thread_join( pp_objects[i] );
00180 vlc_object_detach( pp_objects[i] );
00181 vlc_object_destroy( pp_objects[i] );
00182 }
00183
00184
00185 for( i = 0; i < 1000; i++ )
00186 {
00187 sprintf( psz_var, "blork-%i", i );
00188 var_DelCallback( p_this, psz_var, MyCallback, NULL );
00189 var_Destroy( p_this, psz_var );
00190 }
00191
00192 return VLC_SUCCESS;
00193 }
00194
00195
00196
00197
00198 static int MyCallback( vlc_object_t *p_this, char const *psz_var,
00199 vlc_value_t oldval, vlc_value_t newval, void *p_data )
00200 {
00201 int i_var = 1 + atoi( psz_var + strlen("blork-") );
00202 char psz_newvar[20];
00203
00204 if( i_var == 1000 )
00205 {
00206 i_var = 0;
00207 }
00208
00209
00210 if( i_var == newval.i_int )
00211 {
00212 return VLC_SUCCESS;
00213 }
00214
00215
00216 sprintf( psz_newvar, "blork-%i", i_var );
00217 var_Set( p_this, psz_newvar, newval );
00218
00219 return VLC_SUCCESS;
00220 }
00221
00222
00223
00224
00225 static void * MyThread( vlc_object_t *p_this )
00226 {
00227 char psz_var[20];
00228 vlc_value_t val;
00229 vlc_object_t *p_parent = p_this->p_parent;
00230
00231 vlc_thread_ready( p_this );
00232
00233 val.i_int = 42;
00234
00235 while( !p_this->b_die )
00236 {
00237 int i = (int) (100.0 * rand() / (RAND_MAX));
00238
00239 sprintf( psz_var, "blork-%i", i );
00240 val.i_int = i + 200;
00241 var_Set( p_parent, psz_var, val );
00242
00243
00244 msleep( 1000 );
00245 }
00246
00247 return NULL;
00248 }
00249
00250
00251
00252
00253 static int Stress( vlc_object_t *p_this, char const *psz_cmd,
00254 vlc_value_t oldval, vlc_value_t newval, void *p_data )
00255 {
00256 vlc_object_t **pp_objects;
00257 mtime_t start;
00258 char ** ppsz_name;
00259 char * psz_blob;
00260 int i, i_level;
00261
00262 if( *newval.psz_string )
00263 {
00264 i_level = atoi( newval.psz_string );
00265 if( i_level <= 0 )
00266 {
00267 i_level = 1;
00268 }
00269 else if( i_level > 200 )
00270 {
00271
00272 i_level = 200;
00273 }
00274 }
00275 else
00276 {
00277 i_level = 10;
00278 }
00279
00280
00281 ppsz_name = malloc( MAXVAR * i_level * sizeof(char*) );
00282 psz_blob = malloc( 20 * MAXVAR * i_level * sizeof(char) );
00283 for( i = 0; i < MAXVAR * i_level; i++ )
00284 {
00285 ppsz_name[i] = psz_blob + 20 * i;
00286 }
00287
00288 pp_objects = malloc( MAXOBJ * i_level * sizeof(void*) );
00289
00290
00291
00292
00293 printf( "Test #1: objects\n" );
00294
00295 printf( " - creating %i objects\n", MAXOBJ * i_level );
00296 start = mdate();
00297 for( i = 0; i < MAXOBJ * i_level; i++ )
00298 {
00299 pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
00300 }
00301
00302 printf( " - randomly looking up %i objects\n", MAXLOOK * i_level );
00303 for( i = MAXLOOK * i_level; i--; )
00304 {
00305 int id = (int) (MAXOBJ * i_level * 1.0 * rand() / (RAND_MAX));
00306 vlc_object_get( p_this, pp_objects[id]->i_object_id );
00307 vlc_object_release( p_this );
00308 }
00309
00310 printf( " - destroying the objects (LIFO)\n" );
00311 for( i = MAXOBJ * i_level; i--; )
00312 {
00313 vlc_object_destroy( pp_objects[i] );
00314 }
00315
00316 printf( "done (%fs).\n", (mdate() - start) / 1000000.0 );
00317
00318
00319
00320
00321 printf( "Test #2: integer variables\n" );
00322
00323 printf( " - creating %i integer variables\n", MAXVAR * i_level );
00324 start = mdate();
00325 for( i = 0; i < MAXVAR * i_level; i++ )
00326 {
00327 sprintf( ppsz_name[i], "foo-%04i-bar-%04x", i, i * 11 );
00328 var_Create( p_this, ppsz_name[i], VLC_VAR_INTEGER );
00329 }
00330
00331 printf( " - randomly assigning %i values\n", MAXSET * i_level );
00332 for( i = 0; i < MAXSET * i_level; i++ )
00333 {
00334 int v = (int) (MAXVAR * i_level * 1.0 * rand() / (RAND_MAX));
00335 var_Set( p_this, ppsz_name[v], (vlc_value_t)i );
00336 }
00337
00338 printf( " - destroying the variables\n" );
00339 for( i = 0; i < MAXVAR * i_level; i++ )
00340 {
00341 var_Destroy( p_this, ppsz_name[i] );
00342 }
00343
00344 printf( "done (%fs).\n", (mdate() - start) / 1000000.0 );
00345
00346
00347
00348
00349 printf( "Test #3: string variables\n" );
00350
00351 printf( " - creating %i string variables\n", MAXVAR * i_level );
00352 start = mdate();
00353 for( i = 0; i < MAXVAR * i_level; i++ )
00354 {
00355 sprintf( ppsz_name[i], "foo-%04i-bar-%04x", i, i * 11 );
00356 var_Create( p_this, ppsz_name[i], VLC_VAR_STRING );
00357 }
00358
00359 printf( " - randomly assigning %i values\n", MAXSET * i_level );
00360 for( i = 0; i < MAXSET * i_level; i++ )
00361 {
00362 int v = (int) (MAXVAR * i_level * 1.0 * rand() / (RAND_MAX));
00363 var_Set( p_this, ppsz_name[v], (vlc_value_t)ppsz_name[v] );
00364 }
00365
00366 printf( " - destroying the variables\n" );
00367 for( i = 0; i < MAXVAR * i_level; i++ )
00368 {
00369 var_Destroy( p_this, ppsz_name[i] );
00370 }
00371
00372 printf( "done (%fs).\n", (mdate() - start) / 1000000.0 );
00373
00374
00375
00376
00377 printf( "Test #4: threads\n" );
00378 start = mdate();
00379
00380 printf( " - spawning %i threads that will each create %i objects\n",
00381 MAXTH * i_level, MAXOBJ/MAXTH );
00382 for( i = 0; i < MAXTH * i_level; i++ )
00383 {
00384 pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
00385 vlc_thread_create( pp_objects[i], "foo", Dummy, 0, VLC_TRUE );
00386 }
00387
00388 printf( " - killing the threads (LIFO)\n" );
00389 for( i = MAXTH * i_level; i--; )
00390 {
00391 pp_objects[i]->b_die = VLC_TRUE;
00392 vlc_thread_join( pp_objects[i] );
00393 vlc_object_destroy( pp_objects[i] );
00394 }
00395
00396 printf( "done (%fs).\n", (mdate() - start) / 1000000.0 );
00397
00398
00399 free( pp_objects );
00400 free( psz_blob );
00401 free( ppsz_name );
00402
00403 return VLC_SUCCESS;
00404 }
00405
00406
00407
00408
00409 static void * Dummy( vlc_object_t *p_this )
00410 {
00411 int i;
00412 vlc_object_t *pp_objects[MAXOBJ/MAXTH];
00413
00414 for( i = 0; i < MAXOBJ/MAXTH; i++ )
00415 {
00416 pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
00417 }
00418
00419 vlc_thread_ready( p_this );
00420
00421 while( !p_this->b_die )
00422 {
00423 msleep( 10000 );
00424 }
00425
00426 for( i = MAXOBJ/MAXTH; i--; )
00427 {
00428 vlc_object_destroy( pp_objects[i] );
00429 }
00430
00431 return NULL;
00432 }
00433
00434
00435
00436
00437 static int Signal( vlc_object_t *p_this, char const *psz_cmd,
00438 vlc_value_t oldval, vlc_value_t newval, void *p_data )
00439 {
00440 raise( atoi(newval.psz_string) );
00441 return VLC_SUCCESS;
00442 }