mutex (try_lock): Implement generic try_lock.
2008-09-28 Chris Fairles <cfairles@gcc.gnu.org> * include/std/mutex (try_lock): Implement generic try_lock. * testsuite/30_threads/try_lock/1.cc: New. * testsuite/30_threads/try_lock/2.cc: Likewise. * testsuite/30_threads/try_lock/3.cc: Likewise. * testsuite/30_threads/mutex/cons/assign_neg.cc: Adjust line numbers. * testsuite/30_threads/mutex/cons/copy_neg.cc: Likewise. * testsuite/30_threads/timed_mutex/cons/assign_neg.cc: Likewise. * testsuite/30_threads/timed_mutex/cons/copy_neg.cc: Likewise. * testsuite/30_threads/recursive_mutex/cons/assign_neg.cc: Likewise. * testsuite/30_threads/recursive_mutex/cons/copy_neg.cc: Likewise. * testsuite/30_threads/recursive_timed_mutex/cons/assign_neg.cc: Likewise. * testsuite/30_threads/recursive_timed_mutex/cons/copy_neg.cc: Likewise. From-SVN: r140729
This commit is contained in:
parent
1a9ea3e14b
commit
57cb79efa4
@ -1,3 +1,19 @@
|
||||
2008-09-28 Chris Fairles <cfairles@gcc.gnu.org>
|
||||
|
||||
* include/std/mutex (try_lock): Implement generic try_lock.
|
||||
* testsuite/30_threads/try_lock/1.cc: New.
|
||||
* testsuite/30_threads/try_lock/2.cc: Likewise.
|
||||
* testsuite/30_threads/try_lock/3.cc: Likewise.
|
||||
* testsuite/30_threads/mutex/cons/assign_neg.cc: Adjust line numbers.
|
||||
* testsuite/30_threads/mutex/cons/copy_neg.cc: Likewise.
|
||||
* testsuite/30_threads/timed_mutex/cons/assign_neg.cc: Likewise.
|
||||
* testsuite/30_threads/timed_mutex/cons/copy_neg.cc: Likewise.
|
||||
* testsuite/30_threads/recursive_mutex/cons/assign_neg.cc: Likewise.
|
||||
* testsuite/30_threads/recursive_mutex/cons/copy_neg.cc: Likewise.
|
||||
* testsuite/30_threads/recursive_timed_mutex/cons/assign_neg.cc:
|
||||
Likewise.
|
||||
* testsuite/30_threads/recursive_timed_mutex/cons/copy_neg.cc: Likewise.
|
||||
|
||||
2008-09-26 Peter O'Gorman <pogma@thewrittenword.com>
|
||||
Steve Ellcey <sje@cup.hp.com>
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
# include <c++0x_warning.h>
|
||||
#else
|
||||
|
||||
#include <tuple>
|
||||
#include <cstddef>
|
||||
#include <chrono>
|
||||
#include <exception>
|
||||
@ -601,9 +602,81 @@ namespace std
|
||||
swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>&& __y)
|
||||
{ __x.swap(__y); }
|
||||
|
||||
template<typename _L1, typename _L2, typename ..._L3>
|
||||
template<int _Idx>
|
||||
struct __unlock_impl
|
||||
{
|
||||
template<typename... _Lock>
|
||||
static void
|
||||
__do_unlock(tuple<_Lock&...>& __locks)
|
||||
{
|
||||
std::get<_Idx>(__locks).unlock();
|
||||
__unlock_impl<_Idx - 1>::__do_unlock(__locks);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __unlock_impl<-1>
|
||||
{
|
||||
template<typename... _Lock>
|
||||
static void
|
||||
__do_unlock(tuple<_Lock&...>&)
|
||||
{ }
|
||||
};
|
||||
|
||||
template<int _Idx, bool _Continue = true>
|
||||
struct __try_lock_impl
|
||||
{
|
||||
template<typename... _Lock>
|
||||
static int
|
||||
__do_try_lock(tuple<_Lock&...>& __locks)
|
||||
{
|
||||
if(std::get<_Idx>(__locks).try_lock())
|
||||
{
|
||||
return __try_lock_impl<_Idx + 1,
|
||||
_Idx + 2 < sizeof...(_Lock)>::__do_try_lock(__locks);
|
||||
}
|
||||
else
|
||||
{
|
||||
__unlock_impl<_Idx>::__do_unlock(__locks);
|
||||
return _Idx;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<int _Idx>
|
||||
struct __try_lock_impl<_Idx, false>
|
||||
{
|
||||
template<typename... _Lock>
|
||||
static int
|
||||
__do_try_lock(tuple<_Lock&...>& __locks)
|
||||
{
|
||||
if(std::get<_Idx>(__locks).try_lock())
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
__unlock_impl<_Idx>::__do_unlock(__locks);
|
||||
return _Idx;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief Generic try_lock.
|
||||
* @param __l1 Meets Mutex requirements (try_lock() may throw).
|
||||
* @param __l2 Meets Mutex requirements (try_lock() may throw).
|
||||
* @param __l3 Meets Mutex requirements (try_lock() may throw).
|
||||
* @return Returns -1 if all try_lock() calls return true. Otherwise returns
|
||||
* a 0-based index corresponding to the argument that returned false.
|
||||
* @post Either all arguments are locked, or none will be.
|
||||
*
|
||||
* Sequentially calls try_lock() on each argument.
|
||||
*/
|
||||
template<typename _Lock1, typename _Lock2, typename... _Lock3>
|
||||
int
|
||||
try_lock(_L1& __l1, _L2& __l2, _L3&... __l3);
|
||||
try_lock(_Lock1& __l1, _Lock2& __l2, _Lock3&... __l3)
|
||||
{
|
||||
tuple<_Lock1&, _Lock2&, _Lock3&...> __locks(__l1, __l2, __l3...);
|
||||
return __try_lock_impl<0>::__do_try_lock(__locks);
|
||||
}
|
||||
|
||||
template<typename _L1, typename _L2, typename ..._L3>
|
||||
void
|
||||
|
@ -42,4 +42,4 @@ void test01()
|
||||
}
|
||||
|
||||
// { dg-error "used here" "" { target *-*-* } 41 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 76 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 77 }
|
||||
|
@ -41,4 +41,4 @@ void test01()
|
||||
}
|
||||
|
||||
// { dg-error "used here" "" { target *-*-* } 40 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 75 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 76 }
|
||||
|
@ -42,4 +42,4 @@ void test01()
|
||||
}
|
||||
|
||||
// { dg-error "used here" "" { target *-*-* } 41 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 128 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 129 }
|
||||
|
@ -41,4 +41,4 @@ void test01()
|
||||
}
|
||||
|
||||
// { dg-error "used here" "" { target *-*-* } 40 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 127 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 128 }
|
||||
|
@ -42,4 +42,4 @@ void test01()
|
||||
}
|
||||
|
||||
// { dg-error "used here" "" { target *-*-* } 41 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 282 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 283 }
|
||||
|
@ -41,4 +41,4 @@ void test01()
|
||||
}
|
||||
|
||||
// { dg-error "used here" "" { target *-*-* } 40 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 281 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 282 }
|
||||
|
@ -42,4 +42,4 @@ void test01()
|
||||
}
|
||||
|
||||
// { dg-error "used here" "" { target *-*-* } 41 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 179 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 180 }
|
||||
|
@ -41,4 +41,4 @@ void test01()
|
||||
}
|
||||
|
||||
// { dg-error "used here" "" { target *-*-* } 40 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 178 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 179 }
|
||||
|
72
libstdc++-v3/testsuite/30_threads/try_lock/1.cc
Normal file
72
libstdc++-v3/testsuite/30_threads/try_lock/1.cc
Normal file
@ -0,0 +1,72 @@
|
||||
// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } }
|
||||
// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } }
|
||||
// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } }
|
||||
// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } }
|
||||
// { dg-require-cstdint "" }
|
||||
// { dg-require-gthreads "" }
|
||||
|
||||
// Copyright (C) 2008 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.
|
||||
|
||||
// As a special exception, you may use this file as part of a free software
|
||||
// library without restriction. Specifically, if other files instantiate
|
||||
// templates or use macros or inline functions from this file, or you compile
|
||||
// this file and link it with other files to produce an executable, this
|
||||
// file does not by itself cause the resulting executable to be covered by
|
||||
// the GNU General Public License. This exception does not however
|
||||
// invalidate any other reasons why the executable file might be covered by
|
||||
// the GNU General Public License.
|
||||
|
||||
#include <mutex>
|
||||
#include <system_error>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
typedef std::mutex mutex_type;
|
||||
typedef std::unique_lock<mutex_type> lock_type;
|
||||
|
||||
try
|
||||
{
|
||||
mutex_type m1, m2, m3;
|
||||
lock_type l1(m1, std::defer_lock),
|
||||
l2(m2, std::defer_lock),
|
||||
l3(m3, std::defer_lock);
|
||||
|
||||
try
|
||||
{
|
||||
int result = std::try_lock(l1, l2, l3);
|
||||
VERIFY( result == -1 );
|
||||
}
|
||||
catch (const std::system_error& e)
|
||||
{
|
||||
VERIFY( false );
|
||||
}
|
||||
}
|
||||
catch (const std::system_error& e)
|
||||
{
|
||||
VERIFY( false );
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
VERIFY( false );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
117
libstdc++-v3/testsuite/30_threads/try_lock/2.cc
Normal file
117
libstdc++-v3/testsuite/30_threads/try_lock/2.cc
Normal file
@ -0,0 +1,117 @@
|
||||
// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } }
|
||||
// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } }
|
||||
// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } }
|
||||
// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } }
|
||||
// { dg-require-cstdint "" }
|
||||
// { dg-require-gthreads "" }
|
||||
|
||||
// Copyright (C) 2008 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.
|
||||
|
||||
// As a special exception, you may use this file as part of a free software
|
||||
// library without restriction. Specifically, if other files instantiate
|
||||
// templates or use macros or inline functions from this file, or you compile
|
||||
// this file and link it with other files to produce an executable, this
|
||||
// file does not by itself cause the resulting executable to be covered by
|
||||
// the GNU General Public License. This exception does not however
|
||||
// invalidate any other reasons why the executable file might be covered by
|
||||
// the GNU General Public License.
|
||||
|
||||
#include <mutex>
|
||||
#include <system_error>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
try
|
||||
{
|
||||
std::mutex m1, m2, m3;
|
||||
m1.lock();
|
||||
int result = std::try_lock(m1, m2, m3);
|
||||
VERIFY( result == 0 );
|
||||
m1.lock();
|
||||
m2.lock();
|
||||
m3.lock();
|
||||
}
|
||||
catch (const std::system_error& e)
|
||||
{
|
||||
VERIFY( false );
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
VERIFY( false );
|
||||
}
|
||||
}
|
||||
|
||||
void test02()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
try
|
||||
{
|
||||
std::mutex m1, m2, m3;
|
||||
m2.lock();
|
||||
int result = std::try_lock(m1, m2, m3);
|
||||
VERIFY( result == 1 );
|
||||
m1.lock();
|
||||
m2.lock();
|
||||
m3.lock();
|
||||
}
|
||||
catch (const std::system_error& e)
|
||||
{
|
||||
VERIFY( false );
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
VERIFY( false );
|
||||
}
|
||||
}
|
||||
|
||||
void test03()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
try
|
||||
{
|
||||
std::mutex m1, m2, m3;
|
||||
m3.lock();
|
||||
int result = std::try_lock(m1, m2, m3);
|
||||
VERIFY( result == 2 );
|
||||
m1.lock();
|
||||
m2.lock();
|
||||
m3.lock();
|
||||
}
|
||||
catch (const std::system_error& e)
|
||||
{
|
||||
VERIFY( false );
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
VERIFY( false );
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
return 0;
|
||||
}
|
100
libstdc++-v3/testsuite/30_threads/try_lock/3.cc
Normal file
100
libstdc++-v3/testsuite/30_threads/try_lock/3.cc
Normal file
@ -0,0 +1,100 @@
|
||||
// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } }
|
||||
// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } }
|
||||
// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } }
|
||||
// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } }
|
||||
// { dg-require-cstdint "" }
|
||||
// { dg-require-gthreads "" }
|
||||
|
||||
// Copyright (C) 2008 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.
|
||||
|
||||
// As a special exception, you may use this file as part of a free software
|
||||
// library without restriction. Specifically, if other files instantiate
|
||||
// templates or use macros or inline functions from this file, or you compile
|
||||
// this file and link it with other files to produce an executable, this
|
||||
// file does not by itself cause the resulting executable to be covered by
|
||||
// the GNU General Public License. This exception does not however
|
||||
// invalidate any other reasons why the executable file might be covered by
|
||||
// the GNU General Public License.
|
||||
|
||||
#include <mutex>
|
||||
#include <system_error>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
struct user_lock
|
||||
{
|
||||
user_lock() : is_locked(false) { }
|
||||
~user_lock() = default;
|
||||
user_lock(const user_lock&) = default;
|
||||
|
||||
void lock()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
VERIFY( !is_locked );
|
||||
is_locked = true;
|
||||
}
|
||||
|
||||
bool try_lock()
|
||||
{ return is_locked ? false : (is_locked = true); }
|
||||
|
||||
void unlock()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
VERIFY( is_locked );
|
||||
is_locked = false;
|
||||
}
|
||||
|
||||
private:
|
||||
bool is_locked;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
try
|
||||
{
|
||||
std::mutex m1;
|
||||
std::recursive_mutex m2;
|
||||
user_lock m3;
|
||||
|
||||
try
|
||||
{
|
||||
//heterogeneous types
|
||||
int result = std::try_lock(m1, m2, m3);
|
||||
VERIFY( result == -1 );
|
||||
m1.unlock();
|
||||
m2.unlock();
|
||||
m3.unlock();
|
||||
}
|
||||
catch (const std::system_error& e)
|
||||
{
|
||||
VERIFY( false );
|
||||
}
|
||||
}
|
||||
catch (const std::system_error& e)
|
||||
{
|
||||
VERIFY( false );
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
VERIFY( false );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user