Commit 0326005e authored by Clément Stenac's avatar Clément Stenac

Lazy allocation of the stat structure

Update stats in the input threads instead of playlist thread
parent 05aad79a
...@@ -35,7 +35,7 @@ struct libvlc_global_data_t ...@@ -35,7 +35,7 @@ struct libvlc_global_data_t
vlc_bool_t b_ready; ///< Initialization boolean vlc_bool_t b_ready; ///< Initialization boolean
uint32_t i_cpu; ///< CPU extensions uint32_t i_cpu; ///< CPU extensions
/* Object structure data */ /* Object structure data */
int i_counter; ///< object counter int i_counter; ///< object counter
int i_objects; ///< Attached objects count int i_objects; ///< Attached objects count
......
...@@ -104,9 +104,8 @@ static inline void input_ItemInit( vlc_object_t *p_o, input_item_t *p_i ) ...@@ -104,9 +104,8 @@ static inline void input_ItemInit( vlc_object_t *p_o, input_item_t *p_i )
p_i->i_type = ITEM_TYPE_UNKNOWN; p_i->i_type = ITEM_TYPE_UNKNOWN;
p_i->b_fixed_name = VLC_TRUE; p_i->b_fixed_name = VLC_TRUE;
p_i->p_stats = (input_stats_t*) malloc( sizeof( input_stats_t ) ); p_i->p_stats = NULL;
p_i->p_meta = NULL; p_i->p_meta = NULL;
vlc_mutex_init( p_o, &p_i->p_stats->lock );
vlc_mutex_init( p_o, &p_i->lock ); vlc_mutex_init( p_o, &p_i->lock );
} }
...@@ -131,11 +130,13 @@ VLC_EXPORT( void, input_ItemAddOptionNoDup,( input_item_t *, const char * ) ); ...@@ -131,11 +130,13 @@ VLC_EXPORT( void, input_ItemAddOptionNoDup,( input_item_t *, const char * ) );
static inline void input_ItemClean( input_item_t *p_i ) static inline void input_ItemClean( input_item_t *p_i )
{ {
if( p_i->psz_name ) free( p_i->psz_name ); free( p_i->psz_name );
if( p_i->psz_uri ) free( p_i->psz_uri ); free( p_i->psz_uri );
if( p_i->p_stats ) free( p_i->p_stats ); if( p_i->p_stats )
p_i->psz_name = 0; {
p_i->psz_uri = 0; vlc_mutex_destroy( &p_i->p_stats->lock );
free( p_i->p_stats );
}
if( p_i->p_meta ) vlc_meta_Delete( p_i->p_meta ); if( p_i->p_meta ) vlc_meta_Delete( p_i->p_meta );
......
...@@ -173,6 +173,8 @@ struct playlist_t ...@@ -173,6 +173,8 @@ struct playlist_t
// Playlist-unrelated fields // Playlist-unrelated fields
interaction_t *p_interaction; /**< Interaction manager */ interaction_t *p_interaction; /**< Interaction manager */
/** The input thread computing stats */
input_thread_t *p_stats_computer;
global_stats_t *p_stats; /**< Global statistics */ global_stats_t *p_stats; /**< Global statistics */
/*@}*/ /*@}*/
}; };
......
...@@ -120,6 +120,19 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item, ...@@ -120,6 +120,19 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
msg_Err( p_parent, "out of memory" ); msg_Err( p_parent, "out of memory" );
return NULL; return NULL;
} }
/* One "randomly" selected input thread is responsible for computing
* the global stats. Check if there is already someone doing this */
if( p_input->p_libvlc->p_playlist->p_stats && !b_quick )
{
vlc_mutex_lock( &p_input->p_libvlc->p_playlist->p_stats->lock );
if( p_input->p_libvlc->p_playlist->p_stats_computer == NULL )
{
p_input->p_libvlc->p_playlist->p_stats_computer = p_input;
}
vlc_mutex_unlock( &p_input->p_libvlc->p_playlist->p_stats->lock );
}
p_input->b_preparsing = b_quick; p_input->b_preparsing = b_quick;
p_input->psz_header = psz_header ? strdup( psz_header ) : NULL; p_input->psz_header = psz_header ? strdup( psz_header ) : NULL;
...@@ -157,7 +170,13 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item, ...@@ -157,7 +170,13 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
if( !p_input->input.p_item->p_meta ) if( !p_input->input.p_item->p_meta )
p_input->input.p_item->p_meta = vlc_meta_New(); p_input->input.p_item->p_meta = vlc_meta_New();
stats_ReinitInputStats( p_item->p_stats );
if( !p_item->p_stats )
{
p_item->p_stats = (input_stats_t*)malloc( sizeof( input_stats_t ) );
vlc_mutex_init( p_input, &p_item->p_stats->lock );
stats_ReinitInputStats( p_item->p_stats );
}
/* No slave */ /* No slave */
p_input->i_slave = 0; p_input->i_slave = 0;
...@@ -515,6 +534,7 @@ static int RunAndClean( input_thread_t *p_input ) ...@@ -515,6 +534,7 @@ static int RunAndClean( input_thread_t *p_input )
static void MainLoop( input_thread_t *p_input ) static void MainLoop( input_thread_t *p_input )
{ {
int64_t i_intf_update = 0; int64_t i_intf_update = 0;
int i_updates = 0;
while( !p_input->b_die && !p_input->b_error && !p_input->input.b_eof ) while( !p_input->b_die && !p_input->b_error && !p_input->input.b_eof )
{ {
vlc_bool_t b_force_update = VLC_FALSE; vlc_bool_t b_force_update = VLC_FALSE;
...@@ -662,6 +682,17 @@ static void MainLoop( input_thread_t *p_input ) ...@@ -662,6 +682,17 @@ static void MainLoop( input_thread_t *p_input )
var_SetBool( p_input, "intf-change", VLC_TRUE ); var_SetBool( p_input, "intf-change", VLC_TRUE );
i_intf_update = mdate() + I64C(150000); i_intf_update = mdate() + I64C(150000);
} }
/* 150ms * 8 = ~ 1 second */
if( ++i_updates % 8 == 0 )
{
stats_ComputeInputStats( p_input, p_input->input.p_item->p_stats );
/* Are we the thread responsible for computing global stats ? */
if( p_input->p_libvlc->p_playlist->p_stats_computer == p_input )
{
stats_ComputeGlobalStats( p_input->p_libvlc->p_playlist,
p_input->p_libvlc->p_playlist->p_stats );
}
}
} }
} }
...@@ -1119,6 +1150,14 @@ static void End( input_thread_t * p_input ) ...@@ -1119,6 +1150,14 @@ static void End( input_thread_t * p_input )
#define CL_CO( c ) stats_CounterClean( p_input->counters.p_##c ); p_input->counters.p_##c = NULL; #define CL_CO( c ) stats_CounterClean( p_input->counters.p_##c ); p_input->counters.p_##c = NULL;
if( p_input->p_libvlc->b_stats ) if( p_input->p_libvlc->b_stats )
{ {
/* make sure we are up to date */
stats_ComputeInputStats( p_input, p_input->input.p_item->p_stats );
if( p_input->p_libvlc->p_playlist->p_stats_computer == p_input )
{
stats_ComputeGlobalStats( p_input->p_libvlc->p_playlist,
p_input->p_libvlc->p_playlist->p_stats );
p_input->p_libvlc->p_playlist->p_stats_computer = NULL;
}
vlc_mutex_lock( &p_input->counters.counters_lock ); vlc_mutex_lock( &p_input->counters.counters_lock );
CL_CO( read_bytes ); CL_CO( read_bytes );
CL_CO( read_packets ); CL_CO( read_packets );
......
...@@ -40,8 +40,6 @@ static void HandlePlaylist( playlist_t * ); ...@@ -40,8 +40,6 @@ static void HandlePlaylist( playlist_t * );
static void EndPlaylist( playlist_t * ); static void EndPlaylist( playlist_t * );
static void DestroyPlaylist( playlist_t * ); static void DestroyPlaylist( playlist_t * );
static void HandleStats( playlist_t *, int );
static void HandleInteraction( playlist_t * ); static void HandleInteraction( playlist_t * );
static void DestroyInteraction( playlist_t * ); static void DestroyInteraction( playlist_t * );
...@@ -68,6 +66,7 @@ void __playlist_ThreadCreate( vlc_object_t *p_parent ) ...@@ -68,6 +66,7 @@ void __playlist_ThreadCreate( vlc_object_t *p_parent )
// Stats // Stats
p_playlist->p_stats = (global_stats_t *)malloc( sizeof( global_stats_t ) ); p_playlist->p_stats = (global_stats_t *)malloc( sizeof( global_stats_t ) );
vlc_mutex_init( p_playlist, &p_playlist->p_stats->lock ); vlc_mutex_init( p_playlist, &p_playlist->p_stats->lock );
p_playlist->p_stats_computer = NULL;
// Interaction // Interaction
p_playlist->p_interaction = NULL; p_playlist->p_interaction = NULL;
...@@ -169,7 +168,6 @@ static void RunControlThread ( playlist_t *p_playlist ) ...@@ -169,7 +168,6 @@ static void RunControlThread ( playlist_t *p_playlist )
i_loops++; i_loops++;
HandleInteraction( p_playlist ); HandleInteraction( p_playlist );
HandleStats( p_playlist, i_loops );
HandlePlaylist( p_playlist ); HandlePlaylist( p_playlist );
/* 100 ms is an acceptable delay for playlist operations */ /* 100 ms is an acceptable delay for playlist operations */
...@@ -247,20 +245,3 @@ static void HandleInteraction( playlist_t *p_playlist ) ...@@ -247,20 +245,3 @@ static void HandleInteraction( playlist_t *p_playlist )
stats_TimerStop( p_playlist, STATS_TIMER_INTERACTION ); stats_TimerStop( p_playlist, STATS_TIMER_INTERACTION );
} }
} }
/*****************************************************************************
* Stats functions
*****************************************************************************/
static void HandleStats( playlist_t *p_playlist, int i_loops )
{
if( i_loops % 5 == 0 && p_playlist->p_stats )
{
stats_ComputeGlobalStats( p_playlist, p_playlist->p_stats );
if( p_playlist->p_input )
{
stats_ComputeInputStats( p_playlist->p_input,
p_playlist->p_input->input.p_item->p_stats );
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment