@@ -199,7 +199,8 @@ int lock_request::wait(uint64_t wait_time_ms) {
199
199
return wait (wait_time_ms, 0 , nullptr );
200
200
}
201
201
202
- int lock_request::wait (uint64_t wait_time_ms, uint64_t killed_time_ms, int (*killed_callback)(void )) {
202
+ int lock_request::wait (uint64_t wait_time_ms, uint64_t killed_time_ms, int (*killed_callback)(void ),
203
+ void (*lock_wait_callback)(void *, TXNID, TXNID)) {
203
204
uint64_t t_now = toku_current_time_microsec ();
204
205
uint64_t t_start = t_now;
205
206
uint64_t t_end = t_start + wait_time_ms * 1000 ;
@@ -208,7 +209,13 @@ int lock_request::wait(uint64_t wait_time_ms, uint64_t killed_time_ms, int (*kil
208
209
209
210
// check again, this time locking out other retry calls
210
211
if (m_state == state::PENDING) {
211
- retry ();
212
+ GrowableArray<TXNID> conflicts_collector;
213
+ conflicts_collector.init ();
214
+ retry (&conflicts_collector);
215
+ if (m_state == state::PENDING) {
216
+ report_waits (&conflicts_collector, lock_wait_callback);
217
+ }
218
+ conflicts_collector.deinit ();
212
219
}
213
220
214
221
while (m_state == state::PENDING) {
@@ -287,7 +294,7 @@ TXNID lock_request::get_conflicting_txnid(void) const {
287
294
return m_conflicting_txnid;
288
295
}
289
296
290
- int lock_request::retry (void ) {
297
+ int lock_request::retry (GrowableArray<TXNID> *conflicts_collector ) {
291
298
invariant (m_state == state::PENDING);
292
299
int r;
293
300
@@ -308,13 +315,14 @@ int lock_request::retry(void) {
308
315
toku_cond_broadcast (&m_wait_cond);
309
316
} else {
310
317
m_conflicting_txnid = conflicts.get (0 );
318
+ add_conflicts_to_waits (&conflicts, conflicts_collector);
311
319
}
312
320
conflicts.destroy ();
313
321
314
322
return r;
315
323
}
316
324
317
- void lock_request::retry_all_lock_requests (locktree *lt, void (*after_retry_all_test_callback)(void )) {
325
+ void lock_request::retry_all_lock_requests (locktree *lt, void (*lock_wait_callback)( void *, TXNID, TXNID), void (* after_retry_all_test_callback)(void )) {
318
326
lt_lock_request_info *info = lt->get_lock_request_info ();
319
327
320
328
info->retry_want ++;
@@ -327,6 +335,9 @@ void lock_request::retry_all_lock_requests(locktree *lt, void (*after_retry_all_
327
335
328
336
toku_mutex_lock (&info->mutex );
329
337
338
+ GrowableArray<TXNID> conflicts_collector;
339
+ conflicts_collector.init ();
340
+
330
341
// here is the group retry algorithm.
331
342
// get the latest retry_want count and use it as the generation number of this retry operation.
332
343
// if this retry generation is > the last retry generation, then do the lock retries. otherwise,
@@ -344,7 +355,7 @@ void lock_request::retry_all_lock_requests(locktree *lt, void (*after_retry_all_
344
355
// move on to the next lock request. otherwise
345
356
// the request is gone from the list so we may
346
357
// read the i'th entry for the next one.
347
- r = request->retry ();
358
+ r = request->retry (&conflicts_collector );
348
359
if (r != 0 ) {
349
360
i++;
350
361
}
@@ -354,6 +365,30 @@ void lock_request::retry_all_lock_requests(locktree *lt, void (*after_retry_all_
354
365
}
355
366
356
367
toku_mutex_unlock (&info->mutex );
368
+
369
+ report_waits (&conflicts_collector, lock_wait_callback);
370
+ conflicts_collector.deinit ();
371
+ }
372
+
373
+ void lock_request::add_conflicts_to_waits (txnid_set *conflicts,
374
+ GrowableArray<TXNID> *wait_conflicts) {
375
+ size_t num_conflicts = conflicts->size ();
376
+ for (size_t i = 0 ; i < num_conflicts; i++) {
377
+ wait_conflicts->push (m_txnid);
378
+ wait_conflicts->push (conflicts->get (i));
379
+ }
380
+ }
381
+
382
+ void lock_request::report_waits (GrowableArray<TXNID> *wait_conflicts,
383
+ void (*lock_wait_callback)(void *, TXNID, TXNID)) {
384
+ if (!lock_wait_callback)
385
+ return ;
386
+ size_t num_conflicts = wait_conflicts->get_size ();
387
+ for (size_t i = 0 ; i < num_conflicts; i += 2 ) {
388
+ TXNID blocked_txnid = wait_conflicts->fetch_unchecked (i);
389
+ TXNID blocking_txnid = wait_conflicts->fetch_unchecked (i+1 );
390
+ (*lock_wait_callback)(nullptr , blocked_txnid, blocking_txnid);
391
+ }
357
392
}
358
393
359
394
void *lock_request::get_extra (void ) const {
0 commit comments