1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/// Returns the ID of the current execution unit.
///
/// The returned ID is never 0. There are therefore usize::MAX - 1 different execution
/// units.
///
/// At any time, an execution unit is either active or inactive. It is active if there is
/// a thread such that this function returns the ID of the execution unit and inactive
/// otherwise.
///
/// If there are two threads such that this function returns the same ID in both threads,
/// then the termination of one of the threads happens before the start of the other
/// thread.
///
/// # Informal explanation
///
/// An execution unit is morally a single thread except that it might span across multiple
/// threads that are connected by a happens-before relationship.
///
/// This become relevant when
///
/// 1. a thread locks the mutex
/// 2. forgets the guard
/// 3. terminates
/// 4. another thread starts and re-uses the thread-local storage, getting the same
/// execution ID
/// 5. eventually unlocks the mutex
///
/// We allow this because it makes reasoning about safety easier because there are fewer
/// special cases to consider. We invent the "execution unit" terminology because we don't
/// want to spell this out every time.
pub