Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. // Support for pointer abstractions -*- C++ -*-
  2.  
  3. // Copyright (C) 2011-2015 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. #include <memory>
  26.  
  27. namespace std _GLIBCXX_VISIBILITY(default)
  28. {
  29. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  30.  
  31.   bad_weak_ptr::~bad_weak_ptr() noexcept = default;
  32.  
  33.   char const*
  34.   bad_weak_ptr::what() const noexcept
  35.   { return "bad_weak_ptr"; }
  36.  
  37. #ifdef __GTHREADS
  38.   namespace
  39.   {
  40.     const unsigned char mask = 0xf;
  41.     const unsigned char invalid = mask + 1;
  42.  
  43.     inline unsigned char key(const void* addr)
  44.     { return _Hash_impl::hash(addr) & mask; }
  45.  
  46.     /* Returns different instances of __mutex depending on the passed address
  47.      * in order to limit contention.
  48.      */
  49.     __gnu_cxx::__mutex&
  50.     get_mutex(unsigned char i)
  51.     {
  52.       static __gnu_cxx::__mutex m[mask + 1];
  53.       return m[i];
  54.     }
  55.   }
  56.  
  57.   _Sp_locker::_Sp_locker(const void* p)
  58.   {
  59.     if (__gthread_active_p())
  60.       {
  61.         _M_key1 = _M_key2 = key(p);
  62.         get_mutex(_M_key1).lock();
  63.       }
  64.     else
  65.       _M_key1 = _M_key2 = invalid;
  66.   }
  67.  
  68.   _Sp_locker::_Sp_locker(const void* p1, const void* p2)
  69.   {
  70.     if (__gthread_active_p())
  71.       {
  72.         _M_key1 = key(p1);
  73.         _M_key2 = key(p2);
  74.         if (_M_key2 < _M_key1)
  75.           get_mutex(_M_key2).lock();
  76.         get_mutex(_M_key1).lock();
  77.         if (_M_key2 > _M_key1)
  78.           get_mutex(_M_key2).lock();
  79.       }
  80.     else
  81.       _M_key1 = _M_key2 = invalid;
  82.   }
  83.  
  84.   _Sp_locker::~_Sp_locker()
  85.   {
  86.     if (_M_key1 != invalid)
  87.       {
  88.         get_mutex(_M_key1).unlock();
  89.         if (_M_key2 != _M_key1)
  90.           get_mutex(_M_key2).unlock();
  91.       }
  92.   }
  93. #endif
  94.  
  95. _GLIBCXX_END_NAMESPACE_VERSION
  96. } // namespace
  97.