Skip to content

Commit 398740a

Browse files
committed
Improve documentation of unique_lock
There are a few important caveats with using `unique_lock` in device code as I found out in #595. This commit adds a few warnings to the documentation to more clearly explain how this type should be used.
1 parent ac84f54 commit 398740a

File tree

1 file changed

+53
-16
lines changed

1 file changed

+53
-16
lines changed

device/common/include/traccc/device/unique_lock.hpp

+53-16
Original file line numberDiff line numberDiff line change
@@ -13,55 +13,92 @@
1313
#include "traccc/definitions/qualifiers.hpp"
1414

1515
namespace traccc::device {
16+
/**
17+
* @brief An RAII-based lock, analogous to `std::unique_lock`.
18+
*
19+
* This unique lock type can be used to increase the safety of critical
20+
* sections at it guarantees that the lock will be released when it goes out of
21+
* scope.
22+
*
23+
* @tparam Mutex The underlying mutex type.
24+
*
25+
* @warning Be wary of using this code across different architectures, as
26+
* lockstep execution may seriously impact the behaviour of this code. In
27+
* particular, be wary of the fact that, on lockstep architectures, trying to
28+
* acquire this lock may result in deadlock as all locks will try to acquire
29+
* the lock at the same time. To resolve this, only try to acquire the lock
30+
* from one thread in a work group or block of threads. When using code written
31+
* in this way on non-lockstep architectures, be aware that the thread holding
32+
* the lock may exit a block before the other threads, releasing the lock early
33+
* and breaking thread safety. To avoid this problem, always synchronize
34+
* threads after the critical section.
35+
*/
1636
template <typename Mutex>
1737
class unique_lock {
1838
public:
1939
using mutex_type = Mutex;
2040

21-
/*
22-
* Construct a unique lock without locking.
41+
/**
42+
* @brief Construct a unique lock without locking.
2343
*/
2444
TRACCC_HOST_DEVICE
2545
unique_lock(mutex_type& m, std::defer_lock_t);
2646

27-
/*
28-
* Construct a unique lock, attempting to lock it.
47+
/**
48+
* @brief Construct a unique lock, attempting to lock it.
49+
*
50+
* @warning This function returning does _not_ guarantee that the lock has
51+
* been acquired.
52+
*
53+
* @note Despite the warnings about acquiring locks in lockstep
54+
* architectures, calling this function across multiple threads is safe as
55+
* it is a non-blocking lock, e.g. it will fail for all but at most one
56+
* thread.
2957
*/
3058
TRACCC_HOST_DEVICE
3159
unique_lock(mutex_type& m, std::try_to_lock_t);
3260

33-
/*
34-
* Construct a unique lock which was previously locked.
61+
/**
62+
* @brief Construct a unique lock which was previously locked.
3563
*/
3664
TRACCC_HOST_DEVICE
3765
unique_lock(mutex_type& m, std::adopt_lock_t);
3866

39-
/*
40-
* Destroy a lock, freeing the underlying mutex.
67+
/**
68+
* @brief Destroy a lock, freeing the underlying mutex.
4169
*/
4270
TRACCC_HOST_DEVICE
4371
~unique_lock();
4472

45-
/*
46-
* Lock the lock, blocking until the operation succeeds.
73+
/**
74+
* @brief Lock the lock, blocking until the operation succeeds.
75+
*
76+
* @warning On lockstep architectures, calling this method on more than a
77+
* single thread in a group will result in deadlock.
4778
*/
4879
TRACCC_HOST_DEVICE
4980
void lock();
5081

51-
/*
52-
* Try to lock the lock without blocking.
82+
/**
83+
* @brief Try to lock the lock without blocking.
84+
*
85+
* @note Calling this method from multiple threads in the same block is
86+
* safe.
5387
*/
5488
TRACCC_HOST_DEVICE
5589
bool try_lock();
5690

57-
/*
58-
* Explicitly lock the underlying lock.
91+
/**
92+
* @brief Explicitly unlock the underlying lock.
93+
*
94+
* @warning Calling this method on a lock which has not been acquired
95+
* constitutes undefined behaviour.
5996
*/
6097
TRACCC_HOST_DEVICE
6198
void unlock();
6299

63-
/*
64-
* Check if the lock is locked by this object.
100+
/**
101+
* @brief Check if the lock is locked by this object.
65102
*/
66103
TRACCC_HOST_DEVICE
67104
bool owns_lock() const;

0 commit comments

Comments
 (0)