Changeset 0d37c5b11c5226f990a48d4617f4b70527bb50b3

Show
Ignore:
Timestamp:
05/28/08 19:22:34 (3 months ago)
Author:
Rémi Denis-Courmont <rem@videolan.org>
git-committer:
Rémi Denis-Courmont <rem@videolan.org> 1211995354 +0300
git-parent:

[620675d9d1a3580afb6913dedd642028ee4582eb]

git-author:
Rémi Denis-Courmont <rem@videolan.org> 1211995354 +0300
Message:

Use a doubly-linked list for objects instead of a flat table

Speeds up object creation and deletion, slows down vlc_object_get (which
you should not use anyway, remember), makes no difference for the rest

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/libvlc.h

    r620675d r0d37c5b  
    150150    /* Object structure data */ 
    151151    int                    i_counter;   ///< object counter 
    152     int                    i_objects;   ///< Attached objects count 
    153     vlc_object_t **        pp_objects;  ///< Array of all objects 
    154152 
    155153    module_bank_t *        p_module_bank; ///< The module bank 
     
    185183    vlc_destructor_t pf_destructor; 
    186184 
     185    /* Objects tree structure */ 
     186    vlc_object_t    *prev, *next; 
    187187    vlc_object_t   **pp_children; 
    188188    int              i_children; 
  • src/misc/objects.c

    r1c8c942 r0d37c5b  
    7373static void           PrintObject   ( vlc_object_t *, const char * ); 
    7474static void           DumpStructure ( vlc_object_t *, int, char * ); 
    75 static int            FindIndex     ( vlc_object_t *, vlc_object_t **, int ); 
    7675 
    7776static vlc_list_t   * NewList       ( int ); 
     
    142141 
    143142        p_libvlc_global->i_counter = 0; 
    144         p_libvlc_global->i_objects = 0; 
    145         p_libvlc_global->pp_objects = NULL; 
     143        p_priv->next = p_priv->prev = p_new; 
    146144        vlc_mutex_init( &structure_lock ); 
    147145    } 
     
    172170    p_priv->pipes[0] = p_priv->pipes[1] = -1; 
    173171 
     172    p_priv->next = VLC_OBJECT (p_libvlc_global); 
    174173    vlc_mutex_lock( &structure_lock ); 
     174    p_priv->prev = vlc_internals (p_libvlc_global)->prev; 
     175    vlc_internals (p_libvlc_global)->prev = p_new; 
     176    vlc_internals (p_priv->prev)->next = p_new; 
    175177    p_new->i_object_id = p_libvlc_global->i_counter++; 
    176     /* Wooohaa! If *this* fails, we're in serious trouble! Anyway it's 
    177      * useless to try and recover anything if pp_objects gets smashed. */ 
    178     TAB_APPEND( p_libvlc_global->i_objects, p_libvlc_global->pp_objects, 
    179                 p_new ); 
    180178    vlc_mutex_unlock( &structure_lock ); 
    181179 
     
    341339        assert( p_global == vlc_global() ); 
    342340        /* Test for leaks */ 
    343         if( p_global->i_objects > 0 ) 
    344         { 
    345             int i; 
    346             for( i = 0; i < p_global->i_objects; i++ ) 
    347             { 
    348                 /* We are leaking this object */ 
    349                 fprintf( stderr, 
    350                          "ERROR: leaking object (id:%i, type:%s, name:%s)\n", 
    351                          p_global->pp_objects[i]->i_object_id, 
    352                          p_global->pp_objects[i]->psz_object_type, 
    353                          p_global->pp_objects[i]->psz_object_name ); 
    354  
    355                 /* Dump libvlc object to ease debugging */ 
    356                 vlc_object_dump( p_global->pp_objects[i] ); 
    357  
    358                 fflush(stderr); 
    359             } 
    360  
     341        for( vlc_object_t *leaked = p_priv->next; 
     342             leaked != p_this; 
     343             leaked = vlc_internals (leaked)->next ) 
     344        { 
     345            /* We are leaking this object */ 
     346            fprintf( stderr, 
     347                     "ERROR: leaking object (id:%i, type:%s, name:%s)\n", 
     348                     leaked->i_object_id, leaked->psz_object_type, 
     349                     leaked->psz_object_name ); 
     350            /* Dump libvlc object to ease debugging */ 
     351            vlc_object_dump( leaked ); 
     352            fflush(stderr); 
     353        } 
     354 
     355        if( p_priv->next != p_this ) 
     356        { 
    361357            /* Dump libvlc object to ease debugging */ 
    362358            vlc_object_dump( p_this ); 
    363  
    364359            /* Strongly abort, cause we want these to be fixed */ 
    365360            abort(); 
     
    368363 
    369364        /* We are the global object ... no need to lock. */ 
    370         free( p_global->pp_objects ); 
    371         p_global->pp_objects = NULL; 
    372  
    373365        vlc_mutex_destroy( &structure_lock ); 
    374366    } 
     
    645637void * vlc_object_get( int i_id ) 
    646638{ 
    647     int i_max, i_middle; 
    648     vlc_object_t **pp_objects; 
    649639    libvlc_global_data_t *p_libvlc_global = vlc_global(); 
    650640    vlc_object_t *obj = NULL; 
     
    652642    vlc_mutex_lock( &structure_lock ); 
    653643 
    654     pp_objects = p_libvlc_global->pp_objects; 
    655  
    656     /* Perform our dichotomy */ 
    657     for( i_max = p_libvlc_global->i_objects - 1 ; ; ) 
    658     { 
    659         i_middle = i_max / 2; 
    660  
    661         if( pp_objects[i_middle]->i_object_id > i_id ) 
    662         { 
    663             i_max = i_middle; 
    664         } 
    665         else if( pp_objects[i_middle]->i_object_id < i_id ) 
    666         { 
    667             if( i_middle ) 
    668             { 
    669                 pp_objects += i_middle; 
    670                 i_max -= i_middle; 
    671             } 
    672             else 
    673             { 
    674                 /* This happens when there are only two remaining objects */ 
    675                 if( pp_objects[i_middle+1]->i_object_id == i_id ) 
    676                 { 
    677                     vlc_object_yield( pp_objects[i_middle+1] ); 
    678                     obj = pp_objects[i_middle+1]; 
    679                 } 
    680                 break; 
    681             } 
    682         } 
    683         else 
    684         { 
    685             vlc_object_yield( pp_objects[i_middle] ); 
    686             obj = pp_objects[i_middle]; 
    687             break; 
     644    for( obj = vlc_internals (p_libvlc_global)->next; 
     645         obj != VLC_OBJECT (p_libvlc_global); 
     646         obj = vlc_internals (obj)->next ) 
     647    { 
     648        if( obj->i_object_id == i_id ) 
     649        { 
     650            vlc_object_yield( obj ); 
     651            return obj; 
    688652        } 
    689653    } 
     
    830794    if( b_should_destroy ) 
    831795    { 
    832         /* Remove the object from the table 
     796        /* Remove the object from object list 
    833797         * so that it cannot be encountered by vlc_object_get() */ 
    834         libvlc_global_data_t *p_libvlc_global = vlc_global(); 
    835         int i_index; 
    836  
    837         i_index = FindIndex( p_this, p_libvlc_global->pp_objects, 
    838                              p_libvlc_global->i_objects ); 
    839         REMOVE_ELEM( p_libvlc_global->pp_objects, 
    840                      p_libvlc_global->i_objects, i_index ); 
     798        vlc_internals (internals->next)->prev = internals->prev; 
     799        vlc_internals (internals->prev)->next = internals->next; 
    841800 
    842801        /* Detach from parent to protect against FIND_CHILDREN */ 
     
    1024983                        vlc_value_t oldval, vlc_value_t newval, void *p_data ) 
    1025984{ 
    1026     libvlc_global_data_t *p_libvlc_global = vlc_global(); 
    1027  
    1028985    (void)oldval; (void)p_data; 
    1029986    if( *psz_cmd == 'l' ) 
    1030987    { 
     988        vlc_object_t *root = VLC_OBJECT (vlc_global ()), *cur = root;  
     989 
    1031990        vlc_mutex_lock( &structure_lock ); 
    1032  
    1033         vlc_object_t **pp_current, **pp_end; 
    1034  
    1035         pp_current = p_libvlc_global->pp_objects; 
    1036         pp_end = pp_current + p_libvlc_global->i_objects; 
    1037  
    1038         for( ; pp_current < pp_end ; pp_current++ ) 
    1039             PrintObject( *pp_current, "" ); 
    1040  
     991        do 
     992        { 
     993            PrintObject (cur, ""); 
     994            cur = vlc_internals (cur)->next; 
     995        } 
     996        while (cur != root); 
    1041997        vlc_mutex_unlock( &structure_lock ); 
    1042998    } 
     
    12131169/* Following functions are local */ 
    12141170 
    1215 /***************************************************************************** 
    1216  * FindIndex: find the index of an object in an array of objects 
    1217  ***************************************************************************** 
    1218  * This function assumes that p_this can be found in pp_objects. It will not 
    1219  * crash if p_this cannot be found, but will return a wrong value. It is your 
    1220  * duty to check the return value if you are not certain that the object could 
    1221  * be found for sure. 
    1222  *****************************************************************************/ 
    1223 static int FindIndex( vlc_object_t *p_this, 
    1224                       vlc_object_t **pp_objects, int i_count ) 
    1225 { 
    1226     int i_middle = i_count / 2; 
    1227  
    1228     if( i_count == 0 ) 
    1229     { 
    1230         return 0; 
    1231     } 
    1232  
    1233     if( pp_objects[i_middle] == p_this ) 
    1234     { 
    1235         return i_middle; 
    1236     } 
    1237  
    1238     if( i_count == 1 ) 
    1239     { 
    1240         return 0; 
    1241     } 
    1242  
    1243     /* We take advantage of the sorted array */ 
    1244     if( pp_objects[i_middle]->i_object_id < p_this->i_object_id ) 
    1245     { 
    1246         return i_middle + FindIndex( p_this, pp_objects + i_middle, 
    1247                                              i_count - i_middle ); 
    1248     } 
    1249     else 
    1250     { 
    1251         return FindIndex( p_this, pp_objects, i_middle ); 
    1252     } 
    1253 } 
    1254  
    12551171static vlc_object_t * FindObject( vlc_object_t *p_this, int i_type, int i_mode ) 
    12561172{