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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
/*-
* Copyright (c) 2014-present MongoDB, Inc.
* Copyright (c) 2008-2014 WiredTiger, Inc.
* All rights reserved.
*
* See the file LICENSE for redistribution information.
*/
/*
* Condition variables:
*
* WiredTiger uses condition variables to signal between threads, and for
* locking operations that are expected to block.
*/
struct __wt_condvar {
const char *name; /* Mutex name for debugging */
wt_mutex_t mtx; /* Mutex */
wt_cond_t cond; /* Condition variable */
int waiters; /* Numbers of waiters, or
-1 if signalled with no waiters. */
/*
* The following fields are used for automatically adjusting condition variable wait times.
*/
uint64_t min_wait; /* Minimum wait duration */
uint64_t max_wait; /* Maximum wait duration */
uint64_t prev_wait; /* Wait duration used last time */
};
/*
* Read/write locks:
*
* WiredTiger uses read/write locks for shared/exclusive access to resources.
* !!!
* Don't modify this structure without understanding the read/write locking
* functions.
*/
struct __wt_rwlock { /* Read/write lock */
volatile union {
uint64_t v; /* Full 64-bit value */
struct {
uint8_t current; /* Current ticket */
uint8_t next; /* Next available ticket */
uint8_t reader; /* Read queue ticket */
uint8_t readers_queued; /* Count of queued readers */
uint32_t readers_active; /* Count of active readers */
} s;
} u;
int16_t stat_read_count_off; /* read acquisitions offset */
int16_t stat_write_count_off; /* write acquisitions offset */
int16_t stat_app_usecs_off; /* waiting application threads offset */
int16_t stat_int_usecs_off; /* waiting server threads offset */
int16_t stat_session_usecs_off; /* waiting session offset */
WT_CONDVAR *cond_readers; /* Blocking readers */
WT_CONDVAR *cond_writers; /* Blocking writers */
};
/*
* WT_RWLOCK_INIT_TRACKED --
* Read write lock initialization, with tracking.
*
* Implemented as a macro so we can pass in a statistics field and convert
* it into a statistics structure array offset.
*/
#define WT_RWLOCK_INIT_TRACKED(session, l, name) \
do { \
WT_RET(__wt_rwlock_init(session, l)); \
(l)->stat_read_count_off = \
(int16_t)WT_STATS_FIELD_TO_OFFSET(S2C(session)->stats, lock_##name##_read_count); \
(l)->stat_write_count_off = \
(int16_t)WT_STATS_FIELD_TO_OFFSET(S2C(session)->stats, lock_##name##_write_count); \
(l)->stat_app_usecs_off = \
(int16_t)WT_STATS_FIELD_TO_OFFSET(S2C(session)->stats, lock_##name##_wait_application); \
(l)->stat_int_usecs_off = \
(int16_t)WT_STATS_FIELD_TO_OFFSET(S2C(session)->stats, lock_##name##_wait_internal); \
} while (0)
#define WT_RWLOCK_INIT_SESSION_TRACKED(session, l, name) \
do { \
WT_RWLOCK_INIT_TRACKED(session, l, name); \
(l)->stat_session_usecs_off = \
(int16_t)WT_SESSION_STATS_FIELD_TO_OFFSET(&(session)->stats, lock_##name##_wait); \
} while (0)
/*
* Spin locks:
*
* WiredTiger uses spinlocks for fast mutual exclusion (where operations done
* while holding the spin lock are expected to complete in a small number of
* instructions).
*/
#define SPINLOCK_GCC 0
#define SPINLOCK_MSVC 1
#define SPINLOCK_PTHREAD_MUTEX 2
#define SPINLOCK_PTHREAD_MUTEX_ADAPTIVE 3
struct __wt_spinlock {
#if SPINLOCK_TYPE == SPINLOCK_GCC
WT_CACHE_LINE_PAD_BEGIN
volatile int lock;
#elif SPINLOCK_TYPE == SPINLOCK_PTHREAD_MUTEX || \
SPINLOCK_TYPE == SPINLOCK_PTHREAD_MUTEX_ADAPTIVE || SPINLOCK_TYPE == SPINLOCK_MSVC
wt_mutex_t lock;
#else
#error Unknown spinlock type
#endif
const char *name; /* Mutex name */
/*
* We track acquisitions and time spent waiting for some locks. For performance reasons and to
* make it possible to write generic code that tracks statistics for different locks, we store
* the offset of the statistics fields to be updated during lock acquisition.
*/
int16_t stat_count_off; /* acquisitions offset */
int16_t stat_app_usecs_off; /* waiting application threads offset */
int16_t stat_int_usecs_off; /* waiting server threads offset */
int16_t stat_session_usecs_off; /* waiting session offset */
int8_t initialized; /* Lock initialized, for cleanup */
#if SPINLOCK_TYPE == SPINLOCK_GCC
WT_CACHE_LINE_PAD_END
#endif
};
|