1 /*****************************************************************************
2 * test4.c : Miscellaneous stress tests module for vlc
3 *****************************************************************************
4 * Copyright (C) 2002 VideoLAN
5 * $Id: test4.c,v 1.3 2002/10/17 13:15:30 sam Exp $
7 * Authors: Samuel Hocevar <sam@zoy.org>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
32 /*****************************************************************************
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 */
41 /*****************************************************************************
43 *****************************************************************************/
44 static int Callback ( vlc_object_t *, char *, char * );
45 static int MyCallback( vlc_object_t *, char const *,
46 vlc_value_t, vlc_value_t, void * );
47 static void * MyThread ( vlc_object_t * );
49 static int Stress ( vlc_object_t *, char *, char * );
50 static void * Dummy ( vlc_object_t * );
52 static int Signal ( vlc_object_t *, char *, char * );
54 /*****************************************************************************
56 *****************************************************************************/
58 set_description( _("Miscellaneous stress tests") );
59 var_Create( p_module->p_libvlc, "callback-test", VLC_VAR_COMMAND );
60 var_Set( p_module->p_libvlc, "callback-test", (vlc_value_t)(void*)Callback );
61 var_Create( p_module->p_libvlc, "stress-test", VLC_VAR_COMMAND );
62 var_Set( p_module->p_libvlc, "stress-test", (vlc_value_t)(void*)Stress );
63 var_Create( p_module->p_libvlc, "signal", VLC_VAR_COMMAND );
64 var_Set( p_module->p_libvlc, "signal", (vlc_value_t)(void*)Signal );
67 /*****************************************************************************
68 * Callback: test callback functions
69 *****************************************************************************/
70 static int Callback( vlc_object_t *p_this, char *psz_cmd, char *psz_arg )
74 vlc_object_t *pp_objects[10];
77 /* Allocate a few variables */
78 for( i = 0; i < 1000; i++ )
80 sprintf( psz_var, "blork-%i", i );
81 var_Create( p_this, psz_var, VLC_VAR_INTEGER );
82 var_AddCallback( p_this, psz_var, MyCallback, NULL );
86 * Test #1: callback loop detection
88 printf( "Test #1: callback loop detection\n" );
90 printf( " - without boundary check (vlc should print an error)\n" );
92 var_Set( p_this, "blork-12", val );
94 printf( " - with boundary check\n" );
96 var_Set( p_this, "blork-12", val );
99 * Test #2: concurrent access
101 printf( "Test #2: concurrent access\n" );
103 printf( " - launch worker threads\n" );
105 for( i = 0; i < 10; i++ )
107 pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
108 vlc_object_attach( pp_objects[i], p_this );
109 vlc_thread_create( pp_objects[i], "foo", MyThread, 0, VLC_TRUE );
114 printf( " - kill worker threads\n" );
116 for( i = 0; i < 10; i++ )
118 pp_objects[i]->b_die = VLC_TRUE;
119 vlc_thread_join( pp_objects[i] );
120 vlc_object_detach( pp_objects[i] );
121 vlc_object_destroy( pp_objects[i] );
125 for( i = 0; i < 1000; i++ )
127 sprintf( psz_var, "blork-%i", i );
128 var_DelCallback( p_this, psz_var, MyCallback, NULL );
129 var_Destroy( p_this, psz_var );
135 /*****************************************************************************
136 * MyCallback: used by callback-test
137 *****************************************************************************/
138 static int MyCallback( vlc_object_t *p_this, char const *psz_var,
139 vlc_value_t oldval, vlc_value_t newval, void *p_data )
141 int i_var = 1 + atoi( psz_var + strlen("blork-") );
149 /* If we are requested to stop, then stop. */
150 if( i_var == newval.i_int )
155 /* If we're the blork-3 callback, set blork-4, and so on. */
156 sprintf( psz_newvar, "blork-%i", i_var );
157 var_Set( p_this, psz_newvar, newval );
162 /*****************************************************************************
163 * MyThread: used by callback-test, creates objects and then do nothing.
164 *****************************************************************************/
165 static void * MyThread( vlc_object_t *p_this )
169 vlc_object_t *p_parent = p_this->p_parent;
171 vlc_thread_ready( p_this );
175 while( !p_this->b_die )
177 int i = (int) (100.0 * rand() / (RAND_MAX));
179 sprintf( psz_var, "blork-%i", i );
181 var_Set( p_parent, psz_var, val );
183 /* This is quite heavy, but we only have 10 threads. Keep cool. */
190 /*****************************************************************************
191 * Stress: perform various stress tests
192 *****************************************************************************/
193 static int Stress( vlc_object_t *p_this, char *psz_cmd, char *psz_arg )
195 vlc_object_t **pp_objects;
203 i_level = atoi( psz_arg );
208 else if( i_level > 200 )
210 /* It becomes quite dangerous above 150 */
219 /* Allocate required data */
220 ppsz_name = malloc( MAXVAR * i_level * sizeof(char*) );
221 psz_blob = malloc( 20 * MAXVAR * i_level * sizeof(char) );
222 for( i = 0; i < MAXVAR * i_level; i++ )
224 ppsz_name[i] = psz_blob + 20 * i;
227 pp_objects = malloc( MAXOBJ * i_level * sizeof(void*) );
232 printf( "Test #1: objects\n" );
234 printf( " - creating %i objects\n", MAXOBJ * i_level );
236 for( i = 0; i < MAXOBJ * i_level; i++ )
238 pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
241 printf( " - randomly looking up %i objects\n", MAXLOOK * i_level );
242 for( i = MAXLOOK * i_level; i--; )
244 int id = (int) (MAXOBJ * i_level * 1.0 * rand() / (RAND_MAX));
245 vlc_object_get( p_this, pp_objects[id]->i_object_id );
248 printf( " - destroying the objects (LIFO)\n" );
249 for( i = MAXOBJ * i_level; i--; )
251 vlc_object_destroy( pp_objects[i] );
254 printf( "done (%fs).\n", (mdate() - start) / 1000000.0 );
257 * Test #2: integer variables
259 printf( "Test #2: integer variables\n" );
261 printf( " - creating %i integer variables\n", MAXVAR * i_level );
263 for( i = 0; i < MAXVAR * i_level; i++ )
265 sprintf( ppsz_name[i], "foo-%04i-bar-%04x", i, i * 11 );
266 var_Create( p_this, ppsz_name[i], VLC_VAR_INTEGER );
269 printf( " - randomly assigning %i values\n", MAXSET * i_level );
270 for( i = 0; i < MAXSET * i_level; i++ )
272 int v = (int) (MAXVAR * i_level * 1.0 * rand() / (RAND_MAX));
273 var_Set( p_this, ppsz_name[v], (vlc_value_t)i );
276 printf( " - destroying the variables\n" );
277 for( i = 0; i < MAXVAR * i_level; i++ )
279 var_Destroy( p_this, ppsz_name[i] );
282 printf( "done (%fs).\n", (mdate() - start) / 1000000.0 );
285 * Test #3: string variables
287 printf( "Test #3: string variables\n" );
289 printf( " - creating %i string variables\n", MAXVAR * i_level );
291 for( i = 0; i < MAXVAR * i_level; i++ )
293 sprintf( ppsz_name[i], "foo-%04i-bar-%04x", i, i * 11 );
294 var_Create( p_this, ppsz_name[i], VLC_VAR_STRING );
297 printf( " - randomly assigning %i values\n", MAXSET * i_level );
298 for( i = 0; i < MAXSET * i_level; i++ )
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] );
304 printf( " - destroying the variables\n" );
305 for( i = 0; i < MAXVAR * i_level; i++ )
307 var_Destroy( p_this, ppsz_name[i] );
310 printf( "done (%fs).\n", (mdate() - start) / 1000000.0 );
315 printf( "Test #4: threads\n" );
318 printf( " - spawning %i threads that will each create %i objects\n",
319 MAXTH * i_level, MAXOBJ/MAXTH );
320 for( i = 0; i < MAXTH * i_level; i++ )
322 pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
323 vlc_thread_create( pp_objects[i], "foo", Dummy, 0, VLC_TRUE );
326 printf( " - killing the threads (LIFO)\n" );
327 for( i = MAXTH * i_level; i--; )
329 pp_objects[i]->b_die = VLC_TRUE;
330 vlc_thread_join( pp_objects[i] );
331 vlc_object_destroy( pp_objects[i] );
334 printf( "done (%fs).\n", (mdate() - start) / 1000000.0 );
336 /* Free required data */
344 /*****************************************************************************
345 * Dummy: used by stress-test, creates objects and then do nothing.
346 *****************************************************************************/
347 static void * Dummy( vlc_object_t *p_this )
350 vlc_object_t *pp_objects[MAXOBJ/MAXTH];
352 for( i = 0; i < MAXOBJ/MAXTH; i++ )
354 pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
357 vlc_thread_ready( p_this );
359 while( !p_this->b_die )
364 for( i = MAXOBJ/MAXTH; i--; )
366 vlc_object_destroy( pp_objects[i] );
372 /*****************************************************************************
373 * Signal: send a signal to the current thread.
374 *****************************************************************************/
375 static int Signal( vlc_object_t *p_this, char *psz_cmd, char *psz_arg )
377 raise( atoi(psz_arg) );