Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

test4.c

00001 /*****************************************************************************
00002  * test4.c : Miscellaneous stress tests module for vlc
00003  *****************************************************************************
00004  * Copyright (C) 2002 the VideoLAN team
00005  * $Id: test4.c 11664 2005-07-09 06:17:09Z courmisch $
00006  *
00007  * Authors: Samuel Hocevar <[email protected]>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  * 
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00022  *****************************************************************************/
00023 
00024 /*****************************************************************************
00025  * Preamble
00026  *****************************************************************************/
00027 #include <vlc/vlc.h>
00028 
00029 #include <stdlib.h>
00030 #include <signal.h>
00031 
00032 /*****************************************************************************
00033  * Defines
00034  *****************************************************************************/
00035 #define MAXVAR        50                    /* Number of variables to create */
00036 #define MAXSET      2000                       /* Number of variables to set */
00037 #define MAXOBJ      1000                      /* Number of objects to create */
00038 #define MAXLOOK    10000                      /* Number of objects to lookup */
00039 #define MAXTH          4                       /* Number of threads to spawn */
00040 
00041 /*****************************************************************************
00042  * Local prototypes.
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  * Module descriptor.
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  * Foo: put anything here
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  * Callback: test callback functions
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     /* Allocate a few variables */
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      *  Test #1: callback loop detection
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      *  Test #2: concurrent access
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     /* Clean our mess */
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  * MyCallback: used by callback-test
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     /* If we are requested to stop, then stop. */
00210     if( i_var == newval.i_int )
00211     {
00212         return VLC_SUCCESS;
00213     }
00214 
00215     /* If we're the blork-3 callback, set blork-4, and so on. */
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  * MyThread: used by callback-test, creates objects and then do nothing.
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         /* This is quite heavy, but we only have 10 threads. Keep cool. */
00244         msleep( 1000 );
00245     }
00246 
00247     return NULL;
00248 }
00249 
00250 /*****************************************************************************
00251  * Stress: perform various stress tests
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             /* It becomes quite dangerous above 150 */
00272             i_level = 200;
00273         }
00274     }
00275     else
00276     {
00277         i_level = 10;
00278     }
00279 
00280     /* Allocate required data */
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      *  Test #1: objects
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      *  Test #2: integer variables
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      *  Test #3: string variables
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      *  Test #4: threads
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     /* Free required data */
00399     free( pp_objects );
00400     free( psz_blob );
00401     free( ppsz_name );
00402 
00403     return VLC_SUCCESS;
00404 }
00405 
00406 /*****************************************************************************
00407  * Dummy: used by stress-test, creates objects and then do nothing.
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  * Signal: send a signal to the current thread.
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 }

Generated on Tue Dec 20 10:14:48 2005 for vlc-0.8.4a by  doxygen 1.4.2