test4.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:14k
源码类别:

midi

开发平台:

Unix_Linux

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