test4.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:14k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * test4.c : Miscellaneous stress tests module for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2002 VideoLAN
  5.  * $Id: test4.c 6961 2004-03-05 17:34:23Z sam $
  6.  *
  7.  * Authors: Samuel Hocevar <sam@zoy.org>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  * 
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #include <vlc/vlc.h>
  27. #include <stdlib.h>
  28. #include <signal.h>
  29. /*****************************************************************************
  30.  * Defines
  31.  *****************************************************************************/
  32. #define MAXVAR        50                    /* Number of variables to create */
  33. #define MAXSET      2000                       /* Number of variables to set */
  34. #define MAXOBJ      1000                      /* Number of objects to create */
  35. #define MAXLOOK    10000                      /* Number of objects to lookup */
  36. #define MAXTH          4                       /* Number of threads to spawn */
  37. /*****************************************************************************
  38.  * Local prototypes.
  39.  *****************************************************************************/
  40. static int    Foo       ( vlc_object_t *, char const *,
  41.                           vlc_value_t, vlc_value_t, void * );
  42. static int    Callback  ( vlc_object_t *, char const *,
  43.                           vlc_value_t, vlc_value_t, void * );
  44. static int    MyCallback( vlc_object_t *, char const *,
  45.                           vlc_value_t, vlc_value_t, void * );
  46. static void * MyThread  ( vlc_object_t * );
  47. static int    Stress    ( vlc_object_t *, char const *,
  48.                           vlc_value_t, vlc_value_t, void * );
  49. static void * Dummy     ( vlc_object_t * );
  50. static int    Signal    ( vlc_object_t *, char const *,
  51.                           vlc_value_t, vlc_value_t, void * );
  52. /*****************************************************************************
  53.  * Module descriptor.
  54.  *****************************************************************************/
  55. vlc_module_begin();
  56.     set_description( _("Miscellaneous stress tests") );
  57.     var_Create( p_module->p_libvlc, "foo-test",
  58.                 VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
  59.     var_AddCallback( p_module->p_libvlc, "foo-test", Foo, NULL );
  60.     var_Create( p_module->p_libvlc, "callback-test",
  61.                 VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
  62.     var_AddCallback( p_module->p_libvlc, "callback-test", Callback, NULL );
  63.     var_Create( p_module->p_libvlc, "stress-test",
  64.                 VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
  65.     var_AddCallback( p_module->p_libvlc, "stress-test", Stress, NULL );
  66.     var_Create( p_module->p_libvlc, "signal",
  67.                 VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
  68.     var_AddCallback( p_module->p_libvlc, "signal", Signal, NULL );
  69. vlc_module_end();
  70. /*****************************************************************************
  71.  * Foo: put anything here
  72.  *****************************************************************************/
  73. static int Foo( vlc_object_t *p_this, char const *psz_cmd,
  74.                 vlc_value_t oldval, vlc_value_t newval, void *p_data )
  75. {
  76.     vlc_value_t val;
  77.     int i;
  78.     var_Create( p_this, "honk", VLC_VAR_STRING | VLC_VAR_HASCHOICE );
  79.     val.psz_string = "foo";
  80.     var_Change( p_this, "honk", VLC_VAR_ADDCHOICE, &val, NULL );
  81.     val.psz_string = "bar";
  82.     var_Change( p_this, "honk", VLC_VAR_ADDCHOICE, &val, NULL );
  83.     val.psz_string = "baz";
  84.     var_Change( p_this, "honk", VLC_VAR_ADDCHOICE, &val, NULL );
  85.     var_Change( p_this, "honk", VLC_VAR_SETDEFAULT, &val, NULL );
  86.     var_Get( p_this, "honk", &val ); printf( "value: %sn", val.psz_string );
  87.     val.psz_string = "foo";
  88.     var_Set( p_this, "honk", val );
  89.     var_Get( p_this, "honk", &val ); printf( "value: %sn", val.psz_string );
  90.     val.psz_string = "blork";
  91.     var_Set( p_this, "honk", val );
  92.     var_Get( p_this, "honk", &val ); printf( "value: %sn", val.psz_string );
  93.     val.psz_string = "baz";
  94.     var_Change( p_this, "honk", VLC_VAR_DELCHOICE, &val, NULL );
  95.     var_Get( p_this, "honk", &val ); printf( "value: %sn", val.psz_string );
  96.     var_Change( p_this, "honk", VLC_VAR_GETLIST, &val, NULL );
  97.     for( i = 0 ; i < val.p_list->i_count ; i++ )
  98.     {
  99.         printf( "value %i: %sn", i, val.p_list->p_values[i].psz_string );
  100.     }
  101.     var_Change( p_this, "honk", VLC_VAR_FREELIST, &val, NULL );
  102.     var_Destroy( p_this, "honk" );
  103.     return VLC_SUCCESS;
  104. }
  105. /*****************************************************************************
  106.  * Callback: test callback functions
  107.  *****************************************************************************/
  108. static int Callback( vlc_object_t *p_this, char const *psz_cmd,
  109.                      vlc_value_t oldval, vlc_value_t newval, void *p_data )
  110. {
  111.     int i;
  112.     char psz_var[20];
  113.     vlc_object_t *pp_objects[10];
  114.     vlc_value_t val;
  115.     /* Allocate a few variables */
  116.     for( i = 0; i < 1000; i++ )
  117.     {
  118.         sprintf( psz_var, "blork-%i", i );
  119.         var_Create( p_this, psz_var, VLC_VAR_INTEGER );
  120.         var_AddCallback( p_this, psz_var, MyCallback, NULL );
  121.     }
  122.     /*
  123.      *  Test #1: callback loop detection
  124.      */
  125.     printf( "Test #1: callback loop detectionn" );
  126.     printf( " - without boundary check (vlc should print an error)n" );
  127.     val.i_int = 1234567;
  128.     var_Set( p_this, "blork-12", val );
  129.     printf( " - with boundary checkn" );
  130.     val.i_int = 12;
  131.     var_Set( p_this, "blork-12", val );
  132.     /*
  133.      *  Test #2: concurrent access
  134.      */
  135.     printf( "Test #2: concurrent accessn" );
  136.     printf( " - launch worker threadsn" );
  137.     for( i = 0; i < 10; i++ )
  138.     {
  139.         pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
  140.         vlc_object_attach( pp_objects[i], p_this );
  141.         vlc_thread_create( pp_objects[i], "foo", MyThread, 0, VLC_TRUE );
  142.     }
  143.     msleep( 3000000 );
  144.     printf( " - kill worker threadsn" );
  145.     for( i = 0; i < 10; i++ )
  146.     {
  147.         pp_objects[i]->b_die = VLC_TRUE;
  148.         vlc_thread_join( pp_objects[i] );
  149.         vlc_object_detach( pp_objects[i] );
  150.         vlc_object_destroy( pp_objects[i] );
  151.     }
  152.     /* Clean our mess */
  153.     for( i = 0; i < 1000; i++ )
  154.     {
  155.         sprintf( psz_var, "blork-%i", i );
  156.         var_DelCallback( p_this, psz_var, MyCallback, NULL );
  157.         var_Destroy( p_this, psz_var );
  158.     }
  159.     return VLC_SUCCESS;
  160. }
  161. /*****************************************************************************
  162.  * MyCallback: used by callback-test
  163.  *****************************************************************************/
  164. static int MyCallback( vlc_object_t *p_this, char const *psz_var,
  165.                        vlc_value_t oldval, vlc_value_t newval, void *p_data )
  166. {
  167.     int i_var = 1 + atoi( psz_var + strlen("blork-") );
  168.     char psz_newvar[20];
  169.     if( i_var == 1000 )
  170.     {
  171.         i_var = 0;
  172.     }
  173.     /* If we are requested to stop, then stop. */
  174.     if( i_var == newval.i_int )
  175.     {
  176.         return VLC_SUCCESS;
  177.     }
  178.     /* If we're the blork-3 callback, set blork-4, and so on. */
  179.     sprintf( psz_newvar, "blork-%i", i_var );
  180.     var_Set( p_this, psz_newvar, newval );
  181.     return VLC_SUCCESS;   
  182. }
  183. /*****************************************************************************
  184.  * MyThread: used by callback-test, creates objects and then do nothing.
  185.  *****************************************************************************/
  186. static void * MyThread( vlc_object_t *p_this )
  187. {
  188.     char psz_var[20];
  189.     vlc_value_t val;
  190.     vlc_object_t *p_parent = p_this->p_parent;
  191.     vlc_thread_ready( p_this );
  192.     val.i_int = 42;
  193.     while( !p_this->b_die )
  194.     {
  195.         int i = (int) (100.0 * rand() / (RAND_MAX));
  196.         sprintf( psz_var, "blork-%i", i );
  197.         val.i_int = i + 200;
  198.         var_Set( p_parent, psz_var, val );
  199.         /* This is quite heavy, but we only have 10 threads. Keep cool. */
  200.         msleep( 1000 );
  201.     }
  202.     return NULL;
  203. }
  204. /*****************************************************************************
  205.  * Stress: perform various stress tests
  206.  *****************************************************************************/
  207. static int Stress( vlc_object_t *p_this, char const *psz_cmd,
  208.                    vlc_value_t oldval, vlc_value_t newval, void *p_data )
  209. {
  210.     vlc_object_t **pp_objects;
  211.     mtime_t start;
  212.     char ** ppsz_name;
  213.     char *  psz_blob;
  214.     int     i, i_level;
  215.     if( *newval.psz_string )
  216.     {
  217.         i_level = atoi( newval.psz_string );
  218.         if( i_level <= 0 )
  219.         {
  220.             i_level = 1;
  221.         }
  222.         else if( i_level > 200 )
  223.         {
  224.             /* It becomes quite dangerous above 150 */
  225.             i_level = 200;
  226.         }
  227.     }
  228.     else
  229.     {
  230.         i_level = 10;
  231.     }
  232.     /* Allocate required data */
  233.     ppsz_name = malloc( MAXVAR * i_level * sizeof(char*) );
  234.     psz_blob = malloc( 20 * MAXVAR * i_level * sizeof(char) );
  235.     for( i = 0; i < MAXVAR * i_level; i++ )
  236.     {
  237.         ppsz_name[i] = psz_blob + 20 * i;
  238.     }
  239.     pp_objects = malloc( MAXOBJ * i_level * sizeof(void*) );
  240.     /*
  241.      *  Test #1: objects
  242.      */
  243.     printf( "Test #1: objectsn" );
  244.     printf( " - creating %i objectsn", MAXOBJ * i_level );
  245.     start = mdate();
  246.     for( i = 0; i < MAXOBJ * i_level; i++ )
  247.     {
  248.         pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
  249.     }
  250.     printf( " - randomly looking up %i objectsn", MAXLOOK * i_level );
  251.     for( i = MAXLOOK * i_level; i--; )
  252.     {
  253.         int id = (int) (MAXOBJ * i_level * 1.0 * rand() / (RAND_MAX));
  254.         vlc_object_get( p_this, pp_objects[id]->i_object_id );
  255.         vlc_object_release( p_this );
  256.     }
  257.     printf( " - destroying the objects (LIFO)n" );
  258.     for( i = MAXOBJ * i_level; i--; )
  259.     {
  260.         vlc_object_destroy( pp_objects[i] );
  261.     }
  262.     printf( "done (%fs).n", (mdate() - start) / 1000000.0 );
  263.     /*
  264.      *  Test #2: integer variables
  265.      */
  266.     printf( "Test #2: integer variablesn" );
  267.     printf( " - creating %i integer variablesn", MAXVAR * i_level );
  268.     start = mdate();
  269.     for( i = 0; i < MAXVAR * i_level; i++ )
  270.     {
  271.         sprintf( ppsz_name[i], "foo-%04i-bar-%04x", i, i * 11 );
  272.         var_Create( p_this, ppsz_name[i], VLC_VAR_INTEGER );
  273.     }
  274.     printf( " - randomly assigning %i valuesn", MAXSET * i_level );
  275.     for( i = 0; i < MAXSET * i_level; i++ )
  276.     {
  277.         int v = (int) (MAXVAR * i_level * 1.0 * rand() / (RAND_MAX));
  278.         var_Set( p_this, ppsz_name[v], (vlc_value_t)i );
  279.     }
  280.     printf( " - destroying the variablesn" );
  281.     for( i = 0; i < MAXVAR * i_level; i++ )
  282.     {
  283.         var_Destroy( p_this, ppsz_name[i] );
  284.     }
  285.     printf( "done (%fs).n", (mdate() - start) / 1000000.0 );
  286.     /*
  287.      *  Test #3: string variables
  288.      */
  289.     printf( "Test #3: string variablesn" );
  290.     printf( " - creating %i string variablesn", MAXVAR * i_level );
  291.     start = mdate();
  292.     for( i = 0; i < MAXVAR * i_level; i++ )
  293.     {
  294.         sprintf( ppsz_name[i], "foo-%04i-bar-%04x", i, i * 11 );
  295.         var_Create( p_this, ppsz_name[i], VLC_VAR_STRING );
  296.     }
  297.     printf( " - randomly assigning %i valuesn", MAXSET * i_level );
  298.     for( i = 0; i < MAXSET * i_level; i++ )
  299.     {
  300.         int v = (int) (MAXVAR * i_level * 1.0 * rand() / (RAND_MAX));
  301.         var_Set( p_this, ppsz_name[v], (vlc_value_t)ppsz_name[v] );
  302.     }
  303.     printf( " - destroying the variablesn" );
  304.     for( i = 0; i < MAXVAR * i_level; i++ )
  305.     {
  306.         var_Destroy( p_this, ppsz_name[i] );
  307.     }
  308.     printf( "done (%fs).n", (mdate() - start) / 1000000.0 );
  309.     /*
  310.      *  Test #4: threads
  311.      */
  312.     printf( "Test #4: threadsn" );
  313.     start = mdate();
  314.     printf( " - spawning %i threads that will each create %i objectsn",
  315.             MAXTH * i_level, MAXOBJ/MAXTH );
  316.     for( i = 0; i < MAXTH * i_level; i++ )
  317.     {
  318.         pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
  319.         vlc_thread_create( pp_objects[i], "foo", Dummy, 0, VLC_TRUE );
  320.     }
  321.     printf( " - killing the threads (LIFO)n" );
  322.     for( i = MAXTH * i_level; i--; )
  323.     {
  324.         pp_objects[i]->b_die = VLC_TRUE;
  325.         vlc_thread_join( pp_objects[i] );
  326.         vlc_object_destroy( pp_objects[i] );
  327.     }
  328.     printf( "done (%fs).n", (mdate() - start) / 1000000.0 );
  329.     /* Free required data */
  330.     free( pp_objects );
  331.     free( psz_blob );
  332.     free( ppsz_name );
  333.     return VLC_SUCCESS;
  334. }
  335. /*****************************************************************************
  336.  * Dummy: used by stress-test, creates objects and then do nothing.
  337.  *****************************************************************************/
  338. static void * Dummy( vlc_object_t *p_this )
  339. {
  340.     int i;
  341.     vlc_object_t *pp_objects[MAXOBJ/MAXTH];
  342.     for( i = 0; i < MAXOBJ/MAXTH; i++ )
  343.     {
  344.         pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
  345.     }
  346.     vlc_thread_ready( p_this );
  347.     while( !p_this->b_die )
  348.     {
  349.         msleep( 10000 );
  350.     }
  351.     for( i = MAXOBJ/MAXTH; i--; )
  352.     {
  353.         vlc_object_destroy( pp_objects[i] );
  354.     }
  355.     return NULL;
  356. }
  357. /*****************************************************************************
  358.  * Signal: send a signal to the current thread.
  359.  *****************************************************************************/
  360. static int Signal( vlc_object_t *p_this, char const *psz_cmd,
  361.                    vlc_value_t oldval, vlc_value_t newval, void *p_data )
  362. {
  363.     raise( atoi(newval.psz_string) );
  364.     return VLC_SUCCESS;
  365. }