@@ -43,20 +43,20 @@ memtable_process(memtable_context *ctxt, uint64 generation)
4343 ctxt -> process (ctxt -> process_ctxt , generation );
4444}
4545
46- void
47- memtable_get_insert_lock (memtable_context * ctxt )
46+ static inline void
47+ memtable_begin_insert (memtable_context * ctxt )
4848{
4949 platform_batch_rwlock_get (ctxt -> rwlock , MEMTABLE_INSERT_LOCK_IDX );
5050}
5151
5252void
53- memtable_unget_insert_lock (memtable_context * ctxt )
53+ memtable_end_insert (memtable_context * ctxt )
5454{
5555 platform_batch_rwlock_unget (ctxt -> rwlock , MEMTABLE_INSERT_LOCK_IDX );
5656}
5757
58- bool
59- memtable_try_lock_insert_lock (memtable_context * ctxt )
58+ static inline bool
59+ memtable_try_begin_insert_rotation (memtable_context * ctxt )
6060{
6161 if (!platform_batch_rwlock_try_claim (ctxt -> rwlock , MEMTABLE_INSERT_LOCK_IDX ))
6262 {
@@ -66,87 +66,120 @@ memtable_try_lock_insert_lock(memtable_context *ctxt)
6666 return TRUE;
6767}
6868
69- void
70- memtable_lock_insert_lock (memtable_context * ctxt )
69+ static inline void
70+ memtable_end_insert_rotation (memtable_context * ctxt )
71+ {
72+ platform_batch_rwlock_unlock (ctxt -> rwlock , MEMTABLE_INSERT_LOCK_IDX );
73+ platform_batch_rwlock_unclaim (ctxt -> rwlock , MEMTABLE_INSERT_LOCK_IDX );
74+ }
75+
76+ static inline void
77+ memtable_begin_raw_rotation (memtable_context * ctxt )
7178{
72- platform_batch_rwlock_claim (ctxt -> rwlock , MEMTABLE_INSERT_LOCK_IDX );
79+ platform_batch_rwlock_get (ctxt -> rwlock , MEMTABLE_INSERT_LOCK_IDX );
80+ platform_batch_rwlock_claim_loop (ctxt -> rwlock , MEMTABLE_INSERT_LOCK_IDX );
7381 platform_batch_rwlock_lock (ctxt -> rwlock , MEMTABLE_INSERT_LOCK_IDX );
7482}
7583
76- void
77- memtable_unlock_insert_lock (memtable_context * ctxt )
84+ static inline void
85+ memtable_end_raw_rotation (memtable_context * ctxt )
7886{
79- platform_batch_rwlock_unclaim (ctxt -> rwlock , MEMTABLE_INSERT_LOCK_IDX );
80- platform_batch_rwlock_unlock (ctxt -> rwlock , MEMTABLE_INSERT_LOCK_IDX );
87+ platform_batch_rwlock_full_unlock (ctxt -> rwlock , MEMTABLE_INSERT_LOCK_IDX );
8188}
8289
8390void
84- memtable_get_lookup_lock (memtable_context * ctxt )
91+ memtable_begin_lookup (memtable_context * ctxt )
8592{
8693 platform_batch_rwlock_get (ctxt -> rwlock , MEMTABLE_LOOKUP_LOCK_IDX );
8794}
8895
8996void
90- memtable_unget_lookup_lock (memtable_context * ctxt )
97+ memtable_end_lookup (memtable_context * ctxt )
9198{
9299 platform_batch_rwlock_unget (ctxt -> rwlock , MEMTABLE_LOOKUP_LOCK_IDX );
93100}
94101
95102void
96- memtable_lock_lookup_lock (memtable_context * ctxt )
103+ memtable_block_lookups (memtable_context * ctxt )
97104{
98- platform_batch_rwlock_claim (ctxt -> rwlock , MEMTABLE_LOOKUP_LOCK_IDX );
105+ platform_batch_rwlock_get (ctxt -> rwlock , MEMTABLE_LOOKUP_LOCK_IDX );
106+ platform_batch_rwlock_claim_loop (ctxt -> rwlock , MEMTABLE_LOOKUP_LOCK_IDX );
99107 platform_batch_rwlock_lock (ctxt -> rwlock , MEMTABLE_LOOKUP_LOCK_IDX );
100108}
101109
102110void
103- memtable_unlock_lookup_lock (memtable_context * ctxt )
111+ memtable_unblock_lookups (memtable_context * ctxt )
104112{
105- platform_batch_rwlock_unclaim (ctxt -> rwlock , MEMTABLE_LOOKUP_LOCK_IDX );
106- platform_batch_rwlock_unlock (ctxt -> rwlock , MEMTABLE_LOOKUP_LOCK_IDX );
113+ platform_batch_rwlock_full_unlock (ctxt -> rwlock , MEMTABLE_LOOKUP_LOCK_IDX );
107114}
108115
109116
110117platform_status
111- memtable_maybe_rotate_and_get_insert_lock (memtable_context * ctxt ,
112- uint64 * generation )
118+ memtable_maybe_rotate_and_begin_insert (memtable_context * ctxt ,
119+ uint64 * generation )
113120{
114121 uint64 wait = 100 ;
115122 while (TRUE) {
116- memtable_get_insert_lock (ctxt );
117- * generation = ctxt -> generation ;
118- uint64 mt_no = * generation % ctxt -> cfg .max_memtables ;
119- memtable * mt = & ctxt -> mt [mt_no ];
120- if (mt -> state != MEMTABLE_STATE_READY ) {
123+ memtable_begin_insert (ctxt );
124+ uint64 current_generation = ctxt -> generation ;
125+ uint64 current_mt_no = current_generation % ctxt -> cfg .max_memtables ;
126+ memtable * current_mt = & ctxt -> mt [current_mt_no ];
127+ if (current_mt -> state != MEMTABLE_STATE_READY ) {
121128 // The next memtable is not ready yet, back off and wait.
122- memtable_unget_insert_lock (ctxt );
129+ memtable_end_insert (ctxt );
123130 platform_sleep_ns (wait );
124131 wait = wait > 2048 ? wait : 2 * wait ;
125132 continue ;
126133 }
127134 wait = 100 ;
128135
129- if (memtable_is_full (& ctxt -> cfg , & ctxt -> mt [mt_no ])) {
130- // If the current memtable is full, try to retire it.
131- memtable_unget_insert_lock (ctxt );
132- if (memtable_try_lock_insert_lock (ctxt )) {
136+ if (memtable_is_full (& ctxt -> cfg , current_mt )) {
137+ // If the current memtable is full, try to retire it
138+
139+ uint64 next_generation = current_generation + 1 ;
140+ uint64 next_mt_no = next_generation % ctxt -> cfg .max_memtables ;
141+ memtable * next_mt = & ctxt -> mt [next_mt_no ];
142+ if (next_mt -> state != MEMTABLE_STATE_READY ) {
143+ memtable_end_insert (ctxt );
144+ return STATUS_BUSY ;
145+ }
146+
147+ if (memtable_try_begin_insert_rotation (ctxt )) {
133148 // We successfully got the lock, so we do the finalization
134149 memtable_transition (
135- mt , MEMTABLE_STATE_READY , MEMTABLE_STATE_FINALIZED );
150+ current_mt , MEMTABLE_STATE_READY , MEMTABLE_STATE_FINALIZED );
136151
137152 // Safe to increment non-atomically because we have a lock on
138153 // the insert lock
139- uint64 process_generation = ctxt -> generation ++ ;
154+ ctxt -> generation ++ ;
155+ platform_assert (ctxt -> generation - ctxt -> generation_retired
156+ <= ctxt -> cfg .max_memtables ,
157+ "ctxt->generation: %lu, "
158+ "ctxt->generation_retired: %lu, "
159+ "current_generation: %lu\n" ,
160+ ctxt -> generation ,
161+ ctxt -> generation_retired ,
162+ current_generation );
163+ platform_assert (current_generation + 1 == ctxt -> generation ,
164+ "ctxt->generation: %lu, "
165+ "ctxt->generation_retired: %lu, "
166+ "current_generation: %lu\n" ,
167+ ctxt -> generation ,
168+ ctxt -> generation_retired ,
169+ current_generation );
170+
140171 memtable_mark_empty (ctxt );
141- memtable_unlock_insert_lock (ctxt );
142- memtable_process (ctxt , process_generation );
172+ memtable_end_insert_rotation (ctxt );
173+ memtable_end_insert (ctxt );
174+ memtable_process (ctxt , current_generation );
143175 } else {
176+ memtable_end_insert (ctxt );
144177 platform_sleep_ns (wait );
145178 wait = wait > 2048 ? wait : 2 * wait ;
146179 }
147180 continue ;
148181 }
149- * generation = ctxt -> generation ;
182+ * generation = current_generation ;
150183 return STATUS_OK ;
151184 }
152185}
@@ -232,17 +265,19 @@ memtable_dec_ref_maybe_recycle(memtable_context *ctxt, memtable *mt)
232265uint64
233266memtable_force_finalize (memtable_context * ctxt )
234267{
235- memtable_lock_insert_lock (ctxt );
268+ memtable_begin_raw_rotation (ctxt );
236269
237270 uint64 generation = ctxt -> generation ;
238271 uint64 mt_no = generation % ctxt -> cfg .max_memtables ;
239272 memtable * mt = & ctxt -> mt [mt_no ];
240273 memtable_transition (mt , MEMTABLE_STATE_READY , MEMTABLE_STATE_FINALIZED );
241- uint64 process_generation = ctxt -> generation ++ ;
274+ uint64 current_generation = ctxt -> generation ++ ;
275+ platform_assert (ctxt -> generation - ctxt -> generation_retired
276+ <= ctxt -> cfg .max_memtables );
242277 memtable_mark_empty (ctxt );
243278
244- memtable_unlock_insert_lock (ctxt );
245- return process_generation ;
279+ memtable_end_raw_rotation (ctxt );
280+ return current_generation ;
246281}
247282
248283void
0 commit comments