From 0326005e1cb52ee615b50c545a2e9fae858a9214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Stenac?= Date: Sun, 1 Oct 2006 14:24:44 +0000 Subject: [PATCH] Lazy allocation of the stat structure Update stats in the input threads instead of playlist thread --- include/main.h | 2 +- include/vlc_input.h | 15 ++++++++------- include/vlc_playlist.h | 2 ++ src/input/input.c | 41 ++++++++++++++++++++++++++++++++++++++++- src/playlist/thread.c | 21 +-------------------- 5 files changed, 52 insertions(+), 29 deletions(-) diff --git a/include/main.h b/include/main.h index df9c78f4cc..914a7514c0 100644 --- a/include/main.h +++ b/include/main.h @@ -35,7 +35,7 @@ struct libvlc_global_data_t vlc_bool_t b_ready; ///< Initialization boolean uint32_t i_cpu; ///< CPU extensions - + /* Object structure data */ int i_counter; ///< object counter int i_objects; ///< Attached objects count diff --git a/include/vlc_input.h b/include/vlc_input.h index ee120936a3..7e2bd30789 100644 --- a/include/vlc_input.h +++ b/include/vlc_input.h @@ -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->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; - vlc_mutex_init( p_o, &p_i->p_stats->lock ); vlc_mutex_init( p_o, &p_i->lock ); } @@ -131,11 +130,13 @@ VLC_EXPORT( void, input_ItemAddOptionNoDup,( input_item_t *, const char * ) ); static inline void input_ItemClean( input_item_t *p_i ) { - if( p_i->psz_name ) free( p_i->psz_name ); - if( p_i->psz_uri ) free( p_i->psz_uri ); - if( p_i->p_stats ) free( p_i->p_stats ); - p_i->psz_name = 0; - p_i->psz_uri = 0; + free( p_i->psz_name ); + free( p_i->psz_uri ); + if( p_i->p_stats ) + { + 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 ); diff --git a/include/vlc_playlist.h b/include/vlc_playlist.h index 7069c14548..2b396535e5 100644 --- a/include/vlc_playlist.h +++ b/include/vlc_playlist.h @@ -173,6 +173,8 @@ struct playlist_t // Playlist-unrelated fields interaction_t *p_interaction; /**< Interaction manager */ + /** The input thread computing stats */ + input_thread_t *p_stats_computer; global_stats_t *p_stats; /**< Global statistics */ /*@}*/ }; diff --git a/src/input/input.c b/src/input/input.c index 658bfdc6cd..6965789770 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -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" ); 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->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, if( !p_input->input.p_item->p_meta ) 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 */ p_input->i_slave = 0; @@ -515,6 +534,7 @@ static int RunAndClean( input_thread_t *p_input ) static void MainLoop( input_thread_t *p_input ) { int64_t i_intf_update = 0; + int i_updates = 0; while( !p_input->b_die && !p_input->b_error && !p_input->input.b_eof ) { vlc_bool_t b_force_update = VLC_FALSE; @@ -662,6 +682,17 @@ static void MainLoop( input_thread_t *p_input ) var_SetBool( p_input, "intf-change", VLC_TRUE ); 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 ) #define CL_CO( c ) stats_CounterClean( p_input->counters.p_##c ); p_input->counters.p_##c = NULL; 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 ); CL_CO( read_bytes ); CL_CO( read_packets ); diff --git a/src/playlist/thread.c b/src/playlist/thread.c index 8f7169b2a7..a3cc707a6f 100644 --- a/src/playlist/thread.c +++ b/src/playlist/thread.c @@ -40,8 +40,6 @@ static void HandlePlaylist( playlist_t * ); static void EndPlaylist( playlist_t * ); static void DestroyPlaylist( playlist_t * ); -static void HandleStats( playlist_t *, int ); - static void HandleInteraction( playlist_t * ); static void DestroyInteraction( playlist_t * ); @@ -68,6 +66,7 @@ void __playlist_ThreadCreate( vlc_object_t *p_parent ) // Stats p_playlist->p_stats = (global_stats_t *)malloc( sizeof( global_stats_t ) ); vlc_mutex_init( p_playlist, &p_playlist->p_stats->lock ); + p_playlist->p_stats_computer = NULL; // Interaction p_playlist->p_interaction = NULL; @@ -169,7 +168,6 @@ static void RunControlThread ( playlist_t *p_playlist ) i_loops++; HandleInteraction( p_playlist ); - HandleStats( p_playlist, i_loops ); HandlePlaylist( p_playlist ); /* 100 ms is an acceptable delay for playlist operations */ @@ -247,20 +245,3 @@ static void HandleInteraction( playlist_t *p_playlist ) 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 ); - } - } -} -- GitLab