diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index caca3e7a945177152543fe73b61c2850879135b6..e0ee3438ad00d3c07ef2c79d5727cf5eff5d967e 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,17 @@
+2006-11-07  Benjamin Kosnik  <bkoz@redhat.com>
+
+	PR libstdc++/29722
+	* include/ext/concurrence.h (concurrence_lock_error): New.
+	(concurrence_unlock_error): New.
+	(__throw_concurrence_lock_error): New.
+	(__throw_concurrence_unlock_error): New.
+	(__mutex): Use functions.
+	(__recursive_mutex): Same.
+	* testsuite/abi/cxx_runtime_only_linkage.cc: New.
+
+	* include/ext/pb_ds/exception.hpp: Keep exception classes defined
+	even when -fno-exceptions is passed, consistent with other usage.
+	
 2006-11-07  Benjamin Kosnik  <bkoz@redhat.com>
 
 	* include/ext/pb_ds/exception.hpp (pb_ds): Modify for -fno-exceptions.
diff --git a/libstdc++-v3/include/ext/concurrence.h b/libstdc++-v3/include/ext/concurrence.h
index a19ba8eef4b4f8df02fd974ce9cd492c485b3011..868264ddb533e48f32b061bd5f30cd0f2497ec9e 100644
--- a/libstdc++-v3/include/ext/concurrence.h
+++ b/libstdc++-v3/include/ext/concurrence.h
@@ -36,6 +36,8 @@
 #ifndef _CONCURRENCE_H
 #define _CONCURRENCE_H 1
 
+#include <cstdlib>
+#include <exception>
 #include <bits/gthr.h> 
 #include <bits/functexcept.h>
 
@@ -62,6 +64,45 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
 #else
   _S_single;
 #endif
+  
+  // NB: As this is used in libsupc++, need to only depend on
+  // exception. No stdexception classes, no use of std::string.
+  class concurrence_lock_error : public std::exception
+  {
+  public:
+    virtual char const*
+    what() const throw()
+    { return "__gnu_cxx::concurrence_lock_error"; }
+  };
+
+  class concurrence_unlock_error : public std::exception
+  {
+  public:
+    virtual char const*
+    what() const throw()
+    { return "__gnu_cxx::concurrence_unlock_error"; }
+  };
+
+  // Substitute for concurrence_error object in the case of -fno-exceptions.
+  inline void
+  __throw_concurrence_lock_error()
+  {
+#if __EXCEPTIONS
+    throw concurrence_lock_error();
+#else
+    std::abort();
+#endif
+  }
+
+  inline void
+  __throw_concurrence_unlock_error()
+  {
+#if __EXCEPTIONS
+    throw concurrence_unlock_error();
+#else
+    std::abort();
+#endif
+  }
 
   class __mutex 
   {
@@ -93,7 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
       if (__gthread_active_p())
 	{
 	  if (__gthread_mutex_lock(&_M_mutex) != 0)
-	    std::__throw_runtime_error(__N("__mutex::lock"));
+	    __throw_concurrence_lock_error();
 	}
 #endif
     }
@@ -104,7 +145,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
       if (__gthread_active_p())
 	{
 	  if (__gthread_mutex_unlock(&_M_mutex) != 0)
-	    std::__throw_runtime_error(__N("__mutex::unlock"));
+	    __throw_concurrence_unlock_error();
 	}
 #endif
     }
@@ -140,7 +181,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
       if (__gthread_active_p())
 	{
 	  if (__gthread_recursive_mutex_lock(&_M_mutex) != 0)
-	    std::__throw_runtime_error(__N("__recursive_mutex::lock"));
+	    __throw_concurrence_lock_error();
 	}
 #endif
     }
@@ -151,7 +192,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
       if (__gthread_active_p())
 	{
 	  if (__gthread_recursive_mutex_unlock(&_M_mutex) != 0)
-	    std::__throw_runtime_error(__N("__recursive_mutex::unlock"));
+	    __throw_concurrence_unlock_error();
 	}
 #endif
     }
diff --git a/libstdc++-v3/include/ext/pb_ds/exception.hpp b/libstdc++-v3/include/ext/pb_ds/exception.hpp
index d8eff1749d1416da947eb1ab1b6c3f503f32d551..896ff391810710e0a390131c42f5f5d84e4e65c1 100644
--- a/libstdc++-v3/include/ext/pb_ds/exception.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/exception.hpp
@@ -51,13 +51,11 @@
 
 namespace pb_ds
 {
-#if __EXCEPTIONS
-
   // Base class for exceptions.
   struct container_error : public std::logic_error
   {
     container_error() 
-    : std::logic_error(__N("policy based data structure exception")) { }
+    : std::logic_error(__N("pb_ds::container_error")) { }
   };
 
   // An entry cannot be inserted into a container object for logical
@@ -72,6 +70,7 @@ namespace pb_ds
   // A container cannot be resized.
   struct resize_error : public container_error { };
 
+#if __EXCEPTIONS
   void
   __throw_container_error(void)
   { throw container_error(); }
@@ -87,9 +86,7 @@ namespace pb_ds
   void
   __throw_resize_error(void)
   { throw resize_error(); }
-
 #else
-
   void
   __throw_container_error(void)
   { std::abort(); }
@@ -105,7 +102,6 @@ namespace pb_ds
   void
   __throw_resize_error(void)
   { std::abort(); }
-
 #endif
 } // namespace pb_ds
 
diff --git a/libstdc++-v3/testsuite/abi/cxx_runtime_only_linkage.cc b/libstdc++-v3/testsuite/abi/cxx_runtime_only_linkage.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7e6409ba4d0b7ec7b80f3070d0499b4369f63f55
--- /dev/null
+++ b/libstdc++-v3/testsuite/abi/cxx_runtime_only_linkage.cc
@@ -0,0 +1,26 @@
+// { dg-do link }
+// { dg-options "-x c -L../libsupc++/.libs -lsupc++" }
+// Copyright (C) 2006 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+// Must be able to link C++ apps compiled with gcc and libsupc++.
+
+int main()
+{
+  return 0;
+}