change the way thread name is managed and accessed; store thread name for JACK thread...
authorPaul Davis <paul@linuxaudiosystems.com>
Sat, 26 Dec 2009 16:15:11 +0000 (16:15 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Sat, 26 Dec 2009 16:15:11 +0000 (16:15 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@6399 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/audioengine.cc
libs/ardour/session.cc
libs/ardour/session_state.cc
libs/pbd/boost_debug.cc
libs/pbd/pbd/pthread_utils.h
libs/pbd/pthread_utils.cc

index 5b6a7da73a3d200c531cd0e2a1d04c4af5a30615..900f0893da714fdb429bdc9912962df61906bb36 100644 (file)
@@ -134,6 +134,10 @@ _thread_init_callback (void * /*arg*/)
           knows about it.
        */
 
+       char* c = new char[12];
+       strcpy (c, X_("audioengine"));
+       pthread_set_name (c);
+
        PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("Audioengine"), 4096);
        PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("Audioengine"), 128);
 
index f0d69fec28087484a74965466b7668e843392265..d512d49b3943ff6b458955aa2be4cd784890c81f 100644 (file)
@@ -425,7 +425,6 @@ Session::destroy ()
        routes.flush ();
 
        boost::shared_ptr<RouteList> r = routes.reader ();
-       cerr << "\n\n\n AFTER ROUTE CLEARING, there are " << r->size() << " routes in RCU\n";
 
        DEBUG_TRACE (DEBUG::Destruction, "delete diskstreams\n");
        {
@@ -2129,20 +2128,21 @@ Session::add_routes (RouteList& new_routes, bool save)
        for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
 
                boost::weak_ptr<Route> wpr (*x);
+               boost::shared_ptr<Route> r (*x);
 
-               (*x)->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
-               (*x)->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, wpr));
-               (*x)->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
-               (*x)->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
-               (*x)->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
-               (*x)->route_group_changed.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
+               r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
+               r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, wpr));
+               r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
+               r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
+               r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
+               r->route_group_changed.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
 
-               if ((*x)->is_master()) {
-                       _master_out = (*x);
+               if (r->is_master()) {
+                       _master_out = r;
                }
 
-               if ((*x)->is_control()) {
-                       _control_out = (*x);
+               if (r->is_control()) {
+                       _control_out = r;
                }
        }
 
index b733531ac4daa7ba6de044b3c4d546aff175f2ea..13b9112866d264d7dcb71248b02636d5e5b1c404 100644 (file)
@@ -1104,7 +1104,6 @@ Session::set_state (const XMLNode& node, int version)
        XMLNode* child;
        const XMLProperty* prop;
        int ret = -1;
-       extern void boost_debug_shared_ptr_show_live_debugging (bool);
 
        _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
 
@@ -1379,6 +1378,7 @@ Session::XMLRouteFactory (const XMLNode& node, int version)
 
        DataType type = DataType::AUDIO;
        const XMLProperty* prop = node.property("default-type");
+       boost::shared_ptr<Route> ret;
 
        if (prop) {
                type = DataType(prop->value());
@@ -1390,17 +1390,18 @@ Session::XMLRouteFactory (const XMLNode& node, int version)
                if (type == DataType::AUDIO) {
                        AudioTrack* at = new AudioTrack (*this, node, version);
                        boost_debug_shared_ptr_mark_interesting (at, "Track");
-                       return boost::shared_ptr<Route> (at);
-
+                       ret.reset (at);
+                       
                } else {
-                       boost::shared_ptr<Route> ret (new MidiTrack (*this, node, version));
-                       return ret;
+                       ret.reset (new MidiTrack (*this, node, version));
                }
        } else {
                Route* rt = new Route (*this, node);
                boost_debug_shared_ptr_mark_interesting (rt, "Route");
-               return boost::shared_ptr<Route> (rt);
+               ret.reset (rt);
        }
+
+       return ret;
 }
 
 int
index f828f7d17bf23486eaddaa090bd8d40577f968a7..751941983c95cab9774463d3c80671257c549f82 100644 (file)
@@ -65,7 +65,7 @@ Backtrace::print (std::ostream& str) const
                strings = ::backtrace_symbols (trace, size);
 #endif         
                if (strings) {
-                       for (i = 5; i < 5+18 && i < size; i++) {
+                       for (i = 3; i < 5+18 && i < size; i++) {
                                str << strings[i] << std::endl;
                        }
                        free (strings);
@@ -204,13 +204,51 @@ boost_debug_shared_ptr_operator_equals (void const *sp, void const *old_obj, int
 }
 
 void
-boost_debug_shared_ptr_reset (void const *sp, void const *obj, int use_count)
+boost_debug_shared_ptr_reset (void const *sp, void const *old_obj, int old_use_count,  void const *obj, int new_use_count)
 {
-       if (is_interesting_object (obj)) {
+       if (old_obj == 0 && obj == 0) {
+               return;
+       }
+
+       Glib::Mutex::Lock guard (the_lock);
+
+       if (is_interesting_object  (old_obj) || is_interesting_object (obj)) {
                if (debug_out) {
-                       cerr << "reset sp to object @ " << obj << " @ " << sp << " UC was " << use_count << " (total sp's = " << sptrs.size() << ')' << endl;
+                       cerr << "RESET SWAPS " << old_obj << " & " << obj << endl;
+               }
+       }
+
+       if (is_interesting_object (old_obj)) {
+               if (debug_out) {
+                       cerr << "\tlost old sp @ " << sp << " for " << old_obj << " UC = " << old_use_count << " now for " << obj << " UC = " << new_use_count 
+                            << " (total sp's = " << sptrs.size() << ')' << endl;                       
+               }
+               PointerMap::iterator x = sptrs.find (sp);
+               
+               if (x != sptrs.end()) {
+                       sptrs.erase (x);
+                       if (debug_out) {
+                               cerr << "\tRemoved (by reset) sp for " << old_obj << " @ " << sp << " UC = " << old_use_count << " (total sp's = " << sptrs.size() << ')' << endl;
+                       }
                }
        }
+
+       if (is_interesting_object (obj)) {
+
+               pair<void const*, SPDebug*> newpair;
+
+               newpair.first = sp;
+               newpair.second = new SPDebug (new Backtrace());
+
+               sptrs.insert (newpair);
+               
+               if (debug_out) {
+                       cerr << "reset created sp for " << obj << " @ " << sp << " used to point to " << old_obj << " UC = " << old_use_count 
+                            << " UC = " << new_use_count 
+                            << " (total sp's = " << sptrs.size() << ')' << endl;                       
+                       cerr << *newpair.second << endl;
+               }
+       } 
 }
 
 void
index b8f99ba1440257475fe4cf6775fc68a363bc676e..793c3a19807e6d987510ae020d2e6536fd84c6f4 100644 (file)
@@ -32,7 +32,8 @@ void pthread_cancel_one (pthread_t thread);
 void pthread_cancel_all ();
 void pthread_kill_all (int signum);
 void pthread_exit_pbd (void* status);
-std::string pthread_name ();
+const char* pthread_name ();
+void pthread_set_name (const char* name);
 
 namespace PBD {
        extern void notify_gui_about_thread_creation (std::string, pthread_t, std::string, int requests = 256);
index ca636034468d68021cb6b70d96d0c82be120391f..34ac6fd1afabba93e4b262da4f1b9fc60c68311d 100644 (file)
@@ -18,7 +18,7 @@
     $Id$
 */
 
-#include <map>
+#include <set>
 #include <iostream>
 #include <string>
 #include <stdint.h>
 
 using namespace std;
 
-typedef std::map<string,pthread_t> ThreadMap;
+typedef std::set<pthread_t> ThreadMap;
 static ThreadMap all_threads;
 static pthread_mutex_t thread_map_lock = PTHREAD_MUTEX_INITIALIZER;
+static Glib::StaticPrivate<char> thread_name;
 
 namespace PBD {
        PBD::Signal4<void,std::string, pthread_t,std::string,uint32_t> ThreadCreatedWithRequestSize;
@@ -55,23 +56,48 @@ PBD::notify_gui_about_thread_creation (std::string target_gui, pthread_t thread,
        ThreadCreatedWithRequestSize (target_gui, thread, str, request_count);
 }
 
+struct ThreadStartWithName {
+    void* (*thread_work)(void*);
+    void* arg;
+    const char* name;
+    
+    ThreadStartWithName (void* (*f)(void*), void* a, const char* s)
+           : thread_work (f), arg (a), name (s) {}
+};
+
+static void*
+fake_thread_start (void* arg)
+{
+       ThreadStartWithName* ts = (ThreadStartWithName*) arg;
+       void* (*thread_work)(void*) = ts->thread_work;
+       void* thread_arg = ts->arg;
+
+       pthread_set_name (ts->name);
+
+       delete ts;
+       /* name will be deleted by the default handler for GStaticPrivate, when the thread exits */
+
+       return thread_work (thread_arg);
+}
+
 int  
 pthread_create_and_store (string name, pthread_t  *thread, void * (*start_routine)(void *), void * arg)
 {
        pthread_attr_t default_attr;
        int ret;
-       
+
        // set default stack size to sensible default for memlocking
        pthread_attr_init(&default_attr);
        pthread_attr_setstacksize(&default_attr, 500000);
 
-       if ((ret = thread_creator (thread, &default_attr, start_routine, arg)) == 0) {
-               std::pair<string,pthread_t> newpair;
-               newpair.first = name;
-               newpair.second = *thread;
+       char* cname = new char[name.length() + 1];
+       strcpy (cname, name.c_str());
 
+       ThreadStartWithName* ts = new ThreadStartWithName (start_routine, arg, cname);
+
+       if ((ret = thread_creator (thread, &default_attr, fake_thread_start, ts)) == 0) {
                pthread_mutex_lock (&thread_map_lock);
-               all_threads.insert (newpair);
+               all_threads.insert (*thread);
                pthread_mutex_unlock (&thread_map_lock);
        }
 
@@ -80,21 +106,21 @@ pthread_create_and_store (string name, pthread_t  *thread, void * (*start_routin
        return ret;
 }
 
-string
+void
+pthread_set_name (const char *str)
+{
+       /* str will be deleted when this thread exits */
+       thread_name.set (const_cast<char*>(str));
+}
+
+const char *
 pthread_name ()
 {
-       pthread_t self = pthread_self();
-       string str;
+       const char* str = thread_name.get ();
 
-       pthread_mutex_lock (&thread_map_lock);
-       for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) {
-               if (i->second == self) {
-                       str = i->first;
-                       pthread_mutex_unlock (&thread_map_lock);
-                       return str;
-               }
-       }
-       pthread_mutex_unlock (&thread_map_lock);
+       if (str) {
+               return str;
+       } 
        return "unknown";
 }
 
@@ -103,8 +129,8 @@ pthread_kill_all (int signum)
 {      
        pthread_mutex_lock (&thread_map_lock);
        for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) {
-               if (i->second != pthread_self()) {
-                       pthread_kill (i->second, signum);
+               if ((*i) != pthread_self()) {
+                       pthread_kill ((*i), signum);
                }
        }
        all_threads.clear();
@@ -116,8 +142,8 @@ pthread_cancel_all ()
 {      
        pthread_mutex_lock (&thread_map_lock);
        for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) {
-               if (i->second != pthread_self()) {
-                       pthread_cancel (i->second);
+               if ((*i) != pthread_self()) {
+                       pthread_cancel ((*i));
                }
        }
        all_threads.clear();
@@ -129,7 +155,7 @@ pthread_cancel_one (pthread_t thread)
 {      
        pthread_mutex_lock (&thread_map_lock);
        for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) {
-               if (i->second == thread) {
+               if ((*i) == thread) {
                        all_threads.erase (i);
                        break;
                }
@@ -146,7 +172,7 @@ pthread_exit_pbd (void* status)
 
        pthread_mutex_lock (&thread_map_lock);
        for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) {
-               if (i->second == thread) {
+               if ((*i) == thread) {
                        all_threads.erase (i);
                        break;
                }