Skip to content

Commit

Permalink
[libc++] Make std::unique_lock available with _LIBCPP_HAS_NO_THREADS (l…
Browse files Browse the repository at this point in the history
…lvm#99562)

This is a follow up to llvm#98717,
which made lock_guard available under _LIBCPP_HAS_NO_THREADS. We can
make unique_lock available under similar circumstances. This patch
follows the example in llvm#98717, by:

  - Removing the preprocessor guards for _LIBCPP_HAS_NO_THREADS in the
    unique_lock header.
  - providing a set of custom mutex implementations in a local header.
  - using custom locks in tests that can be made to work under
    `no-threads`.
  • Loading branch information
ilovepi authored and clementval committed Jul 31, 2024
1 parent d303498 commit 29462e2
Show file tree
Hide file tree
Showing 22 changed files with 314 additions and 382 deletions.
4 changes: 0 additions & 4 deletions libcxx/include/__mutex/unique_lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
# pragma GCC system_header
#endif

#ifndef _LIBCPP_HAS_NO_THREADS

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Mutex>
Expand Down Expand Up @@ -172,6 +170,4 @@ inline _LIBCPP_HIDE_FROM_ABI void swap(unique_lock<_Mutex>& __x, unique_lock<_Mu

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP_HAS_NO_THREADS

#endif // _LIBCPP___MUTEX_UNIQUE_LOCK_H
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: no-threads
// UNSUPPORTED: c++03, c++11, c++14

// <mutex>
Expand All @@ -18,12 +17,13 @@
#include <mutex>

#include "test_macros.h"
#include "types.h"

int main(int, char**) {
std::mutex mutex;
MyMutex mutex;
{
std::unique_lock lock(mutex);
ASSERT_SAME_TYPE(decltype(lock), std::unique_lock<std::mutex>);
ASSERT_SAME_TYPE(decltype(lock), std::unique_lock<MyMutex>);
}

return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,7 @@
// unique_lock& operator=(unique_lock const&) = delete;

#include <mutex>
#include <cassert>

int main(int, char**)
{
{
typedef std::mutex M;
M m0;
M m1;
std::unique_lock<M> lk0(m0);
std::unique_lock<M> lk1(m1);
lk1 = lk0;
assert(lk1.mutex() == &m0);
assert(lk1.owns_lock() == true);
assert(lk0.mutex() == nullptr);
assert(lk0.owns_lock() == false);
}
#include "../types.h"

return 0;
}
static_assert(!std::is_copy_assignable<std::lock_guard<MyMutex> >::value, "");
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,7 @@
// unique_lock(unique_lock const&) = delete;

#include <mutex>
#include <cassert>

int main(int, char**)
{
{
typedef std::mutex M;
M m;
std::unique_lock<M> lk0(m);
std::unique_lock<M> lk = lk0;
assert(lk.mutex() == &m);
assert(lk.owns_lock() == true);
assert(lk0.mutex() == nullptr);
assert(lk0.owns_lock() == false);
}
#include "../types.h"

return 0;
}
static_assert(!std::is_copy_constructible<std::lock_guard<MyMutex> >::value, "");
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,23 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: no-threads

// <mutex>

// template <class Mutex> class unique_lock;

// unique_lock();

#include <mutex>
#include <cassert>
#include <mutex>

#include "test_macros.h"
#include "../types.h"

int main(int, char**)
{
std::unique_lock<std::mutex> ul;
assert(!ul.owns_lock());
assert(ul.mutex() == nullptr);
int main(int, char**) {
std::unique_lock<MyMutex> ul;
assert(!ul.owns_lock());
assert(ul.mutex() == nullptr);

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,23 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: no-threads, c++03

// <mutex>

// template <class Mutex> class unique_lock;

// unique_lock& operator=(unique_lock&& u);

#include <mutex>
#include <cassert>
#include "nasty_containers.h"
#include <mutex>

#include "nasty_containers.h"
#include "../types.h"
#include "test_macros.h"

int main(int, char**)
{
{
typedef std::mutex M;
int main(int, char**) {
{
typedef MyMutex M;
M m0;
M m1;
std::unique_lock<M> lk0(m0);
Expand All @@ -33,8 +31,8 @@ int main(int, char**)
assert(lk1.owns_lock() == true);
assert(lk0.mutex() == nullptr);
assert(lk0.owns_lock() == false);
}
{
}
{
typedef nasty_mutex M;
M m0;
M m1;
Expand All @@ -45,7 +43,7 @@ int main(int, char**)
assert(lk1.owns_lock() == true);
assert(lk0.mutex() == nullptr);
assert(lk0.owns_lock() == false);
}
}

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,33 @@
//
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: no-threads, c++03
// UNSUPPORTED: c++03

// <mutex>

// template <class Mutex> class unique_lock;

// unique_lock(unique_lock&& u);

#include <mutex>
#include <cassert>
#include "nasty_containers.h"
#include <mutex>

#include "nasty_containers.h"
#include "../types.h"
#include "test_macros.h"

int main(int, char**)
{
{
typedef std::mutex M;
int main(int, char**) {
{
typedef MyMutex M;
M m;
std::unique_lock<M> lk0(m);
std::unique_lock<M> lk = std::move(lk0);
assert(lk.mutex() == std::addressof(m));
assert(lk.owns_lock() == true);
assert(lk0.mutex() == nullptr);
assert(lk0.owns_lock() == false);
}
{
}
{
typedef nasty_mutex M;
M m;
std::unique_lock<M> lk0(m);
Expand All @@ -41,7 +41,7 @@ int main(int, char**)
assert(lk.owns_lock() == true);
assert(lk0.mutex() == nullptr);
assert(lk0.owns_lock() == false);
}
}

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
//
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: no-threads
// UNSUPPORTED: c++03

// <mutex>
Expand All @@ -15,30 +14,30 @@

// unique_lock(mutex_type& m, adopt_lock_t);

#include <mutex>
#include <cassert>
#include "nasty_containers.h"
#include <mutex>

#include "nasty_containers.h"
#include "../types.h"
#include "test_macros.h"

int main(int, char**)
{
{
typedef std::mutex M;
int main(int, char**) {
{
typedef MyMutex M;
M m;
m.lock();
std::unique_lock<M> lk(m, std::adopt_lock);
assert(lk.mutex() == std::addressof(m));
assert(lk.owns_lock() == true);
}
{
}
{
typedef nasty_mutex M;
M m;
m.lock();
std::unique_lock<M> lk(m, std::adopt_lock);
assert(lk.mutex() == std::addressof(m));
assert(lk.owns_lock() == true);
}
}

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
//
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: no-threads
// UNSUPPORTED: c++03

// <mutex>
Expand All @@ -15,28 +14,28 @@

// unique_lock(mutex_type& m, defer_lock_t);

#include <mutex>
#include <cassert>
#include "nasty_containers.h"
#include <mutex>

#include "nasty_containers.h"
#include "../types.h"
#include "test_macros.h"

int main(int, char**)
{
{
typedef std::mutex M;
int main(int, char**) {
{
typedef MyMutex M;
M m;
std::unique_lock<M> lk(m, std::defer_lock);
assert(lk.mutex() == std::addressof(m));
assert(lk.owns_lock() == false);
}
{
}
{
typedef nasty_mutex M;
M m;
std::unique_lock<M> lk(m, std::defer_lock);
assert(lk.mutex() == std::addressof(m));
assert(lk.owns_lock() == false);
}
}

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void f()
}
catch (std::system_error& e)
{
assert(e.code().value() == EDEADLK);
assert(e.code() == std::errc::resource_deadlock_would_occur);
}
#endif
lk.unlock();
Expand All @@ -64,7 +64,7 @@ void f()
}
catch (std::system_error& e)
{
assert(e.code().value() == EPERM);
assert(e.code() == std::errc::operation_not_permitted);
}
#endif
}
Expand Down
Loading

0 comments on commit 29462e2

Please sign in to comment.